Skip to content

Remover comandos de migration dos scripts de inicialização #973

@vrtornisiello

Description

@vrtornisiello

Contexto

Atualmente, nosso script de inicialização start-server.sh:

  1. Cria arquivos de migração.
  2. Aplica as migrações.
echo "> Making migrations"
(cd /app; python manage.py makemigrations)

echo "> Applying migrations"
(cd /app; python manage.py migrate)

Problemas

1. Criação de migrações em runtime

O comando makemigrations no script de inicialização pode gerar arquivos de migração diretamente nos pods quando há alterações nos modelos sem as migrações correspondentes commitadas. Essas migrações efêmeras são perdidas quando o pod é destruído e recriadas no próximo deploy, resultando em erros ao tentar aplicar migrações já existentes no banco. Isso torna o estado do banco de dados imprevisível e dificulta debug e rollback.

2. Migrações concorrentes durante o deploy

Com múltiplas réplicas do backend no GKE, todos os pods executam migrate simultaneamente no mesmo banco de dados. Isso causa:

  • Aumento no tempo de startup devido ao lock do banco
  • Risco de estado indesejado dependendo das operações das migrações

Embora atualmente utilizemos apenas uma réplica, essa configuração não escala e não é uma boa prática.

Solução proposta

Para o problema 1

Remover o comando makemigrations do script. Migrações devem ser criadas e testadas durante o desenvolvimento e commitadas no repositório. O processo de code review deve garantir que todas as alterações nos modelos possuam as migrações correspondentes.

Para o problema 2

Substituir a execução de migrate no script por um Job com Helm Hooks, executado como etapa anterior ao deploy do backend.

Exemplo de configuração do Job:

apiVersion: batch/v1
kind: Job
metadata:
  name: {{ .Values.api.name }}-migration
  annotations:
    "helm.sh/hook": pre-install,pre-upgrade
    "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded
spec:
  template:
    spec:
      containers:
        - name: api-migration
          image: "{{ .Values.api.image.name }}:{{ .Values.api.image.tag }}"
          command: ["python", "manage.py", "migrate"]
          # ... envs e volumes necessários
      restartPolicy: Never
  activeDeadlineSeconds: 300  # Timeout de 5 minutos
  backoffLimit: 3 # Limite de três tentativas

Se o Job falhar, a release é abortada. Caso contrário, o deploy prossegue normalmente.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions