# 2026-08-18-implement-deployment-infrastructure ## Overview - Clear description of the feature/change being implemented: Implement the complete deployment infrastructure for the trip-planner service including Dockerfile, updated docker-compose.yml with cron and watchtower services, and Gitea Actions CI/CD workflow. - Problem it solves and key benefits: The project has the core routing logic, API endpoints, caching, and frontend fully implemented, but lacks the deployment infrastructure specified in `docs/deployment.md`. This plan adds the missing Dockerfile, completes docker-compose.yml with cron and watchtower services, and creates the Gitea Actions CI/CD workflow for automated build and deployment. - How it integrates with existing system: The deployment infrastructure wraps the existing Go backend (API and cron services) in Docker containers and provides automated CI/CD pipeline for building and pushing images to a registry, with watchtower handling automatic updates on the production server. ## Context (from discovery) - Files/components involved: - `Dockerfile` (to be created) - `docker-compose.yml` (to be updated with cron and watchtower services, redis_data volume) - `.gitea/workflows/deploy.yml` (to be created) - Existing: `/cmd/api/main.go`, `/cmd/cron/station_status.go`, `go.mod`, `go.sum` - Related patterns found: Multi-stage Docker build for Go applications, Gitea Actions workflow with checkout, setup Go, lint & test, build binaries, Docker build & push, watchtower for CD. - Dependencies identified: Go 1.22+, PostgreSQL 15-alpine, Redis 7-alpine, nickfedor/watchtower image. ## Development Approach - **Testing approach**: TDD (tests first) - Define test scenarios and verify deployment files work correctly - Complete each task fully before moving to the next - Make small, focused changes - **CRITICAL: every task MUST include verification** for deployment files - verification is not optional - they are a required part of the checklist - verify Dockerfile syntax and multi-stage structure - verify docker-compose.yml syntax and service definitions - verify Gitea Actions workflow YAML syntax - include both success and error scenarios in verification - **CRITICAL: all verifications must pass before starting next task** - no exceptions - **CRITICAL: update this plan file when scope changes during implementation** - Keep plan in sync with actual work done ## Testing Strategy - **Verification tests**: required for every task (see Development Approach above) - **Syntax validation**: verify YAML files with yaml lint, verify Dockerfile with docker build --dry-run - **Configuration validation**: verify docker-compose.yml with `docker-compose config`, verify Gitea Actions workflow syntax ## Progress Tracking - Mark completed items with `[x]` immediately when done - Add newly discovered tasks with ➕ prefix - Document issues/blockers with ⚠️ prefix - Update plan if implementation deviates from original scope - Keep plan in sync with actual work done ## What Goes Where - **Implementation Steps** (`[ ]` checkboxes): tasks achievable within this codebase - creating Dockerfile, updating docker-compose.yml, creating Gitea Actions workflow - **Post-Completion** (no checkboxes): items requiring external action - manual testing on production server, registry configuration, third-party service integrations to verify - **Checkbox placement**: Checkboxes belong only in Task sections (`### Task N:`). Do not put checkboxes in Success criteria, Overview, or Context — they cause extra loop iterations. ## Implementation Steps ### Task 1: Create Multi-stage Dockerfile - [x] create Dockerfile with builder stage (Go 1.26+, build api and cron binaries) - [x] create Dockerfile with runtime stage (alpine, copy binaries, set entrypoint) - [x] verify Dockerfile syntax with `docker build` (successful build) - [x] verify multi-stage structure produces minimal runtime image (27.1MB) ### Task 2: Update docker-compose.yml - [ ] add `cron` service (Go cron binary, depends_on: postgres, redis) - [ ] add `watchtower` service (nickfedor/watchtower image, volume for docker.sock, command for cleanup) - [ ] add `redis_data` volume to volumes section - [ ] verify docker-compose.yml syntax with `docker-compose config` ### Task 3: Create Gitea Actions CI/CD Workflow - [ ] create `.gitea/workflows/deploy.yml` file - [ ] add checkout step (actions/checkout@v3) - [ ] add setup Go step (actions/setup-go@v4, go-version: '1.22') - [ ] add Go modules cache step (actions/cache@v3) - [ ] add lint & test step (golangci-lint, go test -v -race ./...) - [ ] add Docker Buildx setup step (docker/setup-buildx-action@v2) - [ ] add Docker login step (docker/login-action@v2) - [ ] add Docker build & push step (docker/build-push-action@v4, tags: latest and {{.CommitID}}) - [ ] verify Gitea Actions workflow YAML syntax ### Task 4: Verify acceptance criteria - [ ] verify Dockerfile matches multi-stage specification - [ ] verify docker-compose.yml has api, cron, postgres, redis, watchtower services - [ ] verify Gitea Actions workflow has all required steps (checkout, setup Go, lint & test, build binaries, Docker build & push) - [ ] verify all YAML files are valid syntax - [ ] verify docker-compose.yml volumes section includes pg_data and redis_data ## Technical Details - **Dockerfile structure**: - Builder stage: `golang:1.22-alpine` as builder, copy go.mod/go.sum, `go mod download`, copy source, `go build -o api cmd/api/main.go`, `go build -o cron cmd/cron/main.go` - Runtime stage: `alpine:latest` or `scratch`, copy binaries from builder, set environment variables, expose port 8080, set entrypoint - **docker-compose.yml services**: - `api`: build from Dockerfile, ports: 8080:8080, environment: DB_DSN, REDIS_ADDR, YANDEX_API_KEY, depends_on: db, redis - `cron`: build from Dockerfile, environment: same as api, depends_on: db, redis - `db` (postgres): postgres:15-alpine, environment: POSTGRES_USER, POSTGRES_PASSWORD, POSTGRES_DB, volumes: pg_data - `redis`: redis:7-alpine, volumes: redis_data - `watchtower`: nickfedor/watchtower, volumes: /var/run/docker.sock:/var/run/docker.sock, command: --interval 60 --cleanup travel-api - **.gitea/workflows/deploy.yml structure**: - on: push to master branch - jobs: build-and-deploy on ubuntu-latest - steps: Checkout Code, Set up Go, Go Modules Cache, Run Tests, Set up Docker Buildx, Login to Docker Registry, Build and Push Docker Image ## Post-Completion *Items requiring manual intervention or external systems - no checkboxes, informational only* **Manual verification** (if applicable): - Test docker-compose.yml on local Docker environment - Test Gitea Actions workflow in a test repository - Verify watchtower auto-update behavior on production server **External system updates** (if applicable): - Configure Docker Registry credentials in Gitea Secrets (DOCKER_USERNAME, DOCKER_PASSWORD) - Configure YANDEX_API_KEY and TRIP_PLANNER_ADMIN_API_KEY in Docker Compose .env file - Verify PostgreSQL and Redis persistence volumes are properly mounted