services: ksan-dev: # Normally built and pushed by CI; deployed by tag, never by :latest, so a # rollback is a re-run of `up -d` with an older tag instead of a rebuild. image: ${IMAGE_NAME:-git.ksan.dev/ksan/ksan.dev}:${IMAGE_TAG:-latest} # TEMPORARY — while the Gitea workflows sit at .disabled, nothing builds or # pushes an image, so the VPS builds from its own checkout instead: # # git pull && docker compose up -d --build # # PLANS_PAGES must be in the VPS .env for this to work; it is a build arg # (the codes are baked in via generateStaticParams), not a runtime var. # Remove this block when CI is re-enabled — a registry image is the only # thing `deploy.sh` and `rollback.sh` can deploy by tag. build: context: . args: PLANS_PAGES: ${PLANS_PAGES} container_name: ksan-dev restart: unless-stopped env_file: - .env networks: - frontend # Shared VPS: keep one site's leak from taking the box down with it. mem_limit: 512m cpus: 0.5 logging: driver: json-file options: max-size: "10m" max-file: "3" # `/` 307-redirects to the default locale, so probe the locale path directly. healthcheck: test: ["CMD", "wget", "-q", "-O", "/dev/null", "http://127.0.0.1:3000/en"] interval: 30s timeout: 5s retries: 3 start_period: 15s labels: - traefik.enable=true - traefik.http.routers.ksan-dev-http.rule=Host(`${DOMAIN}`) || Host(`www.${DOMAIN}`) - traefik.http.routers.ksan-dev-http.entrypoints=web - traefik.http.routers.ksan-dev-https.tls=true - traefik.http.routers.ksan-dev-https.tls.certresolver=cloudflare - traefik.http.routers.ksan-dev-https.entrypoints=websecure - traefik.http.routers.ksan-dev-https.rule=Host(`${DOMAIN}`) || Host(`www.${DOMAIN}`) - traefik.http.services.ksan-dev.loadbalancer.server.port=3000 networks: frontend: external: true