Update epic checklist, mark completed tasks, fix Gitea username/domain references, and update DEPLOYMENT.md with correct registry paths. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
153 lines
5.0 KiB
Markdown
153 lines
5.0 KiB
Markdown
# 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/thefurya/nuzlocke-tracker-api:latest
|
|
gitea.nerdboden.de/thefurya/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/thefurya/nuzlocke-tracker-api:latest ./backend
|
|
docker build -t gitea.nerdboden.de/thefurya/nuzlocke-tracker-frontend:latest ./frontend
|
|
|
|
# Push
|
|
docker push gitea.nerdboden.de/thefurya/nuzlocke-tracker-api:latest
|
|
docker push gitea.nerdboden.de/thefurya/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/thefurya/nuzlocke-tracker-api:latest ./backend
|
|
docker build -t gitea.nerdboden.de/thefurya/nuzlocke-tracker-frontend:latest ./frontend
|
|
docker push gitea.nerdboden.de/thefurya/nuzlocke-tracker-api:latest
|
|
docker push gitea.nerdboden.de/thefurya/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.
|