Shaun Campbell 4b3af5e947
All checks were successful
Build and Push Image / docker-build-and-push (push) Successful in 2m25s
trips) portainer API deploy + preflight checks (#5)
- 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>
2026-02-21 06:20:51 +00:00
2026-02-18 23:17:34 -05:00
2026-02-19 13:08:25 -05:00
2026-02-18 20:23:34 -05:00
2026-02-18 20:23:34 -05:00
2026-02-18 20:23:34 -05:00
2026-02-18 20:23:34 -05:00
2026-02-19 13:08:25 -05:00
2026-02-18 20:23:34 -05:00

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 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:

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.
Description
Trip Manager
Readme 2.9 MiB
Languages
Svelte 57.1%
TypeScript 42.4%
JavaScript 0.2%
Dockerfile 0.2%