CI/CD Pipeline¶
GreenThumb uses GitHub Actions for continuous integration and deployment.
Overview¶
graph LR
DEV[Developer] -->|push| GH[GitHub]
GH -->|trigger| GA[GitHub Actions]
GA -->|build| DH[Docker Hub]
DH -->|pull| WT[Watchtower]
WT -->|restart| RPI[Raspberry Pi]
Workflows¶
rasp5: Build and Push¶
File: .github/workflows/build.yml
Triggers:
- Push to main branch
- Manual dispatch
Steps:
- Checkout code
- Set up QEMU (for ARM64 builds)
- Set up Docker Buildx
- Login to Docker Hub
- Build and push
greenthumb-api - Build and push
greenthumb-data-collection
name: Build and Push Docker Images
on:
push:
branches: [main]
workflow_dispatch:
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: docker/setup-qemu-action@v3
- uses: docker/setup-buildx-action@v3
- uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- uses: docker/build-push-action@v5
with:
context: ./fastapi
platforms: linux/arm64
push: true
tags: ${{ secrets.DOCKERHUB_USERNAME }}/greenthumb-api:latest
build-args: |
GH_PAT=${{ secrets.GH_PAT }}
docs: Deploy Documentation¶
File: .github/workflows/deploy.yml
Triggers:
- Push to main branch
- Manual dispatch
Steps:
- Checkout code
- Setup Python
- Install MkDocs dependencies
- Build documentation
- Deploy to GitHub Pages
Required Secrets¶
Repository Secrets (rasp5)¶
| Secret | Description |
|---|---|
DOCKERHUB_USERNAME |
Docker Hub username |
DOCKERHUB_TOKEN |
Docker Hub access token |
GH_PAT |
GitHub PAT for private repos |
How to Add Secrets¶
- Go to repository Settings
- Click "Secrets and variables" > "Actions"
- Click "New repository secret"
- Enter name and value
Automatic Updates¶
Watchtower¶
Watchtower runs on the Raspberry Pi and automatically:
- Polls Docker Hub every 5 minutes
- Pulls new images when available
- Restarts containers with new images
- Cleans up old images
Configuration (in compose.yaml):
watchtower:
image: containrrr/watchtower
restart: unless-stopped
volumes:
- /var/run/docker.sock:/var/run/docker.sock
environment:
WATCHTOWER_POLL_INTERVAL: 300
WATCHTOWER_CLEANUP: "true"
Deployment Flow¶
-
Developer pushes to main
-
GitHub Actions builds
- ~5-10 minutes for ARM64 build
-
Images pushed to Docker Hub
-
Watchtower detects update
- Checks every 5 minutes
-
Pulls new images
-
Containers restart
- Zero-downtime for api/data_collection
- Database persists data
Monitoring¶
Check Build Status¶
- Go to repository > Actions tab
- View workflow runs and logs
Check Deployment Status¶
Verify New Version¶
Troubleshooting¶
Build Fails¶
- Check GitHub Actions logs
- Verify secrets are set correctly
- Ensure Dockerfile is valid
Watchtower Not Updating¶
# Check watchtower logs
docker compose logs watchtower
# Force pull
docker compose pull
docker compose up -d
ARM64 Build Issues¶
- Ensure QEMU is set up
- Check platform is
linux/arm64 - Verify base image supports ARM64