gohorsejobs/docs/DEVOPS.md
Tiago Yamamoto 11e0deef2a fix: resolve build errors for Coolify deployment
- Frontend: Remove duplicate useState import in applications page
- Backoffice: Install devDependencies during build for nest CLI
- Seeder: Fix healthcheck port to match app port (8080)
- Add Coolify CI/CD workflow for automatic deployment on push to dev
- Update DEVOPS.md with Coolify environment documentation
2026-02-16 08:42:29 -06:00

237 lines
7.1 KiB
Markdown

# DevOps - GoHorseJobs (Development Environment)
Infraestrutura, CI/CD e deploy do projeto GoHorseJobs no servidor `apolo`.
> **Last Updated:** 2026-02-16
> **Servers:** Apolo VPS (Podman), Redbull VPS (Coolify)
> **Tech Stack:** Podman, Systemd (Quadlet), Traefik, PostgreSQL, Coolify
---
## ☁️ Coolify DEV Environment (Redbull)
Ambiente de desenvolvimento no Coolify para deploy automatizado via Git.
### Server Info
| Property | Value |
|----------|-------|
| **Host** | redbull (185.194.141.70) |
| **Coolify URL** | http://185.194.141.70:8000 |
| **API Token** | `~/.ssh/coolify-redbull-token` |
| **SSH Key** | `~/.ssh/civo` |
| **Project UUID** | `gkgksco0ow4kgwo8ow4cgs8c` |
| **Environment** | `dev` |
### Resources Created
| Resource | UUID | Port | Domain |
|----------|------|------|--------|
| Backend: gohorsejobs-backend-dev | `iw4sow8s0kkg4cccsk08gsoo` | 8521 | coolify-dev.gohorsejobs.com |
| Frontend: gohorsejobs-frontend-dev | `ao8g40scws0w4cgo8coc8o40` | 3000 | dev.gohorsejobs.com |
| Backoffice: gohorsejobs-backoffice-dev | `hg48wkw4wggwsswcwc8sooo4` | 3001 | backoffice-dev.gohorsejobs.com |
| Seeder: gohorsejobs-seeder-dev | `q4w48gos8cgssso00o8w8gck` | 8080 | seeder-dev.gohorsejobs.com |
| Database: gohorsejobs-dev | `bgws48os8wgwk08o48wg8k80` | 5432 | Internal only |
### Architecture
```
GitHub (rede5/gohorsejobs.git)
Coolify (Build & Deploy)
├── Backend (Go) → coolify-dev.gohorsejobs.com:8521
└── PostgreSQL → Internal network only
```
### Environment Variables
Configured via Coolify UI or API:
```bash
DATABASE_URL=postgres://gohorsejobs:gohorsejobs123@bgws48os8wgwk08o48wg8k80:5432/gohorsejobs?sslmode=disable
BACKEND_PORT=8521
ENV=development
JWT_SECRET=<configured>
JWT_EXPIRATION=7d
PASSWORD_PEPPER=<configured>
COOKIE_SECRET=<configured>
COOKIE_DOMAIN=.gohorsejobs.com
CORS_ORIGINS=http://coolify-dev.gohorsejobs.com,https://coolify-dev.gohorsejobs.com
```
### Deploy via API
```bash
# Deploy application
curl -H "Authorization: Bearer $(cat ~/.ssh/coolify-redbull-token)" \
"http://185.194.141.70:8000/api/v1/deploy?uuid=iw4sow8s0kkg4cccsk08gsoo"
# Check deployment status
curl -H "Authorization: Bearer $(cat ~/.ssh/coolify-redbull-token)" \
"http://185.194.141.70:8000/api/v1/deployments/<deployment_uuid>"
# List applications
curl -H "Authorization: Bearer $(cat ~/.ssh/coolify-redbull-token)" \
"http://185.194.141.70:8000/api/v1/applications"
# List databases
curl -H "Authorization: Bearer $(cat ~/.ssh/coolify-redbull-token)" \
"http://185.194.141.70:8000/api/v1/databases"
```
### Coolify Reference
- **Docs:** https://coolify.io/docs/get-started/introduction
- **API Reference:** https://coolify.io/docs/api-reference/authorization
- **GitHub Integration:** Uses SSH deploy key for private repo access
---
## 🏗️ Architecture Diagram
Simplified view of the container hierarchy, networking, and storage.
```mermaid
graph TD
subgraph Host ["Apolo VPS (Host)"]
subgraph FS ["File System (/mnt/data)"]
EnvBE["/gohorsejobs/backend/.env"]
EnvBO["/gohorsejobs/backoffice/.env"]
EnvSE["/gohorsejobs/seeder-api/.env"]
DBData[("postgres-general")]
end
subgraph Net ["Network: web_proxy"]
Traefik("Traefik")
subgraph App ["Application Containers"]
BE["Backend API (:8521)"]
BO["Backoffice (:3001)"]
SE["Seeder API (:8080)"]
FE["Frontend (:3000)"]
end
PG[("postgres-main (:5432)")]
end
end
%% Ingress
Internet((Internet)) --> Traefik
%% Routing
Traefik -- "dev.gohorsejobs.com" --> FE
Traefik -- "api-tmp.gohorsejobs.com" --> BE
Traefik -- "b-tmp.gohorsejobs.com" --> BO
Traefik -- "seeder.gohorsejobs.com" --> SE
%% Config Mounts
EnvBE -.-> BE
EnvBO -.-> BO
EnvSE -.-> SE
%% Data Persistence
PG -.-> DBData
%% Database Connections
BE --> PG
BO --> PG
SE --> PG
style PG fill:#336791,stroke:#fff,color:#fff
style Traefik fill:#f5a623,stroke:#fff,color:#fff
```
---
## 💾 Storage & Persistence (`/mnt/data`)
All persistent data and configuration files are stored in `/mnt/data` on the host.
| Host Path | Container Path | Purpose | Type |
|-----------|----------------|---------|------|
| `/mnt/data/gohorsejobs/backend/.env` | (Injected Env) | **Backend Config:** Secrets, DB URL, Port settings. | File |
| `/mnt/data/gohorsejobs/backoffice/.env` | (Injected Env) | **Backoffice Config:** Secrets, DB URL. | File |
| `/mnt/data/gohorsejobs/seeder-api/.env` | (Injected Env) | **Seeder Config:** Secrets, DB URL. | File |
| `/mnt/data/postgres-general` | `/var/lib/postgresql/data` | **Database Storage:** Main storage for `postgres-main` container. Contains `gohorsejobs_dev` DB. | Directory |
> **Backup Note:** To backup the environment, ensure `/mnt/data/gohorsejobs` and `/mnt/data/postgres-general` are included in snapshots.
---
## 🌍 Service Maps & Networking
### 🚦 Traefik Routing
Services are exposed via Traefik labels defined in the Quadlet `.container` files.
| Domain | Service | Internal Port | Host Port (Debug) |
|--------|---------|---------------|-------------------|
| `dev.gohorsejobs.com` | `gohorsejobs-frontend-dev` | `3000` | `8523` |
| `api-tmp.gohorsejobs.com` | `gohorsejobs-backend-dev` | `8521` | `8521` |
| `b-tmp.gohorsejobs.com` | `gohorsejobs-backoffice-dev` | `3001` | - |
| `seeder.gohorsejobs.com` | `gohorsejobs-seeder-dev` | `8080` | `8522` |
### 🛑 Security
- **Backend/Seeder/Frontend** expose ports to the Host (`85xx`) for debugging/direct access if needed.
- **Backoffice** is *only* accessible via Traefik (internal network).
- **PostgreSQL** is *only* accessible internally via `web_proxy` network (no host port binding).
---
## 🛠️ Operational Guide
### 1. View & Manage Configs
Configurations are **not** inside containers. Edit them on the host:
```bash
# Edit Backend Config
vim /mnt/data/gohorsejobs/backend/.env
# Apply changes
systemctl restart gohorsejobs-backend-dev
```
### 2. Full Environment Restart
To restart all GoHorseJobs related services (excluding Database):
```bash
systemctl restart gohorsejobs-backend-dev gohorsejobs-backoffice-dev gohorsejobs-seeder-dev gohorsejobs-frontend-dev
```
### 3. Database Access
Access the local database directly via the `postgres-main` container:
```bash
# Internal Connection
docker exec -it postgres-main psql -U yuki -d gohorsejobs_dev
```
---
## 🚀 Deployment Pipeline (Manual)
Current workflow uses **Local Build** -> **Forgejo Registry** -> **Server Pull**.
### 1. Build & Push (Local Machine)
```bash
# Login
podman login forgejo-gru.rede5.com.br
# Build
cd backend
podman build -t forgejo-gru.rede5.com.br/rede5/gohorsejobs-backend:latest .
# Push
podman push forgejo-gru.rede5.com.br/rede5/gohorsejobs-backend:latest
```
### 2. Deploy (On Apolo Server)
```bash
ssh root@apolo
# Pull new image
podman pull forgejo-gru.rede5.com.br/rede5/gohorsejobs-backend:latest
# Restart service (Systemd handles container recreation)
systemctl restart gohorsejobs-backend-dev
```