All checks were successful
Deploy to NAS / deploy (push) Successful in 44s
- README.md: rewrite with accurate setup steps including all lessons learned - CLAUDE.md: update with working CI/CD patterns and known pitfalls - gitea-actions.md: new file documenting Gitea Actions usage, expressions, act_runner config, and troubleshooting for future projects Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
3.8 KiB
3.8 KiB
CLAUDE.md — NAS Infrastruktur
Kontext für Claude Code Sessions zum Thema Deployment und Infrastruktur auf der Synology NAS.
Umgebung
- NAS: Synology DiskStation, DSM 7.x, IP:
192.168.1.4 - SSH:
ssh jacek@192.168.1.4— Docker-Befehle erfordernsudo - Docker-Datenpfad:
/volume2/docker/— alle persistenten Daten hier - Docker-Binary auf NAS:
/usr/local/bin/docker - Gitea:
http://192.168.1.4:3000(Docker-Container auf NAS)
Laufende Dienste
| Dienst | Container | Port | Pfad |
|---|---|---|---|
| PostgreSQL | shared-postgres-1 |
5433 | /volume2/docker/shared/ |
| act_runner | gitea-runner |
— | /volume2/docker/gitea-runner/ |
| Pamietnik | pamietnik-api-1 |
9050 | /volume2/docker/pamietnik/ |
Datenbankzugriff
Aus Containern: host-gateway:5433
(host-gateway ist Docker's eingebauter Alias für den Host — in extra_hosts und docker-compose.yml deklarieren)
Remote (Heimnetz): psql -h 192.168.1.4 -p 5433 -U <user> -d <db>
Direkt auf NAS:
sudo docker exec -it shared-postgres-1 psql -U postgres
Wichtig PostgreSQL 15+: Nach GRANT ALL PRIVILEGES ON DATABASE zusätzlich:
GRANT ALL ON SCHEMA public TO <user>;
CI/CD: Gitea Actions
Workflow-Datei: .gitea/workflows/deploy.yml
Trigger: Push auf main
Runner-Setup:
- Container:
gitea/act_runner:latestmit--network host GITEA_INSTANCE_URLmuss NAS-IP sein (192.168.1.4:3000), nichtlocalhostconfig.yamlbrauchtvalid_volumes: [/volume2/docker]sonst werden Mounts ignoriert
Job-Container: docker:latest mit -v /volume2/docker:/volume2/docker
- Docker CLI ist im Image enthalten
- Socket wird automatisch vom Runner propagiert (nicht nochmal in
optionsmounten → Duplicate-Fehler) wgetstattcurlverwenden (curlnicht im Image)
Gitea Konfiguration:
- Nicht-sensitive Werte (Pfade, Ports, DB-Namen) → Variables (
vars.NAME) - Passwörter, Tokens → Secrets (
secrets.NAME) - Variables mit Leerzeichen am Ende → Parsing-Fehler in Expressions
Deployment-Muster für neue Projekte
# docker-compose.yml im Repo
services:
api:
build: .
ports:
- "${APP_PORT:-8080}:8080"
extra_hosts:
- "host-gateway:host-gateway"
environment:
DATABASE_URL: postgres://${DB_USER}:${DB_PASSWORD}@host-gateway:5433/${DB_NAME}
volumes:
- /volume2/docker/<projekt>/uploads:/uploads
restart: unless-stopped
# .gitea/workflows/deploy.yml
jobs:
deploy:
runs-on: self-hosted
container:
image: docker:latest
options: -v /volume2/docker:/volume2/docker
steps:
- name: Pull code
run: |
if [ -d "${{ vars.DEPLOY_DIR }}/.git" ]; then
git -C ${{ vars.DEPLOY_DIR }} pull
else
git clone http://192.168.1.4:3000/<org>/<repo>.git ${{ vars.DEPLOY_DIR }}
fi
- name: Write .env
run: printf 'DB_PASSWORD=%s\n' '${{ secrets.DB_PASSWORD }}' > ${{ vars.DEPLOY_DIR }}/.env
- name: Build & Deploy
run: docker compose -f ${{ vars.DEPLOY_DIR }}/docker-compose.yml up --build -d
- name: Health check
run: sleep 15 && wget -qO- http://192.168.1.4:${{ vars.APP_PORT }}/healthz || exit 1
Bekannte Fallstricke
Secure: trueauf Session-Cookies schlägt fehl bei HTTP →Secure: falsesetzen- Ports unter 1024 können Container auf Synology nicht binden → internen Port > 1024 wählen
localhostim Job-Container zeigt auf den Container selbst, nicht auf die NAS- Volume-Mounts in Workflow
container.optionswerden doppelt gemountet wenn identisch mit Runner-Mount /volume2/dockermuss invalid_volumesderconfig.yamlstehen sonst wird Mount ignoriert
Vollständige Setup-Anleitung
Siehe infra/README.md