Compare commits
5 Commits
de6e387c7b
...
579597776c
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
579597776c | ||
|
|
1fb015b0fc | ||
|
|
2a74ea3702 | ||
|
|
257d1e4062 | ||
|
|
b865e5a283 |
26
.gitea/workflows/deploy.yml
Normal file
26
.gitea/workflows/deploy.yml
Normal file
@@ -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
|
||||
2
backend
2
backend
Submodule backend updated: dbcb0d4a09...c3d432e24d
@@ -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:
|
||||
|
||||
155
infra/CLAUDE.md
Normal file
155
infra/CLAUDE.md
Normal file
@@ -0,0 +1,155 @@
|
||||
# CLAUDE.md — Pamietnik Infrastruktur
|
||||
|
||||
Diese Datei ist Kontext für eine dedizierte Infra-Session. Hier ist alles beschrieben, was zum Aufbau und Betrieb der Infrastruktur auf der Synology NAS notwendig ist.
|
||||
|
||||
---
|
||||
|
||||
## Umgebung
|
||||
|
||||
- **NAS:** Synology DiskStation, DSM 7.x
|
||||
- **Docker-Datenpfad:** `/volume2/docker/` (alle Container-Daten hier ablegen)
|
||||
- **Docker-Socket:** `/var/run/docker.sock`
|
||||
- **Gitea:** läuft als Docker-Container auf der NAS, erreichbar unter `http://localhost:3000`
|
||||
- **SSH-Zugriff:** `ssh jacek@<NAS-IP>`, sudo-Befehle erforderlich für Docker
|
||||
|
||||
---
|
||||
|
||||
## Architektur
|
||||
|
||||
```
|
||||
Synology NAS
|
||||
├── Gitea (Docker) :3000 — Git-Server + CI/CD
|
||||
├── act_runner (Docker) — Gitea Actions Runner
|
||||
│
|
||||
├── /volume2/docker/shared/
|
||||
│ └── postgres:16-alpine :5433 — Geteilte DB für alle Projekte
|
||||
│
|
||||
└── /volume2/docker/pamietnik/
|
||||
└── api (Go + SPA) :9050 — Pamietnik App
|
||||
```
|
||||
|
||||
**Verbindung App → Datenbank:** über `host-gateway:5433` (Docker-interner Alias für den NAS-Host)
|
||||
|
||||
---
|
||||
|
||||
## Verzeichnisse auf der NAS
|
||||
|
||||
| Pfad | Inhalt |
|
||||
|------|--------|
|
||||
| `/volume2/docker/shared/pgdata` | PostgreSQL-Daten (persistent) |
|
||||
| `/volume2/docker/shared/.env` | Secrets: `POSTGRES_PASSWORD` |
|
||||
| `/volume2/docker/shared/docker-compose.yml` | Shared Stack (Postgres + pgAdmin) |
|
||||
| `/volume2/docker/pamietnik/uploads` | Hochgeladene Bilder (persistent) |
|
||||
| `/volume2/docker/pamietnik/.env` | `DB_PASSWORD`, `APP_PORT` |
|
||||
| `/volume2/docker/pamietnik/docker-compose.yml` | Wird via CI/CD aus dem Repo kopiert |
|
||||
| `/volume2/docker/gitea-runner/` | act_runner Konfiguration & Daten |
|
||||
|
||||
---
|
||||
|
||||
## Shared Stack (`/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
|
||||
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Pamietnik Stack (`docker-compose.yml` im Repo-Root)
|
||||
|
||||
```yaml
|
||||
services:
|
||||
api:
|
||||
build:
|
||||
context: .
|
||||
dockerfile: Dockerfile
|
||||
ports:
|
||||
- "${APP_PORT:-9050}:8080"
|
||||
extra_hosts:
|
||||
- "host-gateway:host-gateway"
|
||||
environment:
|
||||
DATABASE_URL: postgres://${DB_USER:-pamietnik}:${DB_PASSWORD:?DB_PASSWORD is required}@host-gateway:5433/${DB_NAME:-pamietnik}?sslmode=disable
|
||||
LISTEN_ADDR: :8080
|
||||
UPLOAD_DIR: /uploads
|
||||
volumes:
|
||||
- /volume2/docker/pamietnik/uploads:/uploads
|
||||
restart: unless-stopped
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## CI/CD: Gitea Actions
|
||||
|
||||
**Workflow:** `.gitea/workflows/deploy.yml` — wird bei Push auf `main` ausgeführt.
|
||||
|
||||
**Runner:** `gitea/act_runner` Container auf der NAS mit `--network host` und Docker-Socket-Mount.
|
||||
|
||||
**Gitea Secrets** (Repository → Einstellungen → Actions → Secrets):
|
||||
- `DB_PASSWORD` — Passwort des `pamietnik` DB-Users
|
||||
- `DEPLOY_DIR` — `/volume2/docker/pamietnik`
|
||||
|
||||
**Gitea Variables** (Repository → Einstellungen → Actions → Variables):
|
||||
- `DB_USER` — `pamietnik`
|
||||
- `DB_NAME` — `pamietnik`
|
||||
- `APP_PORT` — `9050`
|
||||
|
||||
---
|
||||
|
||||
## Dienste & URLs
|
||||
|
||||
| Dienst | URL |
|
||||
|--------|-----|
|
||||
| Pamietnik | `http://<NAS-IP>:9050` |
|
||||
| Gitea | `http://<NAS-IP>:3000` |
|
||||
| PostgreSQL | `<NAS-IP>:5433` |
|
||||
|
||||
---
|
||||
|
||||
## Wichtige Befehle
|
||||
|
||||
```bash
|
||||
# Shared Stack starten
|
||||
cd /volume2/docker/shared && sudo docker compose up -d
|
||||
|
||||
# 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
|
||||
|
||||
# Datenbank-User anlegen
|
||||
sudo docker exec -it shared-postgres-1 psql -U postgres
|
||||
|
||||
# Backup
|
||||
sudo docker exec shared-postgres-1 pg_dump -U postgres pamietnik \
|
||||
> /volume2/docker/shared/backup_$(date +%Y%m%d).sql
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Synology-spezifische Hinweise
|
||||
|
||||
- Docker-Befehle erfordern `sudo`
|
||||
- Ports unter 1024 können Container nicht binden → `PGADMIN_LISTEN_PORT: 8080` nötig
|
||||
- pgAdmin-Verzeichnis braucht UID 5050: `sudo chown -R 5050:5050 /volume2/docker/shared/pgadmin`
|
||||
- Docker-Socket ist unter `/var/run/docker.sock` erreichbar
|
||||
- Container Manager UI unterstützt keinen Datei-Mount für den Docker-Socket → `docker run` via SSH nutzen
|
||||
|
||||
---
|
||||
|
||||
## Vollständige Setup-Anleitung
|
||||
|
||||
Siehe `infra/README.md` im Repo.
|
||||
165
infra/README.md
Normal file
165
infra/README.md
Normal file
@@ -0,0 +1,165 @@
|
||||
# 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
|
||||
```
|
||||
|
||||
### docker-compose.yml kopieren
|
||||
|
||||
```bash
|
||||
sudo cp infra/docker-compose.yml /volume2/docker/shared/docker-compose.yml
|
||||
```
|
||||
|
||||
### .env anlegen
|
||||
|
||||
Datei `/volume2/docker/shared/.env`:
|
||||
|
||||
```env
|
||||
POSTGRES_PASSWORD=<sicheres-passwort>
|
||||
```
|
||||
|
||||
### 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=<passwort-von-oben>
|
||||
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=<token-aus-gitea> \
|
||||
-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://<NAS-IP>:9050` |
|
||||
| PostgreSQL | `psql -h <NAS-IP> -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
|
||||
```
|
||||
16
infra/docker-compose.yml
Normal file
16
infra/docker-compose.yml
Normal file
@@ -0,0 +1,16 @@
|
||||
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
|
||||
Reference in New Issue
Block a user