Files
trips/README.md
Shaun Campbell 19c5b76e60
All checks were successful
PR Checks / lint-test-and-docker-build (pull_request) Successful in 2m4s
trips) portainer API deploy + preflight checks
2026-02-21 01:19:03 -05:00

149 lines
3.4 KiB
Markdown

# trips
A SvelteKit travel planning app for managing trips, travelers, transportation, lodgings, package tours, checklists, and experiences.
## Tech Stack
- SvelteKit + TypeScript
- SQLite (`bun:sqlite`)
- Vitest for unit tests
- Biome + Prettier for code quality
- Bun for local/deploy build and runtime workflows
- Docker multi-stage build for production image
## Features
- Authenticated trip dashboard with upcoming/past trip views
- Trip planning with:
- flights
- private vehicles
- other transportation
- lodgings
- package tours
- checklists
- experiences
- Admin flows for travel reference data and tour operator/tour management
## Local Development
### Requirements
- Bun 1.x
### Setup
```sh
cp .env.example .env
bun install
```
### Run
```sh
bun run dev
```
## Quality and Tests
```sh
bun run lint
bun run test
bun run check
```
## Build and Preview
```sh
bun run build
bun run preview
```
## Docker
### Build locally
```sh
docker build -t trips:local .
```
### Run locally
```sh
docker compose up --build
```
The container stores SQLite data at `/data/trips.db` (mounted as the `trips-data` volume in `docker-compose.yml`).
## CI (Gitea Actions)
Workflows live in `.gitea/workflows`:
- `pr-checks.yml`: runs lint, tests, and Docker build on pull requests.
- `main-image.yml`: builds and pushes a Docker image on push to `main`, then calls the Portainer API to redeploy. It can also be run manually from the Actions UI.
### Registry secrets for image publish
Configure these repository secrets in Gitea:
- `REGISTRY_USERNAME`
- `REGISTRY_PASSWORD`
- `PORTAINER_URL` (for example, `https://portainer.example.com`)
- `PORTAINER_API_KEY` (Portainer API key for a user with access to the stack)
- `PORTAINER_STACK_ID` (numeric stack ID in Portainer)
- `PORTAINER_ENDPOINT_ID` (numeric environment/endpoint ID in Portainer)
- `PORTAINER_INSECURE_TLS` (optional: set to `true` only if Portainer uses self-signed TLS)
By default, the publish workflow pushes to:
- `registry.campbellwireless.net/<owner>/<repo>:latest`
- `registry.campbellwireless.net/<owner>/<repo>:<short-sha>`
If your registry host differs, edit `REGISTRY_HOST` in `.gitea/workflows/main-image.yml`.
## Deploy with Portainer API
The `main-image.yml` workflow now calls the Portainer API after pushing `latest`.
In Portainer, create/update your stack to use a published image (not `build`), for example:
```yaml
services:
trips:
image: registry.campbellwireless.net/<owner>/<repo>:latest
container_name: trips
restart: unless-stopped
ports:
- '3000:3000'
volumes:
- trips-data:/data
env_file:
- .env
environment:
NODE_ENV: production
DATABASE_URL: file:/data/trips.db
PORT: '3000'
volumes:
trips-data:
```
Then in Portainer:
1. Create an API key from your user profile (`My account` -> `API keys`).
2. Open the stack details page and note the stack ID.
3. Open `Environments` and note the endpoint/environment ID where the stack runs.
4. Save these values in your Gitea repository secrets:
- `PORTAINER_URL`
- `PORTAINER_API_KEY`
- `PORTAINER_STACK_ID`
- `PORTAINER_ENDPOINT_ID`
- optional `PORTAINER_INSECURE_TLS=true`
Flow on each push to `main` (or manual run of `main-image.yml`):
1. Build image.
2. Push `:latest` and `:<short-sha>`.
3. Run Portainer preflight checks (auth + stack/endpoint IDs).
4. Call Portainer API.
5. Portainer redeploys the stack and pulls the updated image.