diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..e7aebc4 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,9 @@ +krafttrainer +krafttrainer.db +krafttrainer.db-shm +krafttrainer.db-wal +frontend/node_modules/ +frontend/dist/ +backend/static/assets/ +.git/ +.claude/ diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..e690136 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,31 @@ +# Stage 1: Frontend bauen +FROM node:22-slim AS frontend-builder +WORKDIR /app/frontend +RUN corepack enable +COPY frontend/package.json frontend/pnpm-lock.yaml ./ +RUN pnpm install --frozen-lockfile +COPY frontend/ ./ +RUN pnpm build + +# Stage 2: Go-Binary bauen (CGO nötig für go-sqlite3) +FROM golang:1.24-bookworm AS go-builder +WORKDIR /app +COPY backend/go.mod backend/go.sum ./ +RUN go mod download +COPY backend/ ./ +# Frontend-Build in static/ einhängen (wird per embed eingebettet) +COPY --from=frontend-builder /app/frontend/dist/ ./static/ +RUN CGO_ENABLED=1 go build -ldflags="-s -w" -o krafttrainer ./cmd/server + +# Stage 3: Minimales Runtime-Image +FROM debian:bookworm-slim +RUN apt-get update \ + && apt-get install -y --no-install-recommends ca-certificates \ + && rm -rf /var/lib/apt/lists/* + +# DB landet im Volume /data (hardcodierter Pfad "krafttrainer.db" → WORKDIR) +WORKDIR /data +COPY --from=go-builder /app/krafttrainer /usr/local/bin/krafttrainer + +EXPOSE 8090 +CMD ["krafttrainer"] diff --git a/backend/server b/backend/server new file mode 100755 index 0000000..e30d47d Binary files /dev/null and b/backend/server differ diff --git a/deployment.md b/deployment.md new file mode 100644 index 0000000..f809133 --- /dev/null +++ b/deployment.md @@ -0,0 +1,72 @@ +# Deployment + +## Voraussetzungen + +- Docker + Docker Compose auf dem Zielrechner +- Quellcode (git clone) + +## Starten + +```bash +docker compose up --build -d +``` + +Beim ersten Start: +- Docker baut das Image (Frontend + Go-Binary, dauert ~2 Min.) +- Migrations laufen automatisch beim Start +- Server lauscht auf Port `8090` + +## Nach Code-Änderungen + +```bash +docker compose up --build -d +``` + +Docker-Layer-Cache beschleunigt den Rebuild: +- `go.mod` unverändert → `go mod download` wird nicht wiederholt +- `pnpm-lock.yaml` unverändert → `pnpm install` wird nicht wiederholt + +## Logs + +```bash +docker compose logs -f +``` + +## Stoppen + +```bash +docker compose down # Container stoppen (DB bleibt erhalten) +docker compose down -v # Container + DB-Volume löschen (Datenverlust!) +``` + +## Datenbank + +Die SQLite-DB liegt im Docker-Volume `db-data` → `/data/krafttrainer.db` im Container. + +**Backup:** +```bash +docker run --rm -v krafttrainer_db-data:/data -v $(pwd):/backup \ + debian:bookworm-slim cp /data/krafttrainer.db /backup/krafttrainer.db.bak +``` + +**Restore:** +```bash +docker compose down +docker run --rm -v krafttrainer_db-data:/data -v $(pwd):/backup \ + debian:bookworm-slim cp /backup/krafttrainer.db.bak /data/krafttrainer.db +docker compose up -d +``` + +## Image-Aufbau (3-Stage-Build) + +| Stage | Basis | Aufgabe | +|-------|-------|---------| +| 1 | `node:22-slim` | `pnpm build` → `frontend/dist/` | +| 2 | `golang:1.24-bookworm` | Frontend einbetten + `go build` (CGO für SQLite) | +| 3 | `debian:bookworm-slim` | Nur Binary + glibc, ~100MB finales Image | + +## Ports + +| Port | Dienst | +|------|--------| +| `8090` | HTTP-Server (API + Frontend) | diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..01cfa31 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,11 @@ +services: + krafttrainer: + build: . + ports: + - "8090:8090" + volumes: + - db-data:/data + restart: unless-stopped + +volumes: + db-data: