Add Pier deployment configuration (2 services: backend + frontend)

This commit is contained in:
root 2026-07-14 12:23:39 +02:00
parent ef25759eda
commit 71a8b81ace
3 changed files with 203 additions and 0 deletions

53
docker-compose.pier.yml Normal file
View File

@ -0,0 +1,53 @@
# Claim App — Pier Dashboard Container Service
# Project "claim" with 2 services: backend + frontend.
# MongoDB runs as a separate Pier database service named "claim-mongo"
# and is reachable at hostname "pier-claim-mongo" on pier-net.
#
# Auto-deploy: Pier clones this repo and builds from these Dockerfiles.
services:
backend:
build:
context: .
dockerfile: backend/Dockerfile
image: claim-backend:{{BUILD_TAG}}
container_name: pier-claim-backend
restart: unless-stopped
working_dir: /app/backend
command: ["python", "-m", "uvicorn", "server:app", "--host", "0.0.0.0", "--port", "8002"]
env_file: .env
environment:
MONGO_URL: mongodb://pier-claim-mongo:27017
DB_NAME: claim
PORT: "8002"
FRONTEND_URL: ""
CORS_ORIGINS: ""
volumes:
- "claim_uploads:/app/backend/claim_files"
- "claim_attach:/app/backend/claim_attachments"
networks:
pier-net:
aliases:
- backend
depends_on: []
frontend:
build:
context: .
dockerfile: frontend/Dockerfile
image: claim-frontend:{{BUILD_TAG}}
container_name: pier-claim-frontend
restart: unless-stopped
ports:
- "127.0.0.1:8082:80"
networks:
- pier-net
depends_on:
- backend
volumes:
claim_uploads:
claim_attach:
networks:
pier-net:
external: true

147
docs/deploy/pier.md Normal file
View File

@ -0,0 +1,147 @@
# Pier Deployment — Claim App
## Architecture
```
Cloudflare (gray DNS)
claim.skysyaz.my
┌──────┴──────┐
│ Traefik │ (Pier-managed, auto HTTPS)
│ (port 443) │
└──────┬──────┘
pier-net│
┌─────────────┴─────────────┐
│ │
┌────────┴────────┐ ┌──────────┴──────────┐
│ pier-claim- │ │ pier-claim- │
│ frontend │ │ backend │
│ :80 │ │ :8002 │
│ nginx proxy │──────►│ FastAPI │
│ /api → backend │ │ (alias: backend) │
└─────────────────┘ └──────────┬──────────┘
│ mongodb://pier-claim-mongo:27017
┌────────┴────────┐
│ pier-claim- │
│ mongo │
│ MongoDB 7 │
└─────────────────┘
```
## Services
### 1. MongoDB (standalone database service)
- **Image:** `mongo:7`
- **Container:** `pier-claim-mongo`
- **Network:** `pier-net` (alias: `mongo`)
- **Data:** `claim_mongo_data` volume
- **Health:** `mongosh` ping every 10s
- **Pier stack:** `/opt/pier/data/stacks/pier-claim-mongo/`
### 2. Backend (FastAPI)
- **Build:** `backend/Dockerfile` (Python 3.11-slim, LibreOffice Calc)
- **Image:** `claim-backend:latest`
- **Container:** `pier-claim-backend`
- **Network:** `pier-net` (alias: `backend`)
- **Port:** 8002 (internal only)
- **Env:** `MONGO_URL`, `DB_NAME`, `JWT_SECRET`, `ADMIN_*`
- **Pier stack:** `/opt/pier/data/stacks/pier-claim-backend/`
### 3. Frontend (React + Nginx)
- **Build:** `frontend/Dockerfile` (Bun build, Nginx serve)
- **Image:** `claim-frontend:latest`
- **Container:** `pier-claim-frontend`
- **Network:** `pier-net`
- **Port:** `127.0.0.1:8082:80`
- **Domain:** `claim.skysyaz.my` → HTTPS via Traefik/LetsEncrypt
- **Nginx:** proxies `/api` and `/uploads` to `backend:8002`
- **Pier stack:** `/opt/pier/data/stacks/pier-claim-frontend/`
## Pier Configuration
### Project
- **Name:** `claim`
- **ID:** `a68caf79-c700-4f31-854b-3745ccf2935a`
- **Services:** `backend` + `frontend` (2 separate Pier service entries)
### Git auto-deploy
- **Repo:** `https://github.com/skysyaz/claim.git` (mirrored to Gitea)
- **Branch:** `main`
- **Strategy:** `dockerfile` (Pier builds from each Dockerfile)
- **Trigger:** Any push to `main` auto-deploys both services
### Domain (Pier DB - `domains` table)
```
claim.skysyaz.my → frontend service → pier-claim-frontend:80
SSL: LetsEncrypt (auto-provisioned by Traefik when DNS resolves)
```
## Deployment Procedure
### Initial deploy (first time)
```bash
# 1. Build images
docker build -t claim-backend:latest \
-f backend/Dockerfile .
docker build -t claim-frontend:latest \
-f frontend/Dockerfile .
# 2. Start MongoDB (if not running)
docker compose -f /opt/pier/data/stacks/pier-claim-mongo/docker-compose.yml up -d
# 3. Start backend & frontend
docker compose -f /opt/pier/data/stacks/pier-claim-backend/docker-compose.yml up -d
docker compose -f /opt/pier/data/stacks/pier-claim-frontend/docker-compose.yml up -d
```
### Update via git push
```bash
# 1. Make changes and commit
git add -A
git commit -m "description of changes"
git push origin main
# 2. Pier auto-deploys:
# - GitHub webhook → Gitea mirror sync → Pier detects change
# - Pier clones repo, builds both Dockerfiles, redeploys
# - Zero-downtime if configured
```
### Manual redeploy
```bash
# Rebuild and restart a single service
docker compose -f /opt/pier/data/stacks/pier-claim-backend/docker-compose.yml up -d --build
```
## DNS Setup (Cloudflare)
| Record | Type | Value | Proxy |
|--------|------|-------|-------|
| `claim` | `A` | `194.233.86.248` | Gray (DNS only) |
| OR | | |
| `claim` | `CNAME` | `194.233.86.248.sslip.io` | Gray (DNS only) |
> Use **gray cloud** (DNS only, not proxied) so Let's Encrypt can validate the domain via HTTP-01 challenge.
## Monitoring
- **Health endpoint:** `https://claim.skysyaz.my/api/health`
- **Pier dashboard:** `https://pier.skysyaz.my:8443`
- **Container logs:** `docker logs pier-claim-backend`
- **Traefik metrics:** Built into Pier dashboard
## File Reference
| File | Purpose |
|------|---------|
| `pier.yml` | Pier project metadata (repo root) |
| `docker-compose.pier.yml` | Pier compose stack template |
| `backend/Dockerfile` | Backend container image |
| `frontend/Dockerfile` | Frontend container image |
| `frontend/nginx.conf` | Nginx config (proxy `/api` to backend) |
| `backend/.env` | Runtime environment variables |

3
pier.yml Normal file
View File

@ -0,0 +1,3 @@
project: claim
compose_file: docker-compose.pier.yml
description: Employee claims management — FastAPI backend + React frontend + MongoDB