Add DEPLOYMENT.md as living deployment documentation
Covers architecture overview, Gitea container registry setup, branching strategy, and deployment workflow. Sections not yet implemented are marked with TODO to be filled in as the deployment epic progresses. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,11 +1,11 @@
|
||||
---
|
||||
# nuzlocke-tracker-ahza
|
||||
title: Deployment Strategy
|
||||
status: todo
|
||||
status: in-progress
|
||||
type: epic
|
||||
priority: normal
|
||||
created_at: 2026-02-09T14:03:53Z
|
||||
updated_at: 2026-02-09T16:44:13Z
|
||||
updated_at: 2026-02-09T16:53:58Z
|
||||
---
|
||||
|
||||
Define and implement a deployment strategy for running the nuzlocke-tracker in production on a local Unraid server while keeping laptop/PC as the development environment.
|
||||
@@ -51,7 +51,7 @@ Define and implement a deployment strategy for running the nuzlocke-tracker in p
|
||||
- [ ] **Configure Gitea container registry** — create an access token with `read:package` and `write:package` scopes, verify `docker login gitea.yourdomain.com` works, test pushing and pulling an image as a user-level package
|
||||
- [ ] **Create production docker-compose file** (`docker-compose.prod.yml`) — uses images from the Gitea container registry, production env vars, no source volume mounts, proper restart policies
|
||||
- [ ] **Create production Dockerfiles (or multi-stage builds)** — ensure frontend is built and served statically (e.g., via the API or a lightweight nginx container), API runs without debug mode
|
||||
- [ ] **Set up Portainer on Unraid** — install Portainer CE as a Docker container, configure the stack from the production compose file
|
||||
- [x] **Set up Portainer on Unraid** — install Portainer CE as a Docker container, configure the stack from the production compose file
|
||||
- [ ] **Configure Portainer webhook for automated redeployment** — add a webhook trigger in Portainer that pulls latest images and restarts the stack
|
||||
- [ ] **Create deploy script** — a script (e.g., `./deploy.sh`) that builds images from `main`, tags them for the Gitea registry, pushes them, and triggers the Portainer webhook to redeploy
|
||||
- [ ] **Configure Nginx Proxy Manager** — add proxy host entries for Gitea and the nuzlocke-tracker frontend/API on the appropriate ports
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
---
|
||||
# nuzlocke-tracker-hwyk
|
||||
title: Set up Portainer on Unraid
|
||||
status: todo
|
||||
status: completed
|
||||
type: task
|
||||
priority: normal
|
||||
created_at: 2026-02-09T15:30:44Z
|
||||
updated_at: 2026-02-09T15:30:44Z
|
||||
updated_at: 2026-02-09T16:53:41Z
|
||||
parent: nuzlocke-tracker-ahza
|
||||
---
|
||||
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
---
|
||||
# nuzlocke-tracker-re0m
|
||||
title: Document the deployment workflow
|
||||
status: todo
|
||||
status: in-progress
|
||||
type: task
|
||||
priority: normal
|
||||
created_at: 2026-02-09T15:30:57Z
|
||||
updated_at: 2026-02-09T15:31:15Z
|
||||
updated_at: 2026-02-09T16:55:02Z
|
||||
parent: nuzlocke-tracker-ahza
|
||||
blocking:
|
||||
- nuzlocke-tracker-aiw6
|
||||
|
||||
152
DEPLOYMENT.md
Normal file
152
DEPLOYMENT.md
Normal file
@@ -0,0 +1,152 @@
|
||||
# Deployment
|
||||
|
||||
This document describes the deployment architecture and workflows for the nuzlocke-tracker. It is a living document — sections marked with **TODO** are planned but not yet implemented.
|
||||
|
||||
## Architecture Overview
|
||||
|
||||
| Component | Dev (Laptop/PC) | Production (Unraid) |
|
||||
|---|---|---|
|
||||
| API | `docker-compose.yml` (hot reload) | `docker-compose.prod.yml` (built image) |
|
||||
| Frontend | `docker-compose.yml` (Vite dev server) | `docker-compose.prod.yml` (built image) |
|
||||
| Database | PostgreSQL 16 (Docker volume) | PostgreSQL 16 (Docker volume) |
|
||||
| Container Registry | — | Gitea (user-level packages) |
|
||||
| Container Management | — | Portainer CE |
|
||||
| Reverse Proxy | — | Nginx Proxy Manager |
|
||||
|
||||
### Services
|
||||
|
||||
- **Gitea** — self-hosted Git server, container registry, and (future) CI/CD. Accessible at `gitea.nerdboden.de` via SSL.
|
||||
- **Portainer** — Docker management UI. Accessible at `portainer.nerdboden.de` via SSL. Manages the production stack and provides webhook-triggered redeployments.
|
||||
- **Nginx Proxy Manager** — reverse proxy with SSL termination for all services on the Unraid server.
|
||||
|
||||
## Container Registry
|
||||
|
||||
Docker images are hosted on Gitea's built-in container registry as **user-level packages**.
|
||||
|
||||
### Image naming
|
||||
|
||||
Images use the format `gitea.nerdboden.de/<user>/<image>:<tag>`:
|
||||
|
||||
```
|
||||
gitea.nerdboden.de/julian/nuzlocke-tracker-api:latest
|
||||
gitea.nerdboden.de/julian/nuzlocke-tracker-frontend:latest
|
||||
```
|
||||
|
||||
### Authentication
|
||||
|
||||
1. Create a Gitea access token at **Settings > Applications** with `read:package` and `write:package` scopes.
|
||||
2. Log in from the dev machine:
|
||||
```bash
|
||||
docker login gitea.nerdboden.de
|
||||
```
|
||||
Use your Gitea username and the access token as password.
|
||||
|
||||
### Pushing images
|
||||
|
||||
```bash
|
||||
# Build and tag
|
||||
docker build -t gitea.nerdboden.de/julian/nuzlocke-tracker-api:latest ./backend
|
||||
docker build -t gitea.nerdboden.de/julian/nuzlocke-tracker-frontend:latest ./frontend
|
||||
|
||||
# Push
|
||||
docker push gitea.nerdboden.de/julian/nuzlocke-tracker-api:latest
|
||||
docker push gitea.nerdboden.de/julian/nuzlocke-tracker-frontend:latest
|
||||
```
|
||||
|
||||
Pushed images are visible under the **Packages** tab on your Gitea user profile.
|
||||
|
||||
## Branching Strategy
|
||||
|
||||
The project uses a `main` / `develop` / `feature/*` branching model.
|
||||
|
||||
| Branch | Purpose |
|
||||
|---|---|
|
||||
| `main` | Always production-ready. Deploy script builds from here. |
|
||||
| `develop` | Integration branch for day-to-day work. |
|
||||
| `feature/*` | Short-lived branches off `develop` for individual features/fixes. |
|
||||
|
||||
### Workflow
|
||||
|
||||
1. Create `feature/xyz` from `develop`
|
||||
2. Work on the feature, commit, merge into `develop`
|
||||
3. When ready to deploy: merge `develop` into `main`
|
||||
4. Run the deploy script (see below)
|
||||
|
||||
## Deploying
|
||||
|
||||
> **TODO** — deploy script (`./deploy.sh`) not yet created.
|
||||
|
||||
The deploy script will automate:
|
||||
|
||||
1. Build Docker images from `main`
|
||||
2. Tag and push to the Gitea container registry
|
||||
3. Trigger the Portainer webhook to pull new images and restart the stack
|
||||
|
||||
### Manual deployment
|
||||
|
||||
Until the deploy script is in place, deploy manually:
|
||||
|
||||
```bash
|
||||
# 1. Ensure you're on main with latest changes
|
||||
git checkout main
|
||||
|
||||
# 2. Build and push images
|
||||
docker build -t gitea.nerdboden.de/julian/nuzlocke-tracker-api:latest ./backend
|
||||
docker build -t gitea.nerdboden.de/julian/nuzlocke-tracker-frontend:latest ./frontend
|
||||
docker push gitea.nerdboden.de/julian/nuzlocke-tracker-api:latest
|
||||
docker push gitea.nerdboden.de/julian/nuzlocke-tracker-frontend:latest
|
||||
|
||||
# 3. On Unraid (or via Portainer): pull and restart
|
||||
docker compose -f docker-compose.prod.yml pull
|
||||
docker compose -f docker-compose.prod.yml up -d
|
||||
```
|
||||
|
||||
## Production Compose
|
||||
|
||||
> **TODO** — `docker-compose.prod.yml` not yet created.
|
||||
|
||||
The production compose file will differ from the dev compose in:
|
||||
|
||||
- Uses pre-built images from the Gitea registry (no source volume mounts)
|
||||
- No hot reload / debug mode
|
||||
- Production environment variables
|
||||
- Proper restart policies
|
||||
- Frontend served as a static build (not Vite dev server)
|
||||
|
||||
## Portainer
|
||||
|
||||
Portainer CE is running on Unraid at `portainer.nerdboden.de`.
|
||||
|
||||
- Manages the production Docker stack
|
||||
- **TODO**: Configure a webhook for automated redeployment (pull latest images + restart on trigger)
|
||||
|
||||
## Nginx Proxy Manager
|
||||
|
||||
NPM runs on Unraid and handles SSL termination and routing for:
|
||||
|
||||
- `gitea.nerdboden.de` → Gitea
|
||||
- `portainer.nerdboden.de` → Portainer
|
||||
- **TODO**: `nuzlocke.nerdboden.de` (or similar) → nuzlocke-tracker frontend/API
|
||||
|
||||
## Environment & Secrets
|
||||
|
||||
> **TODO** — `.env.prod` template not yet created.
|
||||
|
||||
Production environment variables to configure:
|
||||
|
||||
- `DATABASE_URL` — PostgreSQL connection string
|
||||
- `DEBUG` — must be `false` in production
|
||||
- Additional secrets TBD
|
||||
|
||||
## Database
|
||||
|
||||
PostgreSQL 16 with data stored in a named Docker volume.
|
||||
|
||||
- Migrations run automatically on API container startup (Alembic)
|
||||
- **TODO**: Set up scheduled backups (`pg_dump` cron job on Unraid)
|
||||
|
||||
## Rollback
|
||||
|
||||
> **TODO** — rollback procedure to be documented once image tagging strategy is finalized.
|
||||
|
||||
General approach: tag images with version/commit hash in addition to `latest`, so rolling back means redeploying a previous tag.
|
||||
Reference in New Issue
Block a user