--- title: Infrastructure tags: [architecture, infrastructure, docker, devops] created: 2026-05-23 --- # Infrastructure How the system is packaged, deployed and run in production. Read alongside [[Docker Setup]] (operations runbook) and [[CI-CD Pipeline]]. --- ## 1. Runtime topology ```mermaid flowchart LR DNS[DNS amn.gg] --> CF[CloudFlare / Edge SSL] CF --> Nginx subgraph Host[Single Docker host] Nginx[nginx:alpine
nickapp-nginx
:8083] FE[nickapp-frontend:latest
Next.js standalone
:8083] BE[nickapp-backend:latest
Express + Socket.IO
:5001] Mongo[(mongo:8.0
mongodb_data volume)] Redis[(redis:8-alpine
redis_data volume)] Up[/uploads volume/] end Nginx --> FE Nginx --> BE BE --> Mongo BE --> Redis BE --- Up FE --- Up Watchtower>Watchtower
auto-update] -.-> BE Watchtower -.-> FE ``` > [!info] > Single-host today. Horizontal scaling requires Redis pub/sub adapter for Socket.IO and externalizing the `uploads/` volume (S3 / R2). --- ## 2. Docker images | Image | Source Dockerfile | Stages | Final size target | User | |---|---|---|---|---| | `nickapp-backend:latest` | `backend/Dockerfile.prod` | builder + runner | ~200 MB | `marketplace` (uid 1001) | | `nickapp-backend:dev` | `backend/Dockerfile.dev` | single | ~400 MB | `marketplace` (uid 1001) | | `nickapp-frontend:latest` | `frontend/Dockerfile` | builder + runner | ~250 MB | `nextjs` (uid 1001) | | `nickapp-frontend:dev` | `frontend/Dockerfile.dev` | single | ~600 MB | root | All built on `node:22-alpine`. Backend images include Python+make+g++ in the builder stage for native deps (bcrypt). Frontend runner only ships the `.next/standalone` output + `public/`. --- ## 3. Compose stacks ### 3.1 `docker-compose.dev.yml` (backend repo) Used by developers running `npm run docker:dev`. Three services: | Service | Image | Ports | Volumes | Depends on | |---|---|---|---|---| | `nickdev-backend` | built from `Dockerfile.dev` | `5001:5001` | `./src:/app/src`, `./uploads:/app/uploads` | mongodb, redis | | `nickdev-mongodb` | `mongo:8.0` | `27017:27017` | `mongodb_data:/data/db` | — | | `nickdev-redis` | `redis:8-alpine` | (internal) | `redis_data:/data` | — | Network: `nickapp-network` (bridge). Env: `.env.local`. Frontend dev runs OUTSIDE compose — developer launches `yarn dev` on host so React Fast Refresh works. ### 3.2 `docker-compose.production.yml` (backend repo) Used in production. Five services: | Service | Image | Ports | Healthcheck | Watchtower | |---|---|---|---|---| | `nickapp-nginx` | `nginx:alpine` | `8083:80` | implicit | — | | `nickapp-backend` | `nickapp-backend:latest` (pulled) | 5001 internal | `node healthcheck.js` 30s | ✓ | | `nickapp-frontend` | `nickapp-frontend:latest` (pulled) | 8083 internal | `curl http://localhost:8083` 30s | ✓ | | `nickapp-mongodb` | `mongo:8.0` | internal | `mongosh ping` 30s | — | | `nickapp-redis` | `redis:8-alpine` (with `--requirepass`) | internal | `redis-cli ping` 30s | — | Volumes: `mongodb_data`, `redis_data`, `./uploads`, `./nginx/nginx.conf`, `./nginx/logs`. Env: single root `.env`. > [!warning] > `REDIS_PASSWORD` MUST be set in the production `.env` before starting — otherwise the Redis container fails its healthcheck and dependents won't start. --- ## 4. Nginx configuration The Nginx proxy at `./nginx/nginx.conf` (mounted read-only) is responsible for: - Terminating internal HTTP (SSL handled by an external edge — CloudFlare / nginx-proxy / Caddy) - Routing `/api/*` and `/socket.io/*` to `nickapp-backend:5001` - Routing everything else to `nickapp-frontend:8083` - Serving `/uploads/*` directly from the shared volume (bypasses the Node process) - Standard gzip / compression / client_max_body_size (≥10 MB to match backend body limit) > [!tip] > Put the Nginx access log path on a tmpfs or rotate it aggressively — the container exposes `./nginx/logs` so the host can manage retention. --- ## 5. Watchtower (auto-update) Both `nickapp-backend` and `nickapp-frontend` carry the `watchtower.enable=true` label. Watchtower polls the container registry on its configured interval and re-pulls when the `latest` tag moves. Release cycle: 1. Developer pushes commits to a feature branch → merged into `development`. 2. Manual Gitea workflow `docker-build-simple.yml` builds & pushes `nickapp-backend:latest` (and a versioned tag) to `git.manko.yoga/manawenuz/escrow-backend`. 3. Within the next poll interval (default 5 min) Watchtower restarts the affected service. > [!warning] > Because Watchtower restarts only on tag change, sequential pushes are safe — but a broken build pushed to `latest` will roll out automatically. Keep `dev` and `production` tags separated, or pin production to a versioned tag. --- ## 6. Persistent storage | Volume | What it stores | Backup priority | |---|---|---| | `mongodb_data` | All business data (users, requests, payments, chats, disputes...) | **Critical** — daily dump | | `redis_data` | Cache, session, rate counters | Low — losing it logs everyone out but no data loss | | `./uploads` (host bind) | Avatars, product images, dispute evidence, documents | **High** — daily rsync | | `./nginx/logs` | Access / error logs | Medium | See [[Backup & Recovery]] for the runbook. --- ## 7. CI / CD Located at `backend/.gitea/workflows/`: | Workflow | Trigger | Output | |---|---|---| | `docker-build-simple.yml` | manual | Build → push backend image to registry (`latest` + version) | | `docker-build-dev.yml` | manual | Dev image variant | | `docker-build-no-cache.yml` | manual | Clean build (no GH-Actions cache) | Frontend at `frontend/.gitea/workflows/`: | Workflow | Trigger | Output | |---|---|---| | `deploy.yml` | push to `main`/`master`, manual | Runs `scripts/deploy.sh` (deploy via SSH) | | `devDeploy.yml` | manual | Deploy to dev env | Single secret required: `GITEATOKEN` (Gitea PAT with `write:package`). Full breakdown → [[CI-CD Pipeline]]. --- ## 8. Secrets Never committed. Required in production `.env`: - `JWT_SECRET`, `REFRESH_TOKEN_SECRET` - `MONGODB_URI`, `REDIS_PASSWORD` - `SHKEEPER_API_KEY`, `SHKEEPER_WEBHOOK_SECRET` - `SMTP_USER`, `SMTP_PASS` - `OPENAI_API_KEY` - `GOOGLE_CLIENT_ID`, `GOOGLE_CLIENT_SECRET` - `NEXT_PUBLIC_ALCHEMY_API_KEY_*` (frontend public envs — embedded at build) Recommend storing host-side in an `.env` outside the repo, mounted via Compose. For multi-host: Vault / AWS SSM / GCP Secret Manager. --- ## 9. Observability | Signal | Where | |---|---| | App logs | container `stdout` → `docker logs nickapp-backend` | | Access logs | `./nginx/logs` | | Frontend errors | Sentry (`@sentry/nextjs`) | | Backend errors | Sentry (optional — add `@sentry/node`) | | Healthchecks | `GET /health` (backend) · `GET /` (frontend) · `mongosh ping` · `redis-cli ping` | See [[Monitoring]] for the full table of metrics & recommended alerts. --- ## 10. Networking | Direction | Port | Protocol | Notes | |---|---|---|---| | Internet → Nginx | 8083 | HTTP | SSL terminated upstream | | Browser → Backend | 5001 | HTTP + WS | via Nginx `/api`, `/socket.io` | | Backend → MongoDB | 27017 | TCP | Docker network | | Backend → Redis | 6379 | TCP | Docker network | | Backend → Request Network API | 443 | HTTPS | External payment provider | | Backend → SMTP | 587 | TLS | External | | Backend → OpenAI | 443 | HTTPS | External | | Browser → Blockchain RPC | 443 | HTTPS | Alchemy URLs | | Browser → WalletConnect | 443 | HTTPS | Relay server | --- ## 11. Hardening checklist - [ ] Non-root user inside every container (`marketplace` / `nextjs`) ✓ in Dockerfiles - [ ] Read-only Nginx config mount ✓ - [ ] Redis requires password ✓ - [ ] MongoDB has root credentials + bind to internal network only ✓ - [ ] Rate limit enabled before public traffic ⚠ currently disabled - [ ] Refresh tokens rotated on use ⚠ partial - [ ] All public env values reviewed (no `IS_DEVELOPMENT=true` in prod build) ⚠ - [ ] Watchtower scoped to specific repos - [ ] Sentry source-map upload at build time ✓ (frontend) See [[Security Architecture]] for the deeper review. --- ## Related - [[System Architecture]] · [[Backend Architecture]] · [[Frontend Architecture]] - [[Docker Setup]] — operational walk-through with commands - [[CI-CD Pipeline]] — workflow breakdown - [[Deployment]] — first-deploy runbook - [[Backup & Recovery]] · [[Monitoring]] · [[Incident Response]] - [[Environment Variables]] — full env-var catalog