4b3af5e9474c9d4516ec63e9b3d98d351d1758c2
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>
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
cp .env.example .env
bun install
Run
bun run dev
Quality and Tests
bun run lint
bun run test
bun run check
Build and Preview
bun run build
bun run preview
Docker
Build locally
docker build -t trips:local .
Run locally
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 tomain, 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_USERNAMEREGISTRY_PASSWORDPORTAINER_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 totrueonly if Portainer uses self-signed TLS)
By default, the publish workflow pushes to:
registry.campbellwireless.net/<owner>/<repo>:latestregistry.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:
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:
- Create an API key from your user profile (
My account->API keys). - Open the stack details page and note the stack ID.
- Open
Environmentsand note the endpoint/environment ID where the stack runs. - Save these values in your Gitea repository secrets:
PORTAINER_URLPORTAINER_API_KEYPORTAINER_STACK_IDPORTAINER_ENDPOINT_ID- optional
PORTAINER_INSECURE_TLS=true
Flow on each push to main (or manual run of main-image.yml):
- Build image.
- Push
:latestand:<short-sha>. - Run Portainer preflight checks (auth + stack/endpoint IDs).
- Call Portainer API.
- Portainer redeploys the stack and pulls the updated image.
Description
Languages
Svelte
57.1%
TypeScript
42.4%
JavaScript
0.2%
Dockerfile
0.2%