Skip to content

07 - BE

App Django REST Inicial com SQLite (Base para Migração Futura para RDS e S3)

Este roteiro cria um projeto Django REST inicial simples com SQLite que funciona perfeitamente no Elastic Beanstalk (versão 2026), projetado especificamente para facilitar migrações futuras para RDS e S3.

🛠️ Parte 0: Configuração do Ambiente (VS Code + Python + Django REST)

Passo 1: Instalar Python 3.12+

  1. Instale o Python 3.12 ou superior.
  2. Verifique no terminal:
python --version

Passo 2: Preparar VS Code

  1. Instale o Visual Studio Code.
  2. Em Extensions, instale:
  3. Python (Microsoft)
  4. Pylance (Microsoft)

Passo 3: Criar pasta do projeto e abrir no VS Code

mkdir catalogo-produtos
cd catalogo-produtos
code .

Passo 4: Criar e ativar virtual environment

python -m venv .venv

Ativação:

# Linux/Mac
source .venv/bin/activate

# Windows (PowerShell)
.venv\Scripts\Activate.ps1

Passo 5: Selecionar interpretador no VS Code

  1. Ctrl+Shift+P -> Python: Select Interpreter
  2. Escolha o interpretador da .venv

Passo 6: Instalar dependências iniciais

pip install django djangorestframework pillow gunicorn

Passo 7: Criar projeto Django e app REST

django-admin startproject catalogo .
python manage.py startapp produtos

Passo 8: Inicializar banco local e validar subida

python manage.py migrate
python manage.py runserver

Valide:

  1. http://127.0.0.1:8000/
  2. http://127.0.0.1:8000/admin/

📋 Parte 1: Criação do Projeto Local (30 minutos)

Passo 1: Estrutura Básica do Projeto

Crie esta estrutura de diretórios (fundamental para detecção automática do Elastic Beanstalk 2026):

catalogo-produtos/
├── .ebextensions/
│   ├── django.config
│   └── detection.config
├── .elasticbeanstalk/
│   └── config.yml
├── static/
├── media/
├── requirements.txt
├── Procfile
└── catalogo/
    ├── __init__.py
    ├── settings.py
    ├── urls.py
    ├── wsgi.py
    └── asgi.py
└── produtos/
    ├── __init__.py
    ├── admin.py
    ├── apps.py
    ├── models.py
    ├── serializers.py
    ├── views.py
    └── urls.py

Passo 2: Configuração Básica (SQLite)

catalogo/settings.py (partes relevantes):

import os
from pathlib import Path
BASE_DIR = Path(__file__).resolve().parent.parent

# Configuração de DEBUG - True para desenvolvimento
DEBUG = True if os.getenv('DJANGO_DEBUG', 'True') == 'True' else False

# Configuração do banco de dados
# Database
# https://docs.djangoproject.com/en/6.0/ref/settings/#databases

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': BASE_DIR / 'db.sqlite3',
    }
}

# Configuração de arquivos de mídia
# SQLite não suporta S3, mas já preparamos o caminho
if DEBUG:
    # Armazenamento local para desenvolvimento
    MEDIA_URL = '/media/'
    MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
else:
    # Configuração preparada para S3 (será ativada depois)
    USE_S3 = os.getenv('USE_S3', 'False') == 'True'
    if USE_S3:
        # Configurações S3 serão ativadas posteriormente
        pass
    else:
        MEDIA_URL = '/media/'
        MEDIA_ROOT = os.path.join(BASE_DIR, 'media')

# Hosts permitidos (importante para Elastic Beanstalk)
ALLOWED_HOSTS = os.getenv(
    'DJANGO_ALLOWED_HOSTS',
    'localhost,127.0.0.1,.elasticbeanstalk.com'
).split(',')

# Arquivos estáticos para deploy
STATIC_URL = '/static/'
STATIC_ROOT = BASE_DIR / 'staticfiles'

Passo 3: Modelo Simples de Produtos

produtos/models.py:

from django.db import models

class Produto(models.Model):
    nome = models.CharField(max_length=200)
    descricao = models.TextField()
    preco = models.DecimalField(max_digits=10, decimal_places=2)
    imagem = models.ImageField(upload_to='produtos/', blank=True, null=True)
    data_criacao = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        return self.nome

Passo 4: API REST Básica

produtos/serializers.py:

from rest_framework import serializers
from .models import Produto

class ProdutoSerializer(serializers.ModelSerializer):
    class Meta:
        model = Produto
        fields = ['id', 'nome', 'descricao', 'preco', 'imagem', 'data_criacao']

produtos/views.py:

from rest_framework import viewsets
from .models import Produto
from .serializers import ProdutoSerializer

class ProdutoViewSet(viewsets.ModelViewSet):
    queryset = Produto.objects.all()
    serializer_class = ProdutoSerializer

produtos/urls.py:

from django.urls import include, path
from .views import ProdutoViewSet
from rest_framework.routers import DefaultRouter

router = DefaultRouter()
router.register(r'produtos', ProdutoViewSet)

urlpatterns = [
    path('', include(router.urls)),
]

catalogo/urls.py:

from django.contrib import admin
from django.http import JsonResponse
from django.urls import path, include
from django.conf import settings
from django.conf.urls.static import static

def healthcheck(_request):
    return JsonResponse({'status': 'ok'})

urlpatterns = [
    path('', healthcheck),  # Health check do EB retorna 200
    path('admin/', admin.site.urls),
    path('api/', include('produtos.urls')),
]

# Configuração para servir arquivos de mídia em desenvolvimento
if settings.DEBUG:
    urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

📦 Parte 2: Preparação para Elastic Beanstalk 2026 (20 minutos)

Passo 1: Arquivos essenciais para Python 3.12+

.ebextensions/detection.config:

# Força a detecção correta como app Python/Django
option_settings:
  aws:elasticbeanstalk:application:environment:
    AWS_EB_PLATFORM_DETECTION: "python"
    AWS_EB_PLATFORM_OVERRIDE: "Python 3.12"

.ebextensions/django.config:

option_settings:
  aws:elasticbeanstalk:container:python:
    WSGIPath: catalogo/wsgi.py
  aws:elasticbeanstalk:application:environment:
    DJANGO_SETTINGS_MODULE: catalogo.settings
    DJANGO_DEBUG: False
  aws:elasticbeanstalk:environment:proxy:staticfiles:
    /static: staticfiles
    /media: media
container_commands:
  01_migrate:
    command: "python manage.py migrate --noinput"
    leader_only: true
  02_collectstatic:
    command: "python manage.py collectstatic --noinput"
    leader_only: true
  03_create_media_dir:
    command: "mkdir -p media/produtos"
  04_permissao_arquivo_sqlite:
    command: "chmod 666 db.sqlite3"
  05_permissao_pasta_sqlite:
    command: "chmod 777 ."

Procfile:

web: gunicorn catalogo.wsgi:application --bind 127.0.0.1:8000

.elasticbeanstalk/config.yml (usado no fluxo com EB CLI):

branch-defaults:
  main:
    environment: null
    group_suffix: null
environment-defaults: {}
deploy:
  artifact: app.zip
global:
  application_name: catalogo-produtos
  default_platform: Python 3.12
  default_region: us-east-1
  include_gitid: yes
  instance_profile: null
  platform_name: null
  platform_version: null
  profile: eb-cli
  sc: git
  workspace_type: Application

Passo 2: Requisitos do projeto (Django 6 com Python 3.12+)

requirements.txt:

asgiref==3.11.1
Django==6.0.4
djangorestframework==3.17.1
pillow==12.2.0
sqlparse==0.5.5
tzdata==2026.1
gunicorn==21.2.0
# psycopg2-binary==2.9.9  # Para futura migração para RDS
# boto3==1.28.56          # Para futura migração para S3
# django-storages==1.13.3 # Para futura migração para S3

Passo 3: Variáveis de ambiente no EB (importante)

No primeiro deploy, o Elastic Beanstalk instala dependências e aplica .ebextensions, mas ele não cria automaticamente variáveis como RDS_*, USE_S3 ou DJANGO_ALLOWED_HOSTS só porque elas aparecem no settings.py.

Defina manualmente no console (Configuration > Software > Environment properties), pelo menos:

  • DJANGO_DEBUG=False (produção)
  • DJANGO_ALLOWED_HOSTS=<seu-dominio-eb>,.elasticbeanstalk.com

🧪 Parte 3: Teste Local Antes do Deploy (15 minutos)

Passo 1: Configuração Inicial

# Crie e ative um ambiente virtual
python -m venv venv
source venv/bin/activate  # Linux/Mac
venv\Scripts\activate    # Windows

# Instale dependências
pip install -r requirements.txt

# Crie o banco de dados SQLite
python manage.py migrate

# Crie um superusuário (opcional)
python manage.py createsuperuser

Passo 2: Teste de Funcionamento

python manage.py runserver

Verifique: 1. Acesse http://localhost:8000/admin/ (se criou superusuário) 2. Acesse http://localhost:8000/api/produtos/ - deve ver JSON vazio 3. Teste o upload de uma imagem via POST (use Postman ou curl)

☁️ Parte 4: Deploy no Elastic Beanstalk 2026 (20 minutos)

Passo0: Configuração da Política IAM para Deploy

Entre no IAM, selecione o usuário que usará para deploy e adicione a seguinte política gerenciada:

  • Add Permissions > Attach policies diretly > Pesquise por "Elastic Beanstalk" e selecione:
  • AdministratorAccess-AWSElasticBeanstalk

Passo 1: Preparar o Pacote para Deploy

  1. Certifique-se de que todos os arquivos estão na raiz do ZIP
  2. Não inclua:
  3. Diretório venv/ ou .venv/
  4. Arquivo db.sqlite3
  5. Diretório .git/
  6. Diretórios __pycache__/
  7. Arquivos .env

Passo 2: Fluxo Correto para 2026

  1. Elastic Beanstalk > Create Application
  2. Preencha apenas:
  3. Application name: catalogo-produtos
  4. Description: "Catálogo de produtos para aula"
  5. Role até Application code > Upload your code
  6. Clique em Local file > Choose file
  7. Selecione TODOS os arquivos do projeto (não a pasta, os arquivos diretamente)
  8. Clique em Zip para criar um ZIP temporário
  9. Clique em Upload

Passo 3: Selecione e valide a plataforma

  • Na criação do ambiente, selecione explicitamente Python 3.12
  • Não dependa da versão do Django para o EB inferir a plataforma

  • Espere 1-2 minutos enquanto a AWS analisa seu código

  • Não clique em nada durante este tempo
  • Você verá: "Analyzing your code..."
  • Confirme que o ambiente foi criado em Python 3.12

Passo 4: Finalize e Acompanhe

  1. Clique em Create application
  2. Aguarde 8-10 minutos para o deploy completo
  3. Clique em Environment health para monitorar
  4. Quando estiver verde, clique em Domain para acessar seu app

🔄 Parte 5: Caminho para Migrações Futuras (Documentação para Você)

Migração para RDS (PostgreSQL)

Quando estiverem prontos, siga estes passos:

  1. Crie uma instância RDS no console AWS
  2. Atualize as variáveis de ambiente no Elastic Beanstalk:
  3. RDS_DB_NAME = nome do banco
  4. RDS_USERNAME = usuário
  5. RDS_PASSWORD = senha
  6. RDS_HOSTNAME = endpoint do RDS
  7. RDS_PORT = 5432
  8. Remova o arquivo db.sqlite3 do projeto
  9. Execute migrações:
    eb ssh  # Conecte-se à instância
    source /var/app/venv/*/bin/activate
    cd /var/app/current
    python manage.py migrate
    

Migração para S3

Quando estiverem prontos, siga estes passos:

  1. Crie o bucket S3 conforme discutido anteriormente
  2. Crie o usuário IAM com grupo correto
  3. Atualize as variáveis de ambiente:
  4. USE_S3 = True
  5. AWS_ACCESS_KEY_ID = sua chave
  6. AWS_SECRET_ACCESS_KEY = sua secret
  7. AWS_STORAGE_BUCKET_NAME = nome do bucket
  8. AWS_S3_REGION_NAME = região
  9. Atualize settings.py (descomente a seção S3)
  10. Adicione este código a settings.py:
    if not DEBUG and USE_S3:
        # Configurações AWS S3 atualizadas para 2026
        AWS_S3_ADDRESSING_STYLE = "virtual"
        AWS_S3_FILE_OVERWRITE = False
        AWS_DEFAULT_ACL = None
        AWS_QUERYSTRING_AUTH = False
        AWS_S3_SIGNATURE_VERSION = 's3v4'
    
        AWS_S3_CUSTOM_DOMAIN = f'{AWS_STORAGE_BUCKET_NAME}.s3.{AWS_S3_REGION_NAME}.amazonaws.com'
        MEDIA_URL = f'https://{AWS_S3_CUSTOM_DOMAIN}/media/'
        DEFAULT_FILE_STORAGE = 'storages.backends.s3boto3.S3Boto3Storage'
    

📚 Material de Apoio

Checklist Visual para Deploy 2026

Checklist Elastic Beanstalk 2026

Fluxo de Migração Futura

graph LR
    A[SQLite Local] -->|Fase 1| B[App Funcionando no Elastic Beanstalk]
    B -->|Fase 2| C[Migração para RDS]
    C -->|Fase 3| D[Migração para S3]

    style A fill:#e8f5e9,stroke:#4caf50
    style B fill:#e8f5e9,stroke:#4caf50
    style C fill:#fff8e1,stroke:#ff9800
    style D fill:#ffebee,stroke:#f44336

classDef current fill:#e8f5e9,stroke:#4caf50;
    class A,B current;

✅ Checklist Final de Deploy (10 itens)

Antes de clicar em Create environment, valide:

  1. Plataforma selecionada no EB: Python 3.12.
  2. requirements.txt com versões corretas (Django==6.0.4, DRF e gunicorn).
  3. Procfile presente na raiz com web: gunicorn catalogo.wsgi:application --bind 127.0.0.1:8000.
  4. .ebextensions/django.config contém WSGIPath, DJANGO_SETTINGS_MODULE e container_commands (migrate + collectstatic).
  5. catalogo/urls.py possui rota / de healthcheck retornando 200.
  6. catalogo/settings.py com ALLOWED_HOSTS via DJANGO_ALLOWED_HOSTS.
  7. Variáveis no EB definidas: DJANGO_DEBUG=False e DJANGO_ALLOWED_HOSTS=<dominio-do-ambiente>,.elasticbeanstalk.com.
  8. ZIP com arquivos na raiz (sem pasta pai) e sem venv/, .venv/, .git/, db.sqlite3, __pycache__/, .env.
  9. Usuário IAM com permissão para política de criar ambiente EB.
  10. Após criar, ambiente deve ficar Green e endpoints https://<dominio>/ e https://<dominio>/api/produtos/ devem responder.