Pular para o conteúdo principal

Aplicação Flask usando Nginx e Gunicorn


Aplicação Flask usando Nginx e Gunicorn

Se você já desenvolveu uma aplicação Flask básica, sabe que o servidor de desenvolvimento embutido não é ideal para produção. Ele não é projetado para lidar com altos volumes de tráfego ou conexões simultâneas. Para tornar sua aplicação Flask mais robusta e pronta para produção, podemos usar o Gunicorn como servidor de aplicação e o Nginx como proxy reverso.

Neste artigo, vamos adaptar o exemplo anterior (Criando uma Aplicação CRUD com Flask, PostgreSQL e Docker) para incluir o Nginx e o Gunicorn.


O que são Nginx e Gunicorn?

Gunicorn

O Gunicorn (Green Unicorn) é um servidor de aplicação WSGI que roda aplicações Python como o Flask. Ele é eficiente e simples de configurar, lidando com múltiplas requisições ao mesmo tempo, algo que o servidor embutido do Flask não faz bem.

Nginx


O Nginx é um servidor web que atua como um proxy reverso. Ele recebe requisições HTTP e as encaminha ao Gunicorn. Além disso, o Nginx pode:

  • Servir arquivos estáticos (como imagens e CSS) diretamente.
  • Gerenciar conexões HTTPS.
  • Balancear carga entre várias instâncias do Gunicorn.

Estrutura do Projeto

A estrutura do projeto permanece similar ao exemplo anterior, com algumas adições para o Nginx.

crud-app/
|-- app/
|   |-- app.py
|   |-- templates/
|   |   |-- index.html
|   |   |-- edit.html
|-- Dockerfile
|-- requirements.txt
|-- docker-compose.yml
|-- nginx.conf

Alterações Necessárias

Passo 1: Atualizando o requeriments.txt

No arquivo requeriments.txt, incluimos uma nova dependencia para disponibilzar o Gunicorn, substitua o conteúdo anterior pelo seguinte:

Flask==2.2.2
Flask-SQLAlchemy==3.0.2
psycopg2-binary==2.9.3
Werkzeug==2.2.2
gunicorn==20.1.0

Passo 2: Atualizando o Dockerfile

No arquivo Dockerfile, configuramos o Gunicorn para servir a aplicação Flask. Substitua o conteúdo anterior pelo seguinte:

FROM python:3.9

WORKDIR /app

COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

COPY . .

EXPOSE 5000
CMD ["gunicorn", "-b", "0.0.0.0:5000", "app.app:app"]

Aqui, usamos o Gunicorn para executar a aplicação Flask. O comando gunicorn -b 0.0.0.0:5000 app.app:app diz ao Gunicorn para:

  • Ligar-se ao endereço 0.0.0.0 na porta 5000.
  • Rodar a aplicação Flask localizada na pasta app no arquivo app.py (o formato é <pasta>.<arquivo>:<objeto>).

Passo 3: Adicionando a Configuração do Nginx

Crie um arquivo nginx.conf na raiz do projeto com o seguinte conteúdo:

# nginx.conf
events {
    worker_connections 1024;
}

http {
    server {
        listen 80;

        location / {
            proxy_pass http://web:5000;  # Encaminha requisições para o Gunicorn
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        }

        location /static/ {
            alias /app/static/;  # Serve arquivos estáticos diretamente
        }
    }
}

O Nginx aqui está configurado para encaminhar as requisições para o serviço web (que executará o Gunicorn no Docker).


Passo 4: Atualizando o docker-compose.yml

Adicione o serviço do Nginx ao docker-compose.yml:

services:
  web:
    build: .
    expose:
      - "5000"
    depends_on:
      - db
  db:
    image: postgres:13
    environment:
      POSTGRES_USER: user
      POSTGRES_PASSWORD: password
      POSTGRES_DB: crud_db
    ports:
      - "5432:5432"
  nginx:
    image: nginx
    ports:
      - "80:80"
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf
    depends_on:
      - web

Passo 5: Executando o Projeto

  1. Suba os contêineres com o comando:

    docker-compose up --build
    
  2. Acesse a aplicação em http://localhost.


Benefícios da Nova Configuração

  • Desempenho Melhorado: O Gunicorn gerencia múltiplas requisições e o Nginx é otimizado para lidar com tráfego pesado.
  • Segurança: O Nginx adiciona uma camada de proteção contra ataques comuns.
  • Escalabilidade: Fácil de escalar adicionando mais instâncias do Gunicorn.
  • Gerenciamento de Arquivos Estáticos: O Nginx pode servir arquivos estáticos de forma eficiente.

    Conclusão

    Como vimos é importante pensar na segurança e na escalabilidade de nossas aplicações, ao usar o Nginx e o Gunicorn em nossas aplicações Flask garantimos um ambiente de produção robusto e escalável.

    O projeto de exemplo pode ser encontrado aqui.

    Comentários

    Mais visitadas

    Manipular arquivos com PL/SQL (Oracle)

    O bom e velho arquivo, é impressionante como lidamos com seus vários tipos durante todos os dias, bom hoje vamos mostrar um jeito simples de se escrever e ler arquivos apenas com a codificação nativa do Oracle. A primeira coisa a fazer é criar um diretório válido configurado no Oracle, e permissões de acesso a esse diretório para o usuário de banco onde faremos o exemplo, sendo assim suponhamos que nosso usuário de banco se chame programero, e nosso diretório real esteja em c:\programero, então logado como SYSTEM devemos executar os seguintes comandos: 1: -- cria diretorio 2: create or replace directory DIR_PROGRAMERO as ' C:\PROGRAMERO '; 3: -- concede permissão de escrita e leitura para nosso usuário 4: grant read , write on directory DIR_PROGRAMERO to PROGRAMERO; Para escrever, basicamente precisamos apenas saber onde esse arquivo ficará, no nosso caso no diretório criado acima, segue o código de escrita: 1: declare 2: -- nosso handler 3: v_a...

    Centralizar Texto em Edit

    Como todos sabemos o Edit mantém todo texto digitado a esquerda, o que não fica bem quando o usamos para a entrada de números, pois bem, o exemplo abaixo apresenta uma alternativa para centralizar um determinado valor dentro de um Edit: procedure EditChange(Sender: TObject); var vl_label : TLabel; //variável do tipo Label begin vl_label := TLabel.Create(self); //criamos um label WITH vl_label DO BEGIN Font.Name := TEdit(sender).Font.Name; //pegamos a fonte usada no edit Caption := TEdit(sender).Text; //pegamos o conteúdo do edit SendMessage(TEdit(sender).Handle, EM_SETMARGINS, EC_LEFTMARGIN, (TEdit(sender).Width-vl_label.Width) div 2); //centraliza no label e retorna para o edit END ; vl_label.Free; end ;

    Funções de Data e Hora (Delphi)

    É muito comum nos depararmos no dia a dia com a necessidade de manipular datas e horas, seja para um calculo de permanência, dias de atraso enfim, é praticamente escapar de alguma situação que necessite desse tipo de controle. Assim como a necessidade e se utilizar algum recurso para manipular as datas e horas de alguma maneira e freqüente, as duvidas de como o faze-lo também é, basta um breve olhar em qualquer fórum especializado e lá está, alguma duvida relacionada, por isso decidi falar um pouco sobre uma unit muito poderosa chamada DateUtils para a manipulação de data e hora, com um grande numero de métodos e classes que facilitam a vida de qualquer um. Alguns exemplos: CompareDate(constA, B: TDateTime): TValueRelationship; Compara apenas a data de dois valores (do tipo TDateTime) retornando: LessThanValue O primeiro valor é menor que o segundo EqualsValue Os valores são iguais GreaterThanValue O primeiro valor é maior que o segundo CompareDateTime(const A, B: TD...