feat(monitor/infra): three compose files, Makefile, .env.example

This commit is contained in:
CarterPerez-dev 2026-05-01 06:17:28 -04:00
parent a03c060b9f
commit e46728bd80
5 changed files with 413 additions and 0 deletions

View File

@ -0,0 +1,28 @@
# ©AngelaMos | 2026
# .env.example
APP_NAME=monitor
PUBLIC_URL=http://localhost:8430
NGINX_HOST_PORT=8430
BACKEND_HOST_PORT=5430
FRONTEND_HOST_PORT=3430
POSTGRES_HOST_PORT=5431
REDIS_HOST_PORT=6430
POSTGRES_USER=monitor
POSTGRES_PASSWORD=changeme
POSTGRES_DB=monitor
REDIS_PASSWORD=
JWT_SECRET=
NOTIFICATION_ENCRYPTION_KEY=
NVD_API_KEY=
CF_RADAR_TOKEN=
GREYNOISE_API_KEY=
CLOUDFLARE_TUNNEL_TOKEN=
VITE_API_URL=/api

View File

@ -0,0 +1,107 @@
# ©AngelaMos | 2026
# Makefile
.DEFAULT_GOAL := help
SHELL := /bin/bash
COMPOSE_PROD := docker compose -f compose.yml
COMPOSE_DEV := docker compose -f dev.compose.yml
COMPOSE_TUN := docker compose -f compose.yml -f cloudflared.compose.yml
.PHONY: help up up-dev up-tunnel down down-dev logs logs-dev ps ps-dev migrate migrate-dev psql redis-cli backend-shell frontend-shell tidy fmt test build-prod stop clean
help:
@echo 'Monitor the Situation — Make targets:'
@echo ''
@echo ' Production:'
@echo ' up start production stack (no tunnel)'
@echo ' up-tunnel start production stack + cloudflared'
@echo ' down stop production stack'
@echo ' logs tail production logs'
@echo ' ps status of production services'
@echo ''
@echo ' Development:'
@echo ' up-dev start dev stack (vite + air)'
@echo ' down-dev stop dev stack'
@echo ' logs-dev tail dev logs'
@echo ' ps-dev status of dev services'
@echo ''
@echo ' Database:'
@echo ' migrate run goose migrations against prod db'
@echo ' migrate-dev run goose migrations against dev db'
@echo ' psql psql shell into dev db'
@echo ' redis-cli redis-cli shell into dev redis'
@echo ''
@echo ' Backend:'
@echo ' backend-shell shell into the dev backend container'
@echo ' test run all backend tests with -race'
@echo ' fmt format Go code'
@echo ' tidy go mod tidy'
@echo ''
@echo ' Frontend:'
@echo ' frontend-shell shell into the dev frontend container'
@echo ''
up:
$(COMPOSE_PROD) up -d --build
up-tunnel:
$(COMPOSE_TUN) up -d --build
up-dev:
$(COMPOSE_DEV) up -d --build
down:
$(COMPOSE_PROD) down
down-dev:
$(COMPOSE_DEV) down
logs:
$(COMPOSE_PROD) logs -f --tail=200
logs-dev:
$(COMPOSE_DEV) logs -f --tail=200
ps:
$(COMPOSE_PROD) ps
ps-dev:
$(COMPOSE_DEV) ps
migrate:
$(COMPOSE_PROD) exec backend sh -c 'goose -dir /migrations postgres "$$DATABASE_URL" up'
migrate-dev:
$(COMPOSE_DEV) exec backend sh -c 'cd /app && goose -dir migrations postgres "$$DATABASE_URL" up'
psql:
$(COMPOSE_DEV) exec postgres psql -U $${POSTGRES_USER:-monitor} -d $${POSTGRES_DB:-monitor}
redis-cli:
$(COMPOSE_DEV) exec redis redis-cli
backend-shell:
$(COMPOSE_DEV) exec backend sh
frontend-shell:
$(COMPOSE_DEV) exec frontend sh
test:
cd backend && go test -race -count=1 ./...
fmt:
cd backend && gofumpt -w . && goimports -w .
tidy:
cd backend && go mod tidy
build-prod:
$(COMPOSE_PROD) build
stop:
$(COMPOSE_DEV) stop ; $(COMPOSE_PROD) stop
clean: stop
$(COMPOSE_DEV) down -v
$(COMPOSE_PROD) down -v

View File

@ -0,0 +1,22 @@
# ©AngelaMos | 2026
# cloudflared.compose.yml
services:
cloudflared:
image: cloudflare/cloudflared:latest
container_name: ${APP_NAME:-monitor}-tunnel
command: tunnel run --token ${CLOUDFLARE_TUNNEL_TOKEN}
networks:
- backend
depends_on:
nginx:
condition: service_started
deploy:
resources:
limits:
cpus: '0.5'
memory: 128M
reservations:
cpus: '0.1'
memory: 32M
restart: unless-stopped

View File

@ -0,0 +1,130 @@
# ©AngelaMos | 2026
# compose.yml
name: ${APP_NAME:-monitor}
services:
nginx:
build:
context: .
dockerfile: conf/docker/prod/vite.docker
container_name: ${APP_NAME:-monitor}-nginx
ports:
- "${NGINX_HOST_PORT:-8430}:80"
depends_on:
backend:
condition: service_healthy
networks:
- frontend
- backend
deploy:
resources:
limits:
cpus: '1.0'
memory: 256M
reservations:
cpus: '0.25'
memory: 64M
restart: unless-stopped
backend:
build:
context: .
dockerfile: conf/docker/prod/go.docker
container_name: ${APP_NAME:-monitor}-backend
expose:
- "8080"
env_file:
- .env
environment:
- APP_ENVIRONMENT=production
- DATABASE_URL=postgres://${POSTGRES_USER:-monitor}:${POSTGRES_PASSWORD}@postgres:5432/${POSTGRES_DB:-monitor}?sslmode=disable
- REDIS_URL=redis://:${REDIS_PASSWORD}@redis:6379/0
depends_on:
postgres:
condition: service_healthy
redis:
condition: service_healthy
networks:
- backend
deploy:
resources:
limits:
cpus: '2.0'
memory: 1G
reservations:
cpus: '0.5'
memory: 256M
healthcheck:
test: ["CMD", "/app", "-healthcheck"]
interval: 30s
timeout: 5s
retries: 3
start_period: 30s
restart: unless-stopped
postgres:
image: postgres:17-alpine
container_name: ${APP_NAME:-monitor}-postgres
environment:
POSTGRES_USER: ${POSTGRES_USER:-monitor}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
POSTGRES_DB: ${POSTGRES_DB:-monitor}
volumes:
- pgdata:/var/lib/postgresql/data
networks:
- backend
deploy:
resources:
limits:
cpus: '1.0'
memory: 512M
reservations:
cpus: '0.25'
memory: 128M
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-monitor} -d ${POSTGRES_DB:-monitor}"]
interval: 10s
timeout: 5s
retries: 5
start_period: 30s
restart: unless-stopped
redis:
image: redis:7-alpine
container_name: ${APP_NAME:-monitor}-redis
command: redis-server --appendonly yes ${REDIS_PASSWORD:+--requirepass ${REDIS_PASSWORD}}
volumes:
- redisdata:/data
networks:
- backend
deploy:
resources:
limits:
cpus: '0.5'
memory: 256M
reservations:
cpus: '0.1'
memory: 64M
healthcheck:
test: ["CMD-SHELL", "redis-cli ${REDIS_PASSWORD:+-a ${REDIS_PASSWORD}} ping | grep PONG"]
interval: 10s
timeout: 5s
retries: 5
restart: unless-stopped
networks:
frontend:
driver: bridge
ipam:
config:
- subnet: 10.203.83.0/24
backend:
driver: bridge
ipam:
config:
- subnet: 10.203.84.0/24
volumes:
pgdata:
redisdata:

View File

@ -0,0 +1,126 @@
# ©AngelaMos | 2026
# dev.compose.yml
name: ${APP_NAME:-monitor}-dev
services:
nginx:
image: nginx:1.27-alpine
container_name: ${APP_NAME:-monitor}-nginx-dev
ports:
- "${NGINX_HOST_PORT:-8430}:80"
volumes:
- ./conf/nginx/nginx.conf:/etc/nginx/nginx.conf:ro
- ./conf/nginx/dev.nginx:/etc/nginx/conf.d/default.conf:ro
depends_on:
backend:
condition: service_healthy
frontend:
condition: service_started
networks:
- frontend
- backend
restart: unless-stopped
backend:
build:
context: .
dockerfile: conf/docker/dev/go.docker
container_name: ${APP_NAME:-monitor}-backend-dev
ports:
- "${BACKEND_HOST_PORT:-5430}:8080"
volumes:
- ./backend:/app
- go-mod-cache:/go/pkg/mod
env_file:
- .env
environment:
- APP_ENVIRONMENT=development
- DATABASE_URL=postgres://${POSTGRES_USER:-monitor}:${POSTGRES_PASSWORD:-monitor}@postgres:5432/${POSTGRES_DB:-monitor}?sslmode=disable
- REDIS_URL=redis://redis:6379/0
depends_on:
postgres:
condition: service_healthy
redis:
condition: service_healthy
networks:
- backend
healthcheck:
test: ["CMD-SHELL", "wget -q -O- http://localhost:8080/api/v1/healthz || exit 1"]
interval: 10s
timeout: 5s
retries: 5
start_period: 30s
restart: unless-stopped
frontend:
build:
context: .
dockerfile: conf/docker/dev/vite.docker
container_name: ${APP_NAME:-monitor}-frontend-dev
ports:
- "${FRONTEND_HOST_PORT:-3430}:5173"
volumes:
- ./frontend:/app
- frontend-node-modules:/app/node_modules
environment:
- VITE_API_URL=${VITE_API_URL:-/api}
networks:
- frontend
restart: unless-stopped
postgres:
image: postgres:17-alpine
container_name: ${APP_NAME:-monitor}-postgres-dev
ports:
- "${POSTGRES_HOST_PORT:-5431}:5432"
environment:
POSTGRES_USER: ${POSTGRES_USER:-monitor}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-monitor}
POSTGRES_DB: ${POSTGRES_DB:-monitor}
volumes:
- pgdata-dev:/var/lib/postgresql/data
networks:
- backend
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-monitor} -d ${POSTGRES_DB:-monitor}"]
interval: 10s
timeout: 5s
retries: 5
start_period: 30s
restart: unless-stopped
redis:
image: redis:7-alpine
container_name: ${APP_NAME:-monitor}-redis-dev
ports:
- "${REDIS_HOST_PORT:-6430}:6379"
command: redis-server --appendonly yes
volumes:
- redisdata-dev:/data
networks:
- backend
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 10s
timeout: 5s
retries: 5
restart: unless-stopped
networks:
frontend:
driver: bridge
ipam:
config:
- subnet: 10.201.71.0/24
backend:
driver: bridge
ipam:
config:
- subnet: 10.201.72.0/24
volumes:
pgdata-dev:
redisdata-dev:
go-mod-cache:
frontend-node-modules: