docs(01-infrastructure-and-deployment): create phase plan
This commit is contained in:
parent
909c28cf4b
commit
d57185e262
3 changed files with 413 additions and 2 deletions
|
|
@ -38,7 +38,10 @@ Decimal phases appear between their surrounding integers in numeric order.
|
||||||
2. The Terragrunt stack applies cleanly from a fresh checkout with no manual cluster intervention
|
2. The Terragrunt stack applies cleanly from a fresh checkout with no manual cluster intervention
|
||||||
3. The NFS volume is mounted inside the running pod and a file written to it survives a pod restart
|
3. The NFS volume is mounted inside the running pod and a file written to it survives a pod restart
|
||||||
4. Woodpecker CI pipeline exists and triggers on push to the service's directory
|
4. Woodpecker CI pipeline exists and triggers on push to the service's directory
|
||||||
**Plans**: TBD
|
**Plans**: 2 plans
|
||||||
|
Plans:
|
||||||
|
- [ ] 01-01-PLAN.md — Create FastAPI backend app, Dockerfile, and build/push Docker image
|
||||||
|
- [ ] 01-02-PLAN.md — Update Terraform deployment, apply stack, verify NFS, add CI pipeline
|
||||||
|
|
||||||
### Phase 2: F1 Schedule Subsystem
|
### Phase 2: F1 Schedule Subsystem
|
||||||
**Goal**: The system automatically fetches the full F1 race calendar and serves it as structured data — users can see all sessions for the current season with correct times.
|
**Goal**: The system automatically fetches the full F1 race calendar and serves it as structured data — users can see all sessions for the current season with correct times.
|
||||||
|
|
@ -125,7 +128,7 @@ Phases execute in numeric order: 1 → 2 → 3 → 4 → 5 → 6 → 7 → 8
|
||||||
|
|
||||||
| Phase | Plans Complete | Status | Completed |
|
| Phase | Plans Complete | Status | Completed |
|
||||||
|-------|----------------|--------|-----------|
|
|-------|----------------|--------|-----------|
|
||||||
| 1. Infrastructure and Deployment | 0/TBD | Not started | - |
|
| 1. Infrastructure and Deployment | 0/2 | Planning complete | - |
|
||||||
| 2. F1 Schedule Subsystem | 0/TBD | Not started | - |
|
| 2. F1 Schedule Subsystem | 0/TBD | Not started | - |
|
||||||
| 3. Extractor Framework and First Site | 0/TBD | Not started | - |
|
| 3. Extractor Framework and First Site | 0/TBD | Not started | - |
|
||||||
| 4. Stream Health and Fallback | 0/TBD | Not started | - |
|
| 4. Stream Health and Fallback | 0/TBD | Not started | - |
|
||||||
|
|
|
||||||
173
.planning/phases/01-infrastructure-and-deployment/01-01-PLAN.md
Normal file
173
.planning/phases/01-infrastructure-and-deployment/01-01-PLAN.md
Normal file
|
|
@ -0,0 +1,173 @@
|
||||||
|
---
|
||||||
|
phase: 01-infrastructure-and-deployment
|
||||||
|
plan: 01
|
||||||
|
type: execute
|
||||||
|
wave: 1
|
||||||
|
depends_on: []
|
||||||
|
files_modified:
|
||||||
|
- stacks/f1-stream/files/backend/main.py
|
||||||
|
- stacks/f1-stream/files/backend/requirements.txt
|
||||||
|
- stacks/f1-stream/files/Dockerfile
|
||||||
|
- stacks/f1-stream/files/redeploy.sh
|
||||||
|
autonomous: true
|
||||||
|
requirements:
|
||||||
|
- DEPL-01
|
||||||
|
|
||||||
|
must_haves:
|
||||||
|
truths:
|
||||||
|
- "A Docker image viktorbarzin/f1-stream:v2.0.0 exists and can be pulled"
|
||||||
|
- "The image starts a FastAPI server on port 8000 that responds to GET /health with 200"
|
||||||
|
- "The image is based on python:3.13-slim-bookworm and runs without errors"
|
||||||
|
artifacts:
|
||||||
|
- path: "stacks/f1-stream/files/backend/main.py"
|
||||||
|
provides: "FastAPI app with health endpoint"
|
||||||
|
contains: "/health"
|
||||||
|
- path: "stacks/f1-stream/files/backend/requirements.txt"
|
||||||
|
provides: "Python dependencies"
|
||||||
|
contains: "fastapi"
|
||||||
|
- path: "stacks/f1-stream/files/Dockerfile"
|
||||||
|
provides: "Multi-stage Docker build for Python FastAPI"
|
||||||
|
contains: "python:3.13-slim-bookworm"
|
||||||
|
- path: "stacks/f1-stream/files/redeploy.sh"
|
||||||
|
provides: "Build, push, restart script"
|
||||||
|
contains: "docker build"
|
||||||
|
key_links:
|
||||||
|
- from: "stacks/f1-stream/files/Dockerfile"
|
||||||
|
to: "stacks/f1-stream/files/backend/main.py"
|
||||||
|
via: "COPY backend/ into image"
|
||||||
|
pattern: "COPY.*backend"
|
||||||
|
- from: "stacks/f1-stream/files/Dockerfile"
|
||||||
|
to: "stacks/f1-stream/files/backend/requirements.txt"
|
||||||
|
via: "pip install requirements"
|
||||||
|
pattern: "pip install.*requirements"
|
||||||
|
---
|
||||||
|
|
||||||
|
<objective>
|
||||||
|
Create a minimal FastAPI backend application with a health endpoint and build a Docker image for it. This replaces the existing Go-based f1-stream application with the new Python/FastAPI stack.
|
||||||
|
|
||||||
|
Purpose: Provide a deployable container image that the Terraform stack (Plan 02) will reference. The health endpoint proves the service is running correctly.
|
||||||
|
Output: Docker image `viktorbarzin/f1-stream:v2.0.0` pushed to Docker Hub, containing a working FastAPI server.
|
||||||
|
</objective>
|
||||||
|
|
||||||
|
<execution_context>
|
||||||
|
@/Users/viktorbarzin/.claude/get-shit-done/workflows/execute-plan.md
|
||||||
|
@/Users/viktorbarzin/.claude/get-shit-done/templates/summary.md
|
||||||
|
</execution_context>
|
||||||
|
|
||||||
|
<context>
|
||||||
|
@.planning/PROJECT.md
|
||||||
|
@.planning/ROADMAP.md
|
||||||
|
@.planning/STATE.md
|
||||||
|
@.planning/research/STACK.md
|
||||||
|
|
||||||
|
# Existing files to replace/modify:
|
||||||
|
@stacks/f1-stream/files/Dockerfile
|
||||||
|
@stacks/f1-stream/files/redeploy.sh
|
||||||
|
</context>
|
||||||
|
|
||||||
|
<tasks>
|
||||||
|
|
||||||
|
<task type="auto">
|
||||||
|
<name>Task 1: Create FastAPI backend application with health endpoint</name>
|
||||||
|
<files>stacks/f1-stream/files/backend/main.py, stacks/f1-stream/files/backend/requirements.txt</files>
|
||||||
|
<action>
|
||||||
|
Create the directory `stacks/f1-stream/files/backend/`.
|
||||||
|
|
||||||
|
Create `stacks/f1-stream/files/backend/requirements.txt` with pinned versions:
|
||||||
|
```
|
||||||
|
fastapi==0.132.0
|
||||||
|
uvicorn[standard]
|
||||||
|
```
|
||||||
|
|
||||||
|
Create `stacks/f1-stream/files/backend/main.py` with a minimal FastAPI application:
|
||||||
|
- Import FastAPI
|
||||||
|
- Create app instance with title "F1 Streams"
|
||||||
|
- Add `GET /health` endpoint that returns `{"status": "ok"}`
|
||||||
|
- Add `GET /` root endpoint that returns `{"service": "f1-streams", "version": "2.0.0"}`
|
||||||
|
- Add an `if __name__ == "__main__"` block that runs uvicorn on host 0.0.0.0 port 8000
|
||||||
|
|
||||||
|
This is intentionally minimal -- just enough to prove the deployment works. Later phases will add schedule, extractor, and proxy routes.
|
||||||
|
|
||||||
|
Do NOT add any other dependencies or routes beyond the health check and root. Keep it simple.
|
||||||
|
</action>
|
||||||
|
<verify>
|
||||||
|
Run `python3 -c "import ast; ast.parse(open('stacks/f1-stream/files/backend/main.py').read()); print('Syntax OK')"` to verify the Python file is valid.
|
||||||
|
Verify requirements.txt exists and contains fastapi and uvicorn.
|
||||||
|
</verify>
|
||||||
|
<done>
|
||||||
|
`backend/main.py` exists with a valid FastAPI app that has `/health` and `/` endpoints. `requirements.txt` lists fastapi and uvicorn.
|
||||||
|
</done>
|
||||||
|
</task>
|
||||||
|
|
||||||
|
<task type="auto">
|
||||||
|
<name>Task 2: Create Dockerfile and build/push the container image</name>
|
||||||
|
<files>stacks/f1-stream/files/Dockerfile, stacks/f1-stream/files/redeploy.sh</files>
|
||||||
|
<action>
|
||||||
|
Replace the existing Go Dockerfile at `stacks/f1-stream/files/Dockerfile` with a Python-based Dockerfile:
|
||||||
|
|
||||||
|
```dockerfile
|
||||||
|
FROM python:3.13-slim-bookworm
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
COPY backend/requirements.txt .
|
||||||
|
RUN pip install --no-cache-dir -r requirements.txt
|
||||||
|
|
||||||
|
COPY backend/ ./backend/
|
||||||
|
|
||||||
|
EXPOSE 8000
|
||||||
|
|
||||||
|
CMD ["uvicorn", "backend.main:app", "--host", "0.0.0.0", "--port", "8000"]
|
||||||
|
```
|
||||||
|
|
||||||
|
Key points:
|
||||||
|
- Single-stage build (no build stage needed for Python -- interpreted language)
|
||||||
|
- Use `python:3.13-slim-bookworm` as base (from stack research)
|
||||||
|
- Install deps first for Docker layer caching
|
||||||
|
- Expose port 8000 (FastAPI default, different from old Go app's 8080)
|
||||||
|
- Run via uvicorn pointing to `backend.main:app`
|
||||||
|
|
||||||
|
Update `stacks/f1-stream/files/redeploy.sh`:
|
||||||
|
```bash
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
set -e
|
||||||
|
|
||||||
|
docker build -t viktorbarzin/f1-stream:v2.0.0 -t viktorbarzin/f1-stream:latest .
|
||||||
|
docker push viktorbarzin/f1-stream:v2.0.0
|
||||||
|
docker push viktorbarzin/f1-stream:latest
|
||||||
|
kubectl -n f1-stream rollout restart deployment f1-stream
|
||||||
|
```
|
||||||
|
|
||||||
|
Then build and push the image by running the redeploy script from the `stacks/f1-stream/files/` directory. Only run the docker build and push steps (skip the kubectl rollout -- that happens after Terraform apply in Plan 02).
|
||||||
|
|
||||||
|
Build command: `cd stacks/f1-stream/files && docker build -t viktorbarzin/f1-stream:v2.0.0 -t viktorbarzin/f1-stream:latest . && docker push viktorbarzin/f1-stream:v2.0.0 && docker push viktorbarzin/f1-stream:latest`
|
||||||
|
|
||||||
|
IMPORTANT: The old Go application files (main.go, go.mod, go.sum, internal/, node_modules/, package.json, package-lock.json, index.html, static/) should be removed from `stacks/f1-stream/files/` since they are no longer needed. Keep only: Dockerfile, redeploy.sh, and backend/.
|
||||||
|
</action>
|
||||||
|
<verify>
|
||||||
|
Run `docker images | grep f1-stream` to confirm the image was built.
|
||||||
|
Run `docker run --rm -d -p 18000:8000 --name f1-test viktorbarzin/f1-stream:v2.0.0 && sleep 2 && curl -s http://localhost:18000/health && docker stop f1-test` to verify the container starts and the health endpoint responds.
|
||||||
|
</verify>
|
||||||
|
<done>
|
||||||
|
Docker image `viktorbarzin/f1-stream:v2.0.0` is built, pushed to Docker Hub, and serves a 200 response on GET /health when run locally.
|
||||||
|
</done>
|
||||||
|
</task>
|
||||||
|
|
||||||
|
</tasks>
|
||||||
|
|
||||||
|
<verification>
|
||||||
|
1. `docker images | grep f1-stream` shows the v2.0.0 tag
|
||||||
|
2. Running the image locally and curling /health returns `{"status": "ok"}`
|
||||||
|
3. The old Go files have been removed from `stacks/f1-stream/files/`
|
||||||
|
4. Only Dockerfile, redeploy.sh, and backend/ remain in the files directory
|
||||||
|
</verification>
|
||||||
|
|
||||||
|
<success_criteria>
|
||||||
|
- Docker image viktorbarzin/f1-stream:v2.0.0 exists on Docker Hub
|
||||||
|
- The image runs a FastAPI server on port 8000 with a working /health endpoint
|
||||||
|
- Old Go application files are cleaned up
|
||||||
|
</success_criteria>
|
||||||
|
|
||||||
|
<output>
|
||||||
|
After completion, create `.planning/phases/01-infrastructure-and-deployment/01-01-SUMMARY.md`
|
||||||
|
</output>
|
||||||
235
.planning/phases/01-infrastructure-and-deployment/01-02-PLAN.md
Normal file
235
.planning/phases/01-infrastructure-and-deployment/01-02-PLAN.md
Normal file
|
|
@ -0,0 +1,235 @@
|
||||||
|
---
|
||||||
|
phase: 01-infrastructure-and-deployment
|
||||||
|
plan: 02
|
||||||
|
type: execute
|
||||||
|
wave: 2
|
||||||
|
depends_on:
|
||||||
|
- "01-01"
|
||||||
|
files_modified:
|
||||||
|
- stacks/f1-stream/main.tf
|
||||||
|
- .woodpecker/f1-stream.yml
|
||||||
|
autonomous: true
|
||||||
|
requirements:
|
||||||
|
- DEPL-01
|
||||||
|
- DEPL-02
|
||||||
|
|
||||||
|
must_haves:
|
||||||
|
truths:
|
||||||
|
- "A request to https://f1.viktorbarzin.me/health returns HTTP 200 with JSON {status: ok}"
|
||||||
|
- "The Terragrunt stack applies cleanly with no errors"
|
||||||
|
- "A file written to /data inside the pod survives a pod restart"
|
||||||
|
- "Woodpecker CI pipeline triggers on push for the f1-stream directory"
|
||||||
|
artifacts:
|
||||||
|
- path: "stacks/f1-stream/main.tf"
|
||||||
|
provides: "Kubernetes deployment, service, ingress, TLS for f1-stream"
|
||||||
|
contains: "viktorbarzin/f1-stream:v2.0.0"
|
||||||
|
- path: ".woodpecker/f1-stream.yml"
|
||||||
|
provides: "CI pipeline for f1-stream service"
|
||||||
|
contains: "f1-stream"
|
||||||
|
key_links:
|
||||||
|
- from: "stacks/f1-stream/main.tf"
|
||||||
|
to: "Docker Hub viktorbarzin/f1-stream:v2.0.0"
|
||||||
|
via: "kubernetes_deployment image reference"
|
||||||
|
pattern: "viktorbarzin/f1-stream:v2.0.0"
|
||||||
|
- from: "stacks/f1-stream/main.tf"
|
||||||
|
to: "NFS /mnt/main/f1-stream"
|
||||||
|
via: "inline NFS volume mount"
|
||||||
|
pattern: "/mnt/main/f1-stream"
|
||||||
|
- from: "stacks/f1-stream/main.tf"
|
||||||
|
to: "modules/kubernetes/ingress_factory"
|
||||||
|
via: "ingress module call"
|
||||||
|
pattern: "ingress_factory"
|
||||||
|
---
|
||||||
|
|
||||||
|
<objective>
|
||||||
|
Update the Terraform stack to deploy the new Python/FastAPI container, verify NFS mount persistence, and add a Woodpecker CI pipeline. This completes Phase 1 by making the service live on the cluster and reachable at its public URL.
|
||||||
|
|
||||||
|
Purpose: The service must be running on the Kubernetes cluster, reachable at f1.viktorbarzin.me, with NFS storage mounted and CI/CD in place -- ready for application development in Phase 2.
|
||||||
|
Output: Live deployment at f1.viktorbarzin.me, NFS-backed persistent storage, Woodpecker CI pipeline.
|
||||||
|
</objective>
|
||||||
|
|
||||||
|
<execution_context>
|
||||||
|
@/Users/viktorbarzin/.claude/get-shit-done/workflows/execute-plan.md
|
||||||
|
@/Users/viktorbarzin/.claude/get-shit-done/templates/summary.md
|
||||||
|
</execution_context>
|
||||||
|
|
||||||
|
<context>
|
||||||
|
@.planning/PROJECT.md
|
||||||
|
@.planning/ROADMAP.md
|
||||||
|
@.planning/STATE.md
|
||||||
|
@.planning/phases/01-infrastructure-and-deployment/01-01-SUMMARY.md
|
||||||
|
|
||||||
|
# Key reference files:
|
||||||
|
@stacks/f1-stream/main.tf
|
||||||
|
@stacks/f1-stream/terragrunt.hcl
|
||||||
|
@.woodpecker/build-cli.yml
|
||||||
|
@.woodpecker/default.yml
|
||||||
|
</context>
|
||||||
|
|
||||||
|
<tasks>
|
||||||
|
|
||||||
|
<task type="auto">
|
||||||
|
<name>Task 1: Update Terraform deployment for Python/FastAPI and verify NFS mount</name>
|
||||||
|
<files>stacks/f1-stream/main.tf</files>
|
||||||
|
<action>
|
||||||
|
Modify `stacks/f1-stream/main.tf` to update the deployment for the new Python/FastAPI application:
|
||||||
|
|
||||||
|
1. **Change the container image** from `viktorbarzin/f1-stream:v1.3.1` to `viktorbarzin/f1-stream:v2.0.0`
|
||||||
|
|
||||||
|
2. **Change the container port** from 8080 to 8000 (FastAPI/uvicorn default)
|
||||||
|
|
||||||
|
3. **Update the service target_port** from 8080 to 8000
|
||||||
|
|
||||||
|
4. **Remove old Go-specific environment variables** that are no longer needed:
|
||||||
|
- Remove `WEBAUTHN_RPID`
|
||||||
|
- Remove `WEBAUTHN_ORIGIN`
|
||||||
|
- Remove `WEBAUTHN_DISPLAY_NAME`
|
||||||
|
- Remove `HEADLESS_EXTRACT_ENABLED`
|
||||||
|
- Remove `TURN_URL`
|
||||||
|
- Remove `TURN_SHARED_SECRET`
|
||||||
|
- Remove `TURN_INTERNAL_URL`
|
||||||
|
|
||||||
|
5. **Remove unused variables** from the top of the file:
|
||||||
|
- Remove `variable "coturn_turn_secret"` (was for WebRTC/TURN)
|
||||||
|
- Remove `variable "public_ip"` (was for TURN URL)
|
||||||
|
- Keep `variable "tls_secret_name"` and `variable "nfs_server"` (still needed)
|
||||||
|
|
||||||
|
6. **Keep the NFS volume mount** exactly as-is -- it already follows the inline NFS pattern:
|
||||||
|
```hcl
|
||||||
|
volume {
|
||||||
|
name = "data"
|
||||||
|
nfs {
|
||||||
|
server = var.nfs_server
|
||||||
|
path = "/mnt/main/f1-stream"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
The volume_mount at `/data` stays the same.
|
||||||
|
|
||||||
|
7. **Update resource limits** for Python:
|
||||||
|
```hcl
|
||||||
|
resources {
|
||||||
|
limits = {
|
||||||
|
cpu = "500m"
|
||||||
|
memory = "256Mi"
|
||||||
|
}
|
||||||
|
requests = {
|
||||||
|
cpu = "50m"
|
||||||
|
memory = "64Mi"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
Python/FastAPI with uvicorn needs less CPU than Go+Chromium but similar memory.
|
||||||
|
|
||||||
|
8. **Keep everything else unchanged**: namespace, service, tls_secret module, ingress module.
|
||||||
|
|
||||||
|
After editing, apply the Terraform stack:
|
||||||
|
```bash
|
||||||
|
cd stacks/f1-stream && terragrunt apply --non-interactive
|
||||||
|
```
|
||||||
|
|
||||||
|
Wait for the deployment to roll out:
|
||||||
|
```bash
|
||||||
|
kubectl --kubeconfig $(pwd)/config -n f1-stream rollout status deployment/f1-stream --timeout=120s
|
||||||
|
```
|
||||||
|
|
||||||
|
Verify the pod is running:
|
||||||
|
```bash
|
||||||
|
kubectl --kubeconfig $(pwd)/config -n f1-stream get pods
|
||||||
|
```
|
||||||
|
|
||||||
|
Verify the health endpoint responds through the public URL:
|
||||||
|
```bash
|
||||||
|
curl -s https://f1.viktorbarzin.me/health
|
||||||
|
```
|
||||||
|
|
||||||
|
Verify NFS mount persistence by writing a test file, restarting the pod, and reading it back:
|
||||||
|
```bash
|
||||||
|
POD=$(kubectl --kubeconfig $(pwd)/config -n f1-stream get pods -l app=f1-stream -o jsonpath='{.items[0].metadata.name}')
|
||||||
|
kubectl --kubeconfig $(pwd)/config -n f1-stream exec $POD -- sh -c 'echo "nfs-test-$(date +%s)" > /data/test-file.txt && cat /data/test-file.txt'
|
||||||
|
kubectl --kubeconfig $(pwd)/config -n f1-stream rollout restart deployment/f1-stream
|
||||||
|
kubectl --kubeconfig $(pwd)/config -n f1-stream rollout status deployment/f1-stream --timeout=120s
|
||||||
|
NEW_POD=$(kubectl --kubeconfig $(pwd)/config -n f1-stream get pods -l app=f1-stream -o jsonpath='{.items[0].metadata.name}')
|
||||||
|
kubectl --kubeconfig $(pwd)/config -n f1-stream exec $NEW_POD -- cat /data/test-file.txt
|
||||||
|
```
|
||||||
|
The test file should contain the same content after the pod restart.
|
||||||
|
</action>
|
||||||
|
<verify>
|
||||||
|
1. `terragrunt apply` exits with 0 (no errors)
|
||||||
|
2. `kubectl get pods -n f1-stream` shows 1/1 Running
|
||||||
|
3. `curl -s https://f1.viktorbarzin.me/health` returns `{"status":"ok"}`
|
||||||
|
4. NFS persistence test passes (file survives pod restart)
|
||||||
|
</verify>
|
||||||
|
<done>
|
||||||
|
The f1-stream deployment is running on the cluster with the new Python/FastAPI image, reachable at https://f1.viktorbarzin.me/health, and the NFS volume at /data persists data across pod restarts.
|
||||||
|
</done>
|
||||||
|
</task>
|
||||||
|
|
||||||
|
<task type="auto">
|
||||||
|
<name>Task 2: Create Woodpecker CI pipeline for f1-stream</name>
|
||||||
|
<files>.woodpecker/f1-stream.yml</files>
|
||||||
|
<action>
|
||||||
|
Create `.woodpecker/f1-stream.yml` following the pattern from `build-cli.yml`:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
when:
|
||||||
|
event: push
|
||||||
|
path:
|
||||||
|
include:
|
||||||
|
- "stacks/f1-stream/files/**"
|
||||||
|
|
||||||
|
clone:
|
||||||
|
git:
|
||||||
|
image: woodpeckerci/plugin-git
|
||||||
|
settings:
|
||||||
|
attempts: 5
|
||||||
|
backoff: 10s
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: build-image
|
||||||
|
image: woodpeckerci/plugin-docker-buildx
|
||||||
|
settings:
|
||||||
|
username: "viktorbarzin"
|
||||||
|
password:
|
||||||
|
from_secret: dockerhub-pat
|
||||||
|
repo: viktorbarzin/f1-stream
|
||||||
|
dockerfile: stacks/f1-stream/files/Dockerfile
|
||||||
|
context: stacks/f1-stream/files
|
||||||
|
auto_tag: true
|
||||||
|
```
|
||||||
|
|
||||||
|
Key differences from the default pipeline:
|
||||||
|
- **Path filter**: Only triggers when files under `stacks/f1-stream/files/` change (the application code)
|
||||||
|
- **Builds and pushes the Docker image** using the same `woodpeckerci/plugin-docker-buildx` pattern as build-cli.yml
|
||||||
|
- **Docker context** points to the `stacks/f1-stream/files/` directory where the Dockerfile lives
|
||||||
|
- Does NOT run Terragrunt apply (that is done manually or by the default pipeline for the platform stack)
|
||||||
|
</action>
|
||||||
|
<verify>
|
||||||
|
Verify the YAML is valid: `python3 -c "import yaml; yaml.safe_load(open('.woodpecker/f1-stream.yml')); print('YAML OK')"`
|
||||||
|
Verify the file exists and references f1-stream correctly.
|
||||||
|
</verify>
|
||||||
|
<done>
|
||||||
|
Woodpecker CI pipeline file exists at `.woodpecker/f1-stream.yml`, configured to build and push the Docker image when files under `stacks/f1-stream/files/` change.
|
||||||
|
</done>
|
||||||
|
</task>
|
||||||
|
|
||||||
|
</tasks>
|
||||||
|
|
||||||
|
<verification>
|
||||||
|
1. `curl -s https://f1.viktorbarzin.me/health` returns `{"status":"ok"}`
|
||||||
|
2. `cd stacks/f1-stream && terragrunt plan --non-interactive` shows no changes (stack is clean)
|
||||||
|
3. NFS test file written before pod restart is readable after pod restart
|
||||||
|
4. `.woodpecker/f1-stream.yml` exists and is valid YAML
|
||||||
|
5. `kubectl --kubeconfig $(pwd)/config -n f1-stream get pods` shows 1/1 Running
|
||||||
|
</verification>
|
||||||
|
|
||||||
|
<success_criteria>
|
||||||
|
- The service is live at https://f1.viktorbarzin.me and responds with 200 on /health
|
||||||
|
- Terragrunt stack applies cleanly with no manual cluster intervention
|
||||||
|
- NFS volume mount at /data persists data across pod restarts
|
||||||
|
- Woodpecker CI pipeline exists for automated image builds
|
||||||
|
</success_criteria>
|
||||||
|
|
||||||
|
<output>
|
||||||
|
After completion, create `.planning/phases/01-infrastructure-and-deployment/01-02-SUMMARY.md`
|
||||||
|
</output>
|
||||||
Loading…
Add table
Add a link
Reference in a new issue