From 257d1e40624312e34cc073c116b2d484a0e39b61 Mon Sep 17 00:00:00 2001 From: "Christoph K." Date: Tue, 7 Apr 2026 15:42:58 +0200 Subject: [PATCH] Add Gitea CI/CD pipeline and shared infra setup - docker-compose.yml: remove bundled postgres, connect to shared postgres via host-gateway:5433, add uploads volume, configurable port - .gitea/workflows/deploy.yml: Gitea Actions workflow for automated deploy on push to main - infra/README.md: step-by-step setup guide for NAS deployment (shared postgres, pgAdmin, act_runner, Gitea secrets) Co-Authored-By: Claude Sonnet 4.6 --- .gitea/workflows/deploy.yml | 26 +++++ docker-compose.yml | 29 ++---- infra/README.md | 199 ++++++++++++++++++++++++++++++++++++ 3 files changed, 232 insertions(+), 22 deletions(-) create mode 100644 .gitea/workflows/deploy.yml create mode 100644 infra/README.md diff --git a/.gitea/workflows/deploy.yml b/.gitea/workflows/deploy.yml new file mode 100644 index 0000000..affff09 --- /dev/null +++ b/.gitea/workflows/deploy.yml @@ -0,0 +1,26 @@ +name: Deploy to NAS + +on: + push: + branches: [main] + +jobs: + deploy: + runs-on: self-hosted + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Write .env + run: printf 'DB_PASSWORD=%s\n' '${{ secrets.DB_PASSWORD }}' > ${{ secrets.DEPLOY_DIR }}/.env + + - name: Build & Deploy + run: | + cp -r ${{ github.workspace }}/. ${{ secrets.DEPLOY_DIR }}/ + docker compose -f ${{ secrets.DEPLOY_DIR }}/docker-compose.yml up --build -d + + - name: Health check + run: | + sleep 15 + curl -sf http://localhost:9050/healthz || exit 1 diff --git a/docker-compose.yml b/docker-compose.yml index f86922e..da3dea6 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,31 +1,16 @@ services: - postgres: - image: postgres:16-alpine - environment: - POSTGRES_USER: ${DB_USER:-pamietnik} - POSTGRES_PASSWORD: ${DB_PASSWORD:?DB_PASSWORD is required} - POSTGRES_DB: ${DB_NAME:-pamietnik} - volumes: - - pgdata:/var/lib/postgresql/data - healthcheck: - test: ["CMD-SHELL", "pg_isready -U ${DB_USER:-pamietnik}"] - interval: 5s - timeout: 5s - retries: 5 - api: build: context: . dockerfile: Dockerfile ports: - - "9050:8080" + - "${APP_PORT:-9050}:8080" + extra_hosts: + - "host-gateway:host-gateway" environment: - DATABASE_URL: postgres://${DB_USER:-pamietnik}:${DB_PASSWORD:?DB_PASSWORD is required}@postgres:5432/${DB_NAME:-pamietnik}?sslmode=disable + DATABASE_URL: postgres://${DB_USER:-pamietnik}:${DB_PASSWORD:?DB_PASSWORD is required}@host-gateway:5433/${DB_NAME:-pamietnik}?sslmode=disable LISTEN_ADDR: :8080 - depends_on: - postgres: - condition: service_healthy + UPLOAD_DIR: /uploads + volumes: + - /volume2/docker/pamietnik/uploads:/uploads restart: unless-stopped - -volumes: - pgdata: diff --git a/infra/README.md b/infra/README.md new file mode 100644 index 0000000..9adf0e4 --- /dev/null +++ b/infra/README.md @@ -0,0 +1,199 @@ +# Infrastruktur & Deployment + +## Übersicht + +``` +Synology NAS +├── /volume2/docker/shared/ ← Geteilte Infrastruktur (PostgreSQL + pgAdmin) +│ ├── docker-compose.yml +│ ├── .env +│ ├── pgdata/ ← PostgreSQL-Daten (persistent) +│ └── pgadmin/ ← pgAdmin-Daten (persistent) +│ +└── /volume2/docker/pamietnik/ ← Pamietnik-Deployment + ├── docker-compose.yml ← Kopie aus dem Repo (via CI/CD) + ├── .env + └── uploads/ ← Hochgeladene Bilder (persistent) +``` + +--- + +## 1. Geteilte Infrastruktur einrichten (einmalig) + +### Verzeichnisse anlegen + +```bash +sudo mkdir -p /volume2/docker/shared/pgdata +sudo mkdir -p /volume2/docker/shared/pgadmin +sudo chown -R 5050:5050 /volume2/docker/shared/pgadmin +``` + +### docker-compose.yml anlegen + +Datei `/volume2/docker/shared/docker-compose.yml`: + +```yaml +services: + postgres: + image: postgres:16-alpine + restart: unless-stopped + ports: + - "5433:5432" + environment: + POSTGRES_USER: ${POSTGRES_USER:-postgres} + POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:?POSTGRES_PASSWORD is required} + volumes: + - /volume2/docker/shared/pgdata:/var/lib/postgresql/data + healthcheck: + test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-postgres}"] + interval: 5s + timeout: 5s + retries: 5 + + pgadmin: + image: dpage/pgadmin4:latest + restart: unless-stopped + ports: + - "5050:8080" + environment: + PGADMIN_DEFAULT_EMAIL: ${PGADMIN_EMAIL} + PGADMIN_DEFAULT_PASSWORD: ${PGADMIN_PASSWORD} + PGADMIN_LISTEN_PORT: 8080 + volumes: + - /volume2/docker/shared/pgadmin:/var/lib/pgadmin +``` + +### .env anlegen + +Datei `/volume2/docker/shared/.env`: + +```env +POSTGRES_PASSWORD= +PGADMIN_EMAIL=deine@email.de +PGADMIN_PASSWORD= +``` + +### Starten + +```bash +cd /volume2/docker/shared +sudo docker compose up -d +``` + +### Datenbank & User anlegen + +```bash +sudo docker exec -it shared-postgres-1 psql -U postgres +``` + +```sql +CREATE DATABASE pamietnik; +CREATE USER pamietnik WITH PASSWORD 'deinPasswort'; +GRANT ALL PRIVILEGES ON DATABASE pamietnik TO pamietnik; +\q +``` + +--- + +## 2. Pamietnik-Deployment einrichten (einmalig) + +```bash +sudo mkdir -p /volume2/docker/pamietnik/uploads +``` + +Datei `/volume2/docker/pamietnik/.env`: + +```env +DB_PASSWORD= +APP_PORT=9050 +``` + +--- + +## 3. Gitea CI/CD einrichten (einmalig) + +### act_runner starten + +Token holen: **Gitea → Site-Administration → Actions → Runner → Runner erstellen** + +```bash +sudo docker run -d \ + --name gitea-runner \ + --restart unless-stopped \ + --network host \ + -v /var/run/docker.sock:/var/run/docker.sock \ + -v /volume2/docker/gitea-runner:/data \ + -e GITEA_INSTANCE_URL=http://localhost:3000 \ + -e GITEA_RUNNER_REGISTRATION_TOKEN= \ + -e GITEA_RUNNER_NAME=nas-runner \ + -e GITEA_RUNNER_LABELS=self-hosted,linux,amd64 \ + gitea/act_runner:latest +``` + +### Gitea Secrets & Variables setzen + +**Repository → Einstellungen → Actions → Secrets:** + +| Secret | Wert | +|--------|------| +| `DB_PASSWORD` | Passwort des `pamietnik` DB-Users | +| `DEPLOY_DIR` | `/volume2/docker/pamietnik` | + +**Repository → Einstellungen → Actions → Variables:** + +| Variable | Wert | +|----------|------| +| `DB_USER` | `pamietnik` | +| `DB_NAME` | `pamietnik` | +| `APP_PORT` | `9050` | + +--- + +## 4. Dienste & URLs + +| Dienst | URL | +|--------|-----| +| Pamietnik App | `http://:9050` | +| pgAdmin | `http://:5050` | +| PostgreSQL | `psql -h -p 5433 -U pamietnik -d pamietnik` | + +--- + +## 5. Neues Projekt hinzufügen + +```bash +sudo docker exec -it shared-postgres-1 psql -U postgres +``` + +```sql +CREATE DATABASE neuprojekt; +CREATE USER neuprojekt WITH PASSWORD 'passwort'; +GRANT ALL PRIVILEGES ON DATABASE neuprojekt TO neuprojekt; +\q +``` + +In `docker-compose.yml` des neuen Projekts: +```yaml +extra_hosts: + - "host-gateway:host-gateway" +environment: + DATABASE_URL: postgres://neuprojekt:passwort@host-gateway:5433/neuprojekt +``` + +--- + +## 6. Wartung + +```bash +# Logs +sudo docker compose -f /volume2/docker/shared/docker-compose.yml logs -f +sudo docker compose -f /volume2/docker/pamietnik/docker-compose.yml logs -f api + +# Backup +sudo docker exec shared-postgres-1 pg_dump -U postgres pamietnik \ + > /volume2/docker/shared/backup_$(date +%Y%m%d).sql + +# Stoppen +sudo docker compose -f /volume2/docker/shared/docker-compose.yml down +sudo docker compose -f /volume2/docker/pamietnik/docker-compose.yml down +```