Pular para conteúdo

Deploy em Produção

Deploy do LASERLAB-Sis no servidor laser-estoque usando Docker Compose com Nginx + Gunicorn + PostgreSQL 16.

Pré-requisitos

  • Servidor Ubuntu 24.04 com Docker e Docker Compose instalados
  • Acesso via Tailscale (Tailnet)
  • Deploy key configurada no GitHub para clone via SSH

Arquitetura

Container Imagem Rede Porta
laserlab_nginx nginx:alpine host 80
laserlab_web Dockerfile.prod (Python 3.12) host 8000
laserlab_db postgres:16-alpine bridge 127.0.0.1:5432

Por que network_mode: host? O container web precisa acessar a impressora Zebra na rede local (10.42.0.216:9100). Com rede bridge, o container não alcança a LAN. Veja network-printer.md para detalhes.

Primeiro Deploy (Setup Inicial)

1. Clonar o repositório

ssh laser@100.88.89.90

# Criar diretório de deploy
sudo mkdir -p /opt/laserlab
sudo chown laser:laser /opt/laserlab

# Clonar via deploy key
git clone git@github.com:felipeosmar/LASERLAB-Sis.git /opt/laserlab
cd /opt/laserlab

2. Criar o .env

cp .env.production .env

Editar .env e substituir os valores placeholder:

DEBUG=False
SECRET_KEY=<gerar com: python3 -c "import secrets; print(secrets.token_urlsafe(50))">
ALLOWED_HOSTS=laser-estoque.tailb42313.ts.net,100.88.89.90,localhost

POSTGRES_DB=laserlab
POSTGRES_USER=laserlab
POSTGRES_PASSWORD=<gerar com: python3 -c "import secrets; print(secrets.token_urlsafe(24))">
DATABASE_URL=postgres://laserlab:<MESMA_SENHA>@127.0.0.1:5432/laserlab

Alternativa: O script deploy.sh gera as chaves automaticamente se .env não existir.

3. Executar o deploy

# Opção A: Script automatizado (recomendado para primeiro deploy)
bash deploy.sh

# Opção B: Manual
docker compose -f docker-compose.prod.yml build
docker compose -f docker-compose.prod.yml up -d db
sleep 5
docker compose -f docker-compose.prod.yml run --rm web python manage.py migrate --noinput
docker compose -f docker-compose.prod.yml run --rm web python manage.py collectstatic --noinput
docker compose -f docker-compose.prod.yml up -d

4. Criar superusuário

docker compose -f docker-compose.prod.yml run --rm web python manage.py createsuperuser

⚠️ O deploy.sh cria um superuser padrão (admin/admin123). Troque a senha imediatamente em produção.

Deploys Subsequentes

Deploys subsequentes são automatizados via GitHub Actions (veja ci-cd.md). Para deploy manual:

cd /opt/laserlab
git fetch origin main
git reset --hard origin/main
docker compose -f docker-compose.prod.yml build
docker compose -f docker-compose.prod.yml run --rm web python manage.py migrate --noinput
docker compose -f docker-compose.prod.yml run --rm web python manage.py collectstatic --noinput
docker compose -f docker-compose.prod.yml up -d

Arquivos de Configuração

Arquivo Descrição
docker-compose.prod.yml Orquestração dos 3 containers
Dockerfile.prod Build da imagem Django (Python 3.12-slim + Gunicorn)
nginx/default.conf Proxy reverso + arquivos estáticos
.env.production Template de variáveis de ambiente
.env Variáveis reais (não versionado, apenas no servidor)
deploy.sh Script de primeiro deploy (gera chaves, migra, inicia)

Gunicorn

Configuração no Dockerfile.prod:

Workers: 3
Worker class: gthread
Threads: 2
Timeout: 120s

Comandos Úteis

# Ver status dos containers
docker compose -f docker-compose.prod.yml ps

# Ver logs
docker compose -f docker-compose.prod.yml logs -f web
docker compose -f docker-compose.prod.yml logs -f nginx

# Reiniciar serviço específico
docker compose -f docker-compose.prod.yml restart web

# Abrir shell Django
docker compose -f docker-compose.prod.yml run --rm web python manage.py shell

# Parar tudo
docker compose -f docker-compose.prod.yml down

# Parar tudo E apagar dados (⚠️ CUIDADO)
docker compose -f docker-compose.prod.yml down -v

Troubleshooting

Container web não inicia

docker compose -f docker-compose.prod.yml logs web
Verificar: .env existe? DATABASE_URL aponta para 127.0.0.1:5432?

Nginx retorna 502

O Gunicorn ainda está iniciando ou caiu. Verificar logs do web.

Static files 404

docker compose -f docker-compose.prod.yml run --rm web python manage.py collectstatic --noinput
docker compose -f docker-compose.prod.yml restart nginx