Files
trip-planner/docs/plans/completed/2026-08-18-implement-deployment-infrastructure.md

117 lines
7.0 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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
- [x] add `cron` service (Go cron binary, depends_on: postgres, redis)
- [x] add `watchtower` service (nickfedor/watchtower image, volume for docker.sock, command for cleanup)
- [x] add `redis_data` volume to volumes section
- [x] verify docker-compose.yml syntax with `docker-compose config`
### Task 3: Create Gitea Actions CI/CD Workflow
- [x] create `.gitea/workflows/deploy.yml` file
- [x] add checkout step (actions/checkout@v3)
- [x] add setup Go step (actions/setup-go@v4, go-version: '1.22')
- [x] add Go modules cache step (actions/cache@v3)
- [x] add lint & test step (golangci-lint, go test -v -race ./...)
- [x] add Docker Buildx setup step (docker/setup-buildx-action@v2)
- [x] add Docker login step (docker/login-action@v2)
- [x] add Docker build & push step (docker/build-push-action@v4, tags: latest and {{.CommitID}})
- [x] verify Gitea Actions workflow YAML syntax
### Task 4: Verify acceptance criteria
- [x] verify Dockerfile matches multi-stage specification
- [x] verify docker-compose.yml has api, cron, postgres, redis, watchtower services
- [x] verify Gitea Actions workflow has all required steps (checkout, setup Go, lint & test, build binaries, Docker build & push)
- [x] verify all YAML files are valid syntax
- [x] verify docker-compose.yml volumes section includes postgres_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: postgres, redis
- `cron`: build from Dockerfile, environment: same as api, depends_on: postgres, redis
- `postgres` (postgres): postgres:15-alpine, environment: POSTGRES_USER, POSTGRES_PASSWORD, POSTGRES_DB, volumes: postgres_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