Pular para o conteúdo

Deploy de FastAPI no AWS App Runner: um guia pronto para produção

deploying-fastapi | Cheesecake Labs
Resumo
  • O artigo mostra como fazer deploy de uma aplicação FastAPI no AWS App Runner, que cuida de escala, load balancing e gestão de infraestrutura a partir de um container ou repositório de código.
  • Os pré-requisitos na AWS incluem criar um repositório no Amazon ECR e uma role no IAM com a policy AWSAppRunnerServicePolicyForECRAccess, além de configurar o serviço do App Runner com deploy automático a cada nova imagem enviada.
  • O pipeline de CI/CD usa GitHub Actions com secrets de ambiente (AWS_ACCESS_KEY, AWS_SECRET_ACCESS_KEY, AWS_REGION, ECR_REPOSITORY_URI) para autenticar na AWS, fazer build, tag e push da imagem Docker para o ECR, recomendando permissões mínimas e, se possível, autenticação via OIDC.
  • A aplicação é adaptada com um Dockerfile usando uv, um entrypoint que sobe o Uvicorn na porta 8080 (que deve coincidir com a porta do App Runner) e um endpoint /health, com o deploy podendo ser acompanhado pelos logs no console do serviço.

Fazer deploy de aplicações na AWS tem fama: poderoso, flexível… e vez ou outra capaz de transformar uma tarde tranquila em uma aventura inesperada. Entre roles de IAM, imagens de container e decisões de rede, é fácil sentir que você precisa de mapa e bússola só para colocar um “Hello, world” no ar.

É aí que entra o AWS App Runner. A proposta é um caminho mais simples: você traz a sua aplicação, aponta para um container ou para um repositório de código, e a AWS cuida do trabalho pesado, incluindo escala, load balancing e gestão de infraestrutura.

Neste artigo, você vai percorrer o processo de deploy de uma aplicação FastAPI no AWS App Runner, com foco em um setup limpo e pronto para produção, sem complexidade desnecessária.

Se você gosta de APIs rápidas, menos arquivos YAML e deploys que não exigem sacrifício ritual, está no lugar certo.

Configurações na AWS

Antes de escrever qualquer código, é preciso criar alguns recursos básicos na AWS. Essas configurações permitem que o App Runner puxe a imagem do container com segurança e execute a aplicação FastAPI.

Repositório no Elastic Container Registry

Primeiro, crie um repositório para armazenar a imagem Docker da aplicação FastAPI.

  1. Vá em Amazon ECRCreate repository.
  2. Escolha um nome para o repositório. Neste artigo, vamos usar: fastapi-app-runner
  3. Clique em Create repository.

Depois de criar, copie e guarde o Repository URI. Ele será necessário mais adiante, na hora de fazer o build e o push da imagem Docker.

A role do App Runner

O App Runner precisa de permissão explícita para puxar imagens do Amazon ECR. Esse acesso é concedido criando uma role no IAM.

  1. Vá em IAMRolesCreate role.
  2. Selecione Custom trust policy.
  3. Cole o JSON abaixo no editor de policy:
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": "apprunner.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}Code language: JSON / JSON with Comments (json)
  1. Clique em Next.
  2. Na página Permissions, busque e anexe a policy: AWSAppRunnerServicePolicyForECRAccess
  3. Clique em Next, dê um nome significativo para a role (por exemplo, AppRunnerECRAccessRole) e clique em Create role.

Leia também: Construindo redes neurais do zero

Criando o serviço no App Runner

Com os pré-requisitos da AWS prontos, chegou a hora de criar o serviço do App Runner que vai rodar a aplicação FastAPI. Siga os passos abaixo:

  1. Vá em AWS App Runner Create service.
  2. Em Repository type, selecione Container registry.
  3. Em Provider, escolha Amazon ECR. Cole o URI do repositório ECR criado na seção anterior e acrescente a tag :latest da imagem
  4. Em Deployment trigger, selecione Automatic. Com essa opção ativada, cada nova imagem enviada para o ECR dispara automaticamente um novo deploy no App Runner.
  5. Selecione Use existing service role e escolha a role do IAM criada antes. É ela que permite ao App Runner puxar imagens do ECR.
  6. Clique em Next para abrir a página Configure service.
  7. Dê um nome ao seu serviço.
  8. Para simplificar, mantenha as configurações padrão desta página. Essas opções controlam tamanho de instância, comportamento de escala e roles adicionais do IAM, temas mais avançados e fora do escopo deste artigo. Vamos tratar deles em um post futuro. 
  9. Revise a configuração e clique em Create & deploy.

Assim que o serviço for criado e o deploy terminar, o App Runner passa a executar a sua aplicação FastAPI conteinerizada. Daqui em diante, o foco é adaptar o código da aplicação para funcionar bem com o App Runner.

Leia também: Além do “vibe coding”: engenharia com IA e Cursor

A base do CI/CD: conectando o GitHub à AWS

Para automatizar o processo de build e deploy, é preciso configurar no GitHub as credenciais da AWS e as variáveis específicas de cada ambiente. Isso permite que o workflow do GitHub Actions se autentique na AWS e envie imagens Docker para o Amazon ECR.

Crie um ambiente no GitHub

Usar ambientes ajuda a isolar credenciais e aplicar controles extras, como revisores obrigatórios ou secrets específicos de cada ambiente.

  1. Acesse o seu repositório no GitHub.
  2. Vá em SettingsEnvironments.
  3. Clique em New environment.
  4. Dê um nome ao ambiente (por exemplo, production ou staging) e salve.

Gerenciando credenciais da AWS e variáveis de deploy com segurança

Adicione os secrets do ambiente

Com o ambiente criado, o próximo passo é adicionar os secrets que o pipeline de CI/CD precisa.

  1. Abra o ambiente que você acabou de criar.
  2. Em Environment secrets, clique em Add secret.
  3. Adicione os seguintes secrets: AWS_ACCESS_KEY, AWS_SECRET_ACCESS_KEY, AWS_REGION, ECR_REPOSITORY_URI. Leia este artigo para obter as variáveis KEY.

Garanta que as credenciais do IAM usadas aqui tenham permissão para autenticar no ECR e enviar imagens para o repositório.

Boas práticas de segurança para CI/CD

  • Guarde credenciais apenas como secrets do GitHub. Nunca faça commit delas no repositório.
  • Use um usuário ou uma role do IAM dedicados, com permissões mínimas, limitadas ao acesso ao ECR.
  • Se possível, considere usar autenticação baseada em OIDC com o GitHub Actions para evitar credenciais de longa duração na AWS. Essa abordagem é mais segura e mais adequada a ambientes de produção.

Com o ambiente e os secrets configurados no GitHub, chegou a hora de criar o workflow do GitHub Actions que faz o build da imagem Docker e a envia automaticamente para o Amazon ECR.

Leia também: Como usar Selenium para web scraping no AWS Lambda

Mudanças no código: adaptando a aplicação para rodar no App Runner

Vamos começar pelo arquivo responsável por instanciar a aplicação FastAPI. O trecho de código abaixo mostra um setup mínimo de FastAPI, expondo um único endpoint GET /health.

import os

from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
from starlette.middleware.sessions import SessionMiddleware


app = FastAPI()

app.add_middleware(
    CORSMiddleware,
    allow_origins=["*"],
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

app.add_middleware(SessionMiddleware, secret_key=os.getenv("JWT_SECRET_KEY", "default"))

@app.get("/health")
async def health_check():
    """Health check endpoint."""
    return {"status": "ok"}Code language: JavaScript (javascript)

Agora, veja o Dockerfile. Ele é propositalmente simples: instala as dependencies com o gerenciador de pacotes uv, define o diretório de trabalho e chama o script entrypoint.sh. Preste atenção especial na porta exposta, que precisa coincidir com a porta configurada no AWS App Runner (8080 por padrão).

FROM python:3.12.11-slim-bookworm AS builder

COPY --from=ghcr.io/astral-sh/uv:latest /uv /uvx /bin/

WORKDIR /app
ENV PATH="/app/.venv/bin:$PATH"

ENV UV_LINK_MODE=copy

COPY pyproject.toml uv.lock .python-version ./
RUN uv sync --locked --no-dev
RUN uv pip install --system alembic

COPY . .

FROM python:3.12.11-slim-bookworm

COPY --from=ghcr.io/astral-sh/uv:latest /uv /uvx /bin/
RUN apt-get update && \
    apt-get upgrade -y && \
    apt-get clean && \
    rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*

RUN pip install --upgrade pip setuptools

WORKDIR /app
ENV PATH="/app/.venv/bin:$PATH"

COPY --from=builder /app /app
COPY entrypoint.sh /entrypoint.sh

RUN chmod +x /entrypoint.sh

EXPOSE 8080

ENTRYPOINT ["/entrypoint.sh"]Code language: JavaScript (javascript)

O arquivo docker-compose.yml também é direto. Ele referencia o Dockerfile, expõe as portas do container e carrega as variáveis de ambiente do arquivo .env.

services:
  singuessr:
    build:
      context: .
      dockerfile: Dockerfile
    ports:
      - "8080:8000"
    env_file:
      - .envCode language: CSS (css)

Por fim, o script entrypoint.sh sobe o servidor Uvicorn, escutando na porta 8080.

#!/bin/sh

set -e

echo "Starting application..."
uv run uvicorn main:app --host 0.0.0.0 --port 8080Code language: PHP (php)

Automatizando build e deploy com GitHub Actions

Crie um arquivo chamado .github/workflows/app-runner-deploy.yml na raiz do projeto e adicione a configuração abaixo. Esse workflow define o pipeline do GitHub Actions responsável pelo deploy. Ele executa os seguintes passos: autentica na AWS, faz o build da imagem Docker, aplica a tag e envia a imagem para o Amazon ECR.

name: AWS App Runner Deploy Develop

on:
  push:
    branches:
      - main # ← branch name

jobs:
  deploy:
    name: FastAPI deployment to AWS App Runner
    runs-on: ubuntu-latest
    environment: Production # ← Github environment

    steps:
      - name: Checkout
        uses: actions/checkout@v3

      - name: Configure AWS Credentials
        uses: aws-actions/configure-aws-credentials@v2
        with:
          aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY }}
          aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
          aws-region: ${{ secrets.AWS_REGION }}

      - name: Login to Amazon ECR
        uses: aws-actions/amazon-ecr-login@v1

      - name: Build Docker image
        run: |
          docker build \
            -t fastapi-app-runner:latest \
            -f Dockerfile .

      - name: Tag Docker image
        run: |
          docker tag fastapi-app-runner:latest \
            ${{ secrets.ECR_REPOSITORY_URI }}:latest

      - name: Push Docker image to ECR
        run: |
          docker push ${{ secrets.ECR_REPOSITORY_URI }}:latestCode language: PHP (php)

Depois de fazer o commit e o push das suas mudanças para a branch escolhida (neste exemplo, a branch main), a execução do workflow aparece na aba Actions. Se tudo estiver configurado corretamente, todos os passos vão terminar com sucesso.

Configuração de deploy do serviço no AWS App Runner

O resultado final é uma imagem Docker disponível no seu repositório do Amazon ECR.

Aplicação FastAPI rodando no AWS App Runner

Deploy no App Runner: disparando e acompanhando publicações automáticas

Depois que você envia o código para a branch definida no workflow do GitHub Actions, o deploy no App Runner é disparado automaticamente. Você acompanha o processo e consulta todos os logs de execução direto no console do serviço do App Runner.

O deploy deve terminar em poucos minutos.

Log de eventos do AWS App Runner durante uma publicação automática

Para testar a aplicação, acesse a URL clicando em Default domain e chame, por exemplo, o endpoint /docs para ver a documentação da API.

Resposta da API FastAPI publicada no AWS App Runner

Considerações finais e próximos passos

O AWS App Runner oferece um equilíbrio convincente entre simplicidade e robustez operacional. Para aplicações conteinerizadas como serviços FastAPI, ele elimina boa parte do overhead tradicional de gestão de infraestrutura e ainda se integra de forma limpa ao restante do ecossistema AWS.

Por que o App Runner funciona bem com FastAPI

  • Overhead operacional mínimo: não é preciso gerenciar clusters, load balancers ou políticas de escala manualmente.
  • Suporte nativo a containers: a integração direta com o Amazon ECR simplifica o pipeline de deploy.
  • Escala automática: o serviço sobe e desce conforme o tráfego, sem configuração adicional.
  • Segurança e rede embutidas: HTTPS, load balancing e isolamento de serviço ficam por conta da AWS.
  • Ciclos de iteração curtos: combinado com o GitHub Actions, o deploy fica previsível e repetível.

Para muitos serviços de backend e APIs, o App Runner acerta o ponto entre plataformas totalmente gerenciadas e soluções mais complexas como ECS ou EKS.

Leia também: Boas práticas de FinOps na AWS: como cortar e otimizar custos de cloud

Próximos passos: escala, segurança e melhorias operacionais

Este artigo foca em um setup simples e funcional, mas há várias frentes que valem a exploração seguinte:

  • Ajuste fino da configuração de instância: o App Runner permite ajustar CPU e memória, limites de concorrência e comportamento de auto-scaling. Essas opções são essenciais para otimizar performance e custo conforme o tráfego cresce.
  • Infraestrutura como código com Terraform: gerenciar serviços do App Runner, roles do IAM e repositórios do ECR com Terraform melhora reprodutibilidade e governança. Também deixa setups com vários ambientes (staging, produção) mais fáceis de manter e revisar.
  • Melhorias de segurança: considere trocar as credenciais estáticas da AWS no GitHub Actions por autenticação baseada em OIDC e apertar as permissões do IAM seguindo o princípio do menor privilégio.
  • Observabilidade e monitoramento: integre logs, métricas e alarmes do Amazon CloudWatch para ganhar visibilidade sobre o comportamento e a performance da aplicação.

Em resumo, o App Runner é um excelente ponto de entrada para rodar aplicações FastAPI em nível de produção na AWS. Conforme os requisitos crescem, você adiciona controle e automação aos poucos, sem abrir mão da simplicidade que torna o App Runner atraente desde o começo.

legacy-app-ckl | | Cheesecake Labs

FAQ

O que é o AWS App Runner e qual é a sua proposta?

O AWS App Runner propõe um caminho mais simples para deploy: você traz a sua aplicação, aponta para um container ou para um repositório de código, e a AWS cuida do trabalho pesado, incluindo escala, load balancing e gestão de infraestrutura.

Quais recursos precisam ser criados na AWS antes de configurar o serviço no App Runner?

É preciso criar um repositório no Amazon ECR para armazenar a imagem Docker da aplicação FastAPI (no artigo, chamado fastapi-app-runner) e uma role no IAM com custom trust policy para o serviço apprunner.amazonaws.com, anexando a policy AWSAppRunnerServicePolicyForECRAccess. Essa role dá ao App Runner permissão para puxar imagens do ECR.

Quais secrets devem ser configurados no ambiente do GitHub para o pipeline de CI/CD?

Os secrets são AWS_ACCESS_KEY, AWS_SECRET_ACCESS_KEY, AWS_REGION e ECR_REPOSITORY_URI. As credenciais do IAM usadas devem ter permissão para autenticar no ECR e enviar imagens para o repositório. Como boas práticas, guarde credenciais apenas como secrets do GitHub, use um usuário ou role do IAM dedicados com permissões mínimas e, se possível, considere autenticação baseada em OIDC para evitar credenciais de longa duração.

Qual cuidado é necessário com a porta da aplicação FastAPI no container?

A porta exposta no Dockerfile precisa coincidir com a porta configurada no AWS App Runner, que é 8080 por padrão. No exemplo, o Dockerfile expõe a porta 8080 e o script entrypoint.sh sobe o servidor Uvicorn escutando nessa mesma porta.

Como o deploy é disparado e acompanhado após o push do código?

O workflow do GitHub Actions autentica na AWS, faz o build da imagem Docker, aplica a tag e envia a imagem para o Amazon ECR. Com o Deployment trigger configurado como Automatic no App Runner, cada nova imagem enviada ao ECR dispara automaticamente um novo deploy. O processo e os logs podem ser acompanhados no console do serviço do App Runner, e o deploy deve terminar em poucos minutos; para testar, acesse a URL em Default domain e chame, por exemplo, o endpoint /docs.