Enable CD deployment to Hetzner (task 11.8)
CD workflow: - Uncommented deploy step - Copy docker-compose.yml + Caddyfile to server via SCP - Login to ghcr.io with DEPLOY_GHCR_TOKEN (classic PAT, read:packages) - Download Germany BRouter segments on first deploy (~750MB) - Pull images, restart services, verify Infrastructure: - BRouter segments as bind mount (./segments) not Docker volume - Added ORIGIN, PLANNER_URL, SESSION_SECRET, NODE_ENV to Journal - Added NODE_ENV to Planner - Disabled Garage for now (no media storage yet) Required secrets: DEPLOY_HOST, DEPLOY_SSH_KEY, DEPLOY_GHCR_TOKEN Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
970f591a60
commit
8e2f183288
2 changed files with 58 additions and 32 deletions
63
.github/workflows/cd.yml
vendored
63
.github/workflows/cd.yml
vendored
|
|
@ -59,20 +59,49 @@ jobs:
|
||||||
ghcr.io/trails-cool/brouter:latest
|
ghcr.io/trails-cool/brouter:latest
|
||||||
ghcr.io/trails-cool/brouter:${{ github.sha }}
|
ghcr.io/trails-cool/brouter:${{ github.sha }}
|
||||||
|
|
||||||
# Deploy step - uncomment when Hetzner server is provisioned
|
deploy:
|
||||||
# deploy:
|
name: Deploy to Hetzner
|
||||||
# name: Deploy to Hetzner
|
needs: [build-images, build-brouter]
|
||||||
# needs: [build-images, build-brouter]
|
runs-on: ubuntu-latest
|
||||||
# runs-on: ubuntu-latest
|
steps:
|
||||||
# steps:
|
- uses: actions/checkout@v6
|
||||||
# - uses: actions/checkout@v6
|
|
||||||
# - name: Deploy via SSH
|
- name: Copy files to server
|
||||||
# uses: appleboy/ssh-action@v1
|
uses: appleboy/scp-action@v1
|
||||||
# with:
|
with:
|
||||||
# host: ${{ secrets.DEPLOY_HOST }}
|
host: ${{ secrets.DEPLOY_HOST }}
|
||||||
# username: root
|
username: root
|
||||||
# key: ${{ secrets.DEPLOY_SSH_KEY }}
|
key: ${{ secrets.DEPLOY_SSH_KEY }}
|
||||||
# script: |
|
source: "infrastructure/docker-compose.yml,infrastructure/Caddyfile"
|
||||||
# cd /opt/trails-cool
|
target: /opt/trails-cool
|
||||||
# docker compose pull
|
strip_components: 1
|
||||||
# docker compose up -d
|
|
||||||
|
- name: Deploy via SSH
|
||||||
|
uses: appleboy/ssh-action@v1
|
||||||
|
with:
|
||||||
|
host: ${{ secrets.DEPLOY_HOST }}
|
||||||
|
username: root
|
||||||
|
key: ${{ secrets.DEPLOY_SSH_KEY }}
|
||||||
|
script: |
|
||||||
|
cd /opt/trails-cool
|
||||||
|
|
||||||
|
# Login to ghcr.io to pull private images
|
||||||
|
echo "${{ secrets.DEPLOY_GHCR_TOKEN }}" | docker login ghcr.io -u stigi --password-stdin
|
||||||
|
|
||||||
|
# Download BRouter segments if missing
|
||||||
|
if [ ! -d /opt/trails-cool/segments ] || [ -z "$(ls /opt/trails-cool/segments/*.rd5 2>/dev/null)" ]; then
|
||||||
|
mkdir -p /opt/trails-cool/segments
|
||||||
|
echo "Downloading Germany BRouter segments..."
|
||||||
|
for tile in E5_N45 E5_N50 E10_N45 E10_N50; do
|
||||||
|
[ -f "/opt/trails-cool/segments/${tile}.rd5" ] || \
|
||||||
|
wget -q "https://brouter.de/brouter/segments4/${tile}.rd5" -O "/opt/trails-cool/segments/${tile}.rd5"
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Pull latest images and restart
|
||||||
|
docker compose pull
|
||||||
|
docker compose up -d --remove-orphans
|
||||||
|
|
||||||
|
# Verify services are running
|
||||||
|
sleep 10
|
||||||
|
docker compose ps
|
||||||
|
|
|
||||||
|
|
@ -19,12 +19,12 @@ services:
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
environment:
|
environment:
|
||||||
DOMAIN: ${DOMAIN:-trails.cool}
|
DOMAIN: ${DOMAIN:-trails.cool}
|
||||||
|
ORIGIN: https://${DOMAIN:-trails.cool}
|
||||||
|
PLANNER_URL: https://planner.${DOMAIN:-trails.cool}
|
||||||
DATABASE_URL: postgres://trails:${POSTGRES_PASSWORD:-trails}@postgres:5432/trails
|
DATABASE_URL: postgres://trails:${POSTGRES_PASSWORD:-trails}@postgres:5432/trails
|
||||||
S3_ENDPOINT: http://garage:3900
|
|
||||||
S3_BUCKET: trails-media
|
|
||||||
S3_ACCESS_KEY: ${S3_ACCESS_KEY:-}
|
|
||||||
S3_SECRET_KEY: ${S3_SECRET_KEY:-}
|
|
||||||
JWT_SECRET: ${JWT_SECRET:-change-me-in-production}
|
JWT_SECRET: ${JWT_SECRET:-change-me-in-production}
|
||||||
|
SESSION_SECRET: ${SESSION_SECRET:-change-me-in-production}
|
||||||
|
NODE_ENV: production
|
||||||
PORT: 3000
|
PORT: 3000
|
||||||
depends_on:
|
depends_on:
|
||||||
postgres:
|
postgres:
|
||||||
|
|
@ -36,6 +36,7 @@ services:
|
||||||
environment:
|
environment:
|
||||||
BROUTER_URL: http://brouter:17777
|
BROUTER_URL: http://brouter:17777
|
||||||
DATABASE_URL: postgres://trails:${POSTGRES_PASSWORD:-trails}@postgres:5432/trails
|
DATABASE_URL: postgres://trails:${POSTGRES_PASSWORD:-trails}@postgres:5432/trails
|
||||||
|
NODE_ENV: production
|
||||||
PORT: 3001
|
PORT: 3001
|
||||||
depends_on:
|
depends_on:
|
||||||
postgres:
|
postgres:
|
||||||
|
|
@ -47,8 +48,7 @@ services:
|
||||||
image: ghcr.io/trails-cool/brouter:latest
|
image: ghcr.io/trails-cool/brouter:latest
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
volumes:
|
volumes:
|
||||||
- brouter_segments:/data/segments
|
- ./segments:/data/segments
|
||||||
- brouter_profiles:/data/profiles
|
|
||||||
# Segments can be pulled from:
|
# Segments can be pulled from:
|
||||||
# - https://brouter.de/brouter/segments4/ (official, weekly updates)
|
# - https://brouter.de/brouter/segments4/ (official, weekly updates)
|
||||||
# - A trails.cool CDN mirror (later)
|
# - A trails.cool CDN mirror (later)
|
||||||
|
|
@ -68,17 +68,14 @@ services:
|
||||||
timeout: 5s
|
timeout: 5s
|
||||||
retries: 5
|
retries: 5
|
||||||
|
|
||||||
garage:
|
# garage:
|
||||||
image: dxflrs/garage:v1.0
|
# image: dxflrs/garage:v1.0
|
||||||
restart: unless-stopped
|
# restart: unless-stopped
|
||||||
volumes:
|
# volumes:
|
||||||
- garage_data:/var/lib/garage
|
# - garage_data:/var/lib/garage
|
||||||
- ./garage.toml:/etc/garage.toml:ro
|
# - ./garage.toml:/etc/garage.toml:ro
|
||||||
|
|
||||||
volumes:
|
volumes:
|
||||||
caddy_data:
|
caddy_data:
|
||||||
caddy_config:
|
caddy_config:
|
||||||
pgdata:
|
pgdata:
|
||||||
brouter_segments:
|
|
||||||
brouter_profiles:
|
|
||||||
garage_data:
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue