normogen/docs/deployment/DEPLOYMENT_GUIDE.md
goose fff1ed2e6d
Some checks failed
Lint and Build / format (pull_request) Successful in 1m44s
Lint and Build / clippy (pull_request) Successful in 1m48s
Lint and Build / build (pull_request) Successful in 6m40s
Lint and Build / test (pull_request) Failing after 1s
fix(backend): P2 config & Docker consistency
Resolve the operational/config sprawl (#10-#14 from the review): the app read
NORMOGEN_*/MONGODB_* env vars but every env/compose file set SERVER_*/DATABASE_*,
the ports were all over the place (8080/8000/6500/6800), there were 5
inconsistent Dockerfiles (rust:1.82 vs rust:1.93, missing curl), and an 18 MB
binary was committed.

Env-var names — standardize on what the code reads:
* config/mod.rs: NORMOGEN_PORT default 8080 -> 6500 (avoid the over-common
  8000/8080).
* db/mod.rs: create_database() now reads MONGODB_DATABASE (was DATABASE_NAME).
* .env.example, defaults.env, docker-compose.yml, docker-compose.dev.yml,
  DEPLOYMENT_GUIDE.md, deployment/README.md, deploy-and-test-solaria.sh,
  deploy-local-build.sh: use NORMOGEN_HOST/NORMOGEN_PORT/MONGODB_URI/
  MONGODB_DATABASE/APP_ENVIRONMENT; drop the dead SERVER_*/DATABASE_URI/
  DATABASE_NAME names.

Ports — canonical container port 6500 everywhere:
* Both Dockerfiles EXPOSE 6500; prod compose maps 6500:6500, dev 6501:6500.
* Bulk-replaced the long tail of solaria:8000/localhost:8000/localhost:8080 in
  docs and test scripts -> 6500.

Dockerfiles — 2 canonical, rust:latest, curl + healthcheck:
* backend/Dockerfile (prod): rust:latest builder, debian runtime now installs
  curl (so the compose HEALTHCHECK actually works), EXPOSE 6500.
* backend/docker/Dockerfile.dev (dev): rust:latest both stages, EXPOSE 6500.
* Deleted 3 redundant Dockerfiles (Dockerfile.improved x2, docker/Dockerfile).
* Deleted the committed 18 MB binary backend/docker/normogen-backend.
* Deleted 2 stray fix-notes in backend/docker/.

Compose:
* docker-compose.yml: correct env names, 6500:6500, APP_ENVIRONMENT=production,
  JWT_SECRET/ENCRYPTION_KEY required via compose interpolation, dropped the
  obsolete top-level version: key.
* docker-compose.dev.yml: correct env names, 6501:6500, mongo:7 (was 6.0),
  added a working backend healthcheck.
* Deleted docker/docker-compose.improved.yml + backend/deploy-to-solaria-improved.sh
  (built around the now-deleted 'improved' Docker files).

Verified: cargo fmt --check clean, build + clippy --all-targets clean, 18 unit
tests pass; grep confirms no SERVER_*/DATABASE_* env names and no rust:1.x tags
remain outside docs/archive and docs/adr (historical).
2026-06-27 19:54:32 -03:00

7.8 KiB

Normogen Deployment & Testing Guide

Overview

This guide covers deploying the Normogen backend to Solaria and testing all API endpoints.

Prerequisites

Local Setup

  • Git repository cloned
  • SSH access to Solaria configured
  • jq installed for JSON parsing
  • Scripts made executable

Server Requirements (Solaria)

  • Docker and Docker Compose installed
  • Git access to gitea.solivarez.com.ar
  • Ports 8000 available

Deployment Scripts

1. Deploy to Solaria

./deploy-to-solaria.sh

What it does:

  1. Pushes latest changes to git
  2. Connects to Solaria via SSH
  3. Clones/updates the repository
  4. Stops existing containers
  5. Builds and starts new containers
  6. Shows container status and logs

Manual Deployment Steps:

# Push to git
git push origin main

# SSH to Solaria
ssh alvaro@solaria

# Navigate to project
cd ~/normogen/backend

# Stop existing containers
docker-compose down

# Build and start
docker-compose up -d --build

# Check status
docker-compose ps

# View logs
docker-compose logs -f backend

2. Check Server Logs

./check-solaria-logs.sh

What it shows:

  • Container status
  • Backend logs (last 50 lines)
  • MongoDB logs

3. Test API Endpoints

./test-api-endpoints.sh

What it tests:

  1. Health Check
  2. Authentication (Register, Login)
  3. User Management (Get/Update Profile, Settings)
  4. Password Recovery (Set phrase, Recover, Change password)
  5. Share Management (Create, List shares)
  6. Permissions (Check permission)
  7. Session Management (Get sessions)

API Endpoints Reference

Base URL

http://solaria:6500

Public Endpoints (No Auth)

Health Check

curl http://solaria:6500/health

Register

curl -X POST http://solaria:6500/api/auth/register \
  -H "Content-Type: application/json" \
  -d '{
    "email": "test@example.com",
    "password": "Password123!",
    "full_name": "Test User"
  }'

Login

curl -X POST http://solaria:6500/api/auth/login \
  -H "Content-Type: application/json" \
  -d '{
    "email": "test@example.com",
    "password": "Password123!"
  }'

Set Recovery Phrase

curl -X POST http://solaria:6500/api/auth/set-recovery-phrase \
  -H "Content-Type: application/json" \
  -d '{
    "email": "test@example.com",
    "recovery_phrase": "my-secret-phrase"
  }'

Recover Password

curl -X POST http://solaria:6500/api/auth/recover-password \
  -H "Content-Type: application/json" \
  -d '{
    "email": "test@example.com",
    "recovery_phrase": "my-secret-phrase",
    "new_password": "NewPassword456!"
  }'

Protected Endpoints (Require Bearer Token)

Get Profile

curl http://solaria:6500/api/users/me \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN"

Update Profile

curl -X PUT http://solaria:6500/api/users/me \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -d '{
    "full_name": "Updated Name"
  }'

Get Settings

curl http://solaria:6500/api/users/me/settings \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN"

Update Settings

curl -X PUT http://solaria:6500/api/users/me/settings \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -d '{
    "theme": "dark"
  }'

Change Password

curl -X POST http://solaria:6500/api/users/me/change-password \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -d '{
    "old_password": "OldPassword123!",
    "new_password": "NewPassword456!"
  }'

Delete Account

curl -X DELETE http://solaria:6500/api/users/me \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -d '{
    "confirmation": "DELETE_ACCOUNT"
  }'

Create Share

curl -X POST http://solaria:6500/api/shares \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -d '{
    "target_email": "other@example.com",
    "resource_type": "profiles",
    "resource_id": "507f1f77bcf86cd799439011",
    "permissions": ["read"]
  }'

List Shares

curl http://solaria:6500/api/shares \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN"

Update Share

curl -X PUT http://solaria:6500/api/shares/SHARE_ID \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -d '{
    "permissions": ["read", "write"]
  }'

Delete Share

curl -X DELETE http://solaria:6500/api/shares/SHARE_ID \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN"

Check Permission

curl -X POST http://solaria:6500/api/permissions/check \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -d '{
    "resource_id": "507f1f77bcf86cd799439011",
    "permission": "read"
  }'

Get Sessions (NEW)

curl http://solaria:6500/api/sessions \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN"

Revoke Session (NEW)

curl -X DELETE http://solaria:6500/api/sessions/SESSION_ID \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN"

Revoke All Sessions (NEW)

curl -X DELETE http://solaria:6500/api/sessions/all \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN"

Troubleshooting

Container Won't Start

# Check logs
docker-compose logs backend

# Check container status
docker-compose ps

# Restart containers
docker-compose restart

# Rebuild from scratch
docker-compose down -v
docker-compose up -d --build

Database Connection Issues

# Check MongoDB is running
docker-compose ps mongodb

# Check MongoDB logs
docker-compose logs mongodb

# Test MongoDB connection
docker-compose exec backend mongosh mongodb://mongodb:27017

Permission Denied

# Make sure scripts are executable
chmod +x deploy-to-solaria.sh
chmod +x test-api-endpoints.sh
chmod +x check-solaria-logs.sh

SSH Connection Issues

# Test SSH connection
ssh alvaro@solaria

# Check SSH config
cat ~/.ssh/config | grep solaria

Environment Variables

Create a .env file in backend/ directory:

JWT_SECRET=your-super-secret-jwt-key-min-32-chars
MONGODB_URI=mongodb://mongodb:27017
MONGODB_DATABASE=normogen
RUST_LOG=info
NORMOGEN_PORT=6500
NORMOGEN_HOST=0.0.0.0
APP_ENVIRONMENT=production

Security Features (Phase 2.6)

Session Management

  • Tracks user sessions across devices
  • View active sessions
  • Revoke specific or all sessions
  • Automatic cleanup of expired sessions

Audit Logging

  • Logs all security-relevant events
  • Track login attempts, password changes
  • Monitor data access and modifications
  • Query logs by user or system-wide

Account Lockout

  • Brute-force protection
  • Progressive lockout durations
  • Configurable attempt limits
  • Automatic reset on successful login

Security Headers

  • X-Content-Type-Options: nosniff
  • X-Frame-Options: DENY
  • X-XSS-Protection: 1; mode=block
  • Strict-Transport-Security
  • Content-Security-Policy

Performance Tips

Production Deployment

  1. Use environment-specific JWT_SECRET
  2. Set RUST_LOG=warn for production
  3. Enable MongoDB authentication
  4. Use Docker volumes for data persistence
  5. Set up monitoring and alerting
  6. Configure reverse proxy (nginx/caddy)

Monitoring

# Check container stats
docker stats

# View real-time logs
docker-compose logs -f backend

# Check resource usage
docker-compose top

Next Steps

  1. Complete Phase 2.6 (Security Hardening)
  2. Integrate session management into auth flow
  3. Implement proper rate limiting
  4. Add comprehensive tests
  5. Begin Phase 2.7 (Health Data Features)

Support

For issues or questions:

  • Check logs: ./check-solaria-logs.sh
  • Review deployment: ./deploy-to-solaria.sh
  • Test API: ./test-api-endpoints.sh
  • Check PHASE_2.6_COMPLETION.md for implementation details