All checks were successful
Build and Push Image / docker-build-and-push (push) Successful in 2m25s
- Switch CI deploy step from Portainer webhook to Portainer API (CE-compatible) - Add manual workflow trigger (`workflow_dispatch`) - Add preflight checks for Portainer auth, endpoint ID, and stack ID before redeploy - Update README with required secrets and deploy flow Reviewed-on: #5 Co-authored-by: Shaun Campbell <shaun@campbellwireless.net> Co-committed-by: Shaun Campbell <shaun@campbellwireless.net>
149 lines
3.4 KiB
Markdown
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.
|