Introdução
Docker é uma plataforma de contêineres de código aberto. É um ambiente padronizado, leve, virtualizado, portátil e definido por software que permite que o software seja executado de forma isolada de outros softwares em execução na máquina host física. O Docker oferece uma alternativa leve às máquinas virtuais. Ao mesmo tempo, oferece portabilidade, desempenho, agilidade e escalabilidade de aplicativos. Para um guia abrangente sobre o ecossistema Docker, dê uma olhada em nossa visão geral detalhada sobre conteinerização com o Docker.
Flask é um framework web minimalista de código aberto construído com Python. Algumas das excelentes características do Flask são o fato de ser leve, flexível e altamente estruturado. Além disso, não requer ferramentas ou plug-ins específicos para ser executado.
A combinação de Flask e Docker oferece um aplicativo leve, flexível e escalável. Você pode implantá-lo em vários servidores e infraestruturas, graças à natureza portátil dos contêineres Dockerizados. O foco deste tutorial é mostrar como implantar um aplicativo Flask com o Docker. Também demonstraremos como garantir que as atualizações futuras do seu aplicativo entrem em vigor.
Pré-requisitos
Este será um tutorial prático, e você deve criar um ambiente que permita acompanhar as etapas:
- Você deve ter uma instalação do Ubuntu 20.04 como seu ambiente operacional inicial. Você também precisa criar um usuário não-root com privilégios sudo.
- Além disso, você precisa instalar o Docker. Temos um tutorial sobre como instalar e operar o Docker no Ubuntu. Siga as etapas 1, 2, 3 e 4. Isso deve funcionar para qualquer distribuição Ubuntu.
- Finalmente, você precisa ter o Nginx instalado. Siga nosso tutorial sobre instalação do Nginx no Ubuntu.
Agora, vamos começar!
Etapa 1: Preparar o Aplicativo Flask
Começaremos criando um diretório que conterá nosso aplicativo Flask. Você pode escolher o nome de diretório que preferir. No entanto, para este tutorial, nós o chamaremos de flask_demo. Salvaremos os arquivos do projeto dentro do diretório /var/www , que geralmente é o diretório ao qual o Ubuntu permite acesso à internet pública por padrão. Primeiro, execute os seguintes comandos para criar o diretório e navegar até ele:
|
1 2 3 |
sudo mkdir /var/www/flask_demo cd /var/www/flask_demo |
Dentro deste diretório raiz do nosso projeto, criaremos a estrutura de pastas base de um aplicativo Flask. Em seguida, execute o seguinte comando para criar a estrutura base, adicionando a flag -p para criar todas as pastas pai ao longo do caminho:
|
1 |
sudo mkdir -p app/static app/templates |
A pasta app contém todos os arquivos relacionados a um aplicativo Flask, incluindo views e blueprints. As views contêm o código que você escreve para responder às requisições que chegam ao seu aplicativo. Os blueprints ajudam a criar componentes de aplicativo e oferecem suporte a padrões comuns em aplicativos Flask.
A pasta apropriadamente nomeada static contém recursos estáticos, como imagens, arquivos CSS e JavaScript. O diretório templates contém todos os templates HTML do projeto.
Agora podemos começar a escrever os arquivos necessários para inicializar um aplicativo Flask. Comece criando um arquivo chamado __init__.py dentro do diretório app para dizer ao Python interpretador que o diretório app deve ser tratado como um pacote. Execute o seguinte comando no seu terminal para abrir o arquivo com o editor nano:
|
1 |
sudo nano app/__init__.py |
Usamos pacotes em Python para agrupar módulos em namespaces ou hierarquias lógicas. A modularização permite dividir o código em blocos individuais e gerenciáveis que realizam funções definidas.
Depois disso, dentro do arquivo __init__.py aberto no seu editor, adicione o seguinte trecho de código para iniciar a instância do Flask e importar a lógica do views.py que você criará nas próximas etapas:
|
1 2 3 4 5 |
from flask import Flask app = Flask(__name__) from app import views |
Quando terminar, pressione Ctrl + O e ENTER para salvar o arquivo, depois feche-o com Ctrl + X. Em seguida, vamos criar o views.py dentro do app diretório. O views.py arquivo conterá a maior parte da lógica da aplicação:
|
1 |
sudo nano app/views.py |
Dentro do arquivo, adicione o seguinte trecho de código. Este código exibirá uma string simples para mostrar que seu aplicativo está em execução quando os usuários visitarem seu site:
|
1 2 3 4 5 |
from app import app @app.route('/') def home(): return "Nosso aplicativo Flask está em execução!" |
Neste arquivo, começamos importando a instância do aplicativo Flask. Depois, precisamos adicionar uma linha para definir a rota: @app.route(/). A linha @app.route(/) é referida como um decorador no Flask. Você pode usar decoradores para injetar funcionalidades adicionais em uma ou mais funções. Neste caso, estamos passando uma chamada para a rota / para a função home. Quando um usuário visitar esta rota, ele verá o texto: "Nosso aplicativo Flask está em execução!".
Em seguida, você criará o arquivo uwsgi.ini para conter as uWSGI configurações para a aplicação. uWSGI é uma opção de implantação para o Nginx que serve como um protocolo e um servidor de aplicação. Execute o seguinte comando para criar o arquivo no diretório raiz do projeto com o editor nano:
|
1 |
sudo nano uwsgi.ini |
Dentro do arquivo aberto, adicione o seguinte trecho de código:
|
1 2 3 4 |
[uwsgi] module = main callable = app master = true |
Este arquivo contém algumas diretivas. Definimos o propósito delas abaixo:
- module – define o módulo a partir do qual a aplicação Flask será servida. Definimos o módulo como main, referenciando o arquivo main.py no diretório raiz. Criaremos este arquivo no próximo passo.
- callable – direciona o uWSGI a usar a instância app exportada da aplicação.
- master – garante que a aplicação continue em execução para minimizar o tempo de inatividade durante a reinicialização de toda a aplicação.
Salve e feche o arquivo quando terminar.
Agora você pode criar o arquivo main.py para determinar o ponto de entrada para a sua aplicação. O uWSGI lerá este arquivo para saber como interagir com a aplicação. Execute o seguinte comando para criar o arquivo main.py com o nano dentro do diretório raiz do seu projeto:
|
1 |
sudo nano main.py |
Dentro do arquivo, adicione a seguinte linha que importará a instância do Flask que foi criada no pacote da aplicação:
|
1 |
from app import app |
A última coisa que você fará neste passo é definir as dependências necessárias para a aplicação ser executada. Definiremos essas dependências dentro de um arquivo chamado dependencies.txt. Quando o Docker construir a imagem da sua aplicação, ele executará um comando do gerenciador (de pacotes pip) para instalar as dependências. Abra o arquivo no diretório raiz com o seguinte comando:
|
1 |
sudo nano dependencies.txt |
Até este ponto em nosso projeto, queremos apenas uma dependência: Flask. Portanto, podemos adicionar a seguinte linha para referenciar a versão correta do Flask que queremos para o nosso projeto:
|
1 |
Flask==2.0.1 |
Estamos optando pela versão do Flask version 2.0.1 como a dependência. É a versão mais recente no momento da redação deste tutorial. Você pode descobrir mais sobre as várias versões na página Flask Changes . Isso conclui a configuração da aplicação Flask. Agora vamos preparar as configurações do Docker para a implantação.
Step 2: Configure Docker
Para configurar uma implantação do Docker, criaremos dois arquivos, Dockerfile e start.sh. O Dockerfile contém linhas declarativas que compõem uma imagem Docker. O start.sh é um script shell básico para construir a imagem e iniciar o contêiner a partir do Dockerfile. Enquanto estiver no diretório raiz do projeto, execute o seguinte comando para criar o Dockerfile:
|
1 |
sudo nano Dockerfile |
Este arquivo contém as configurações necessárias para uma imagem Docker. Em seguida, adicione o seguinte trecho de código para especificar as dependências e como construir a imagem:
|
1 2 3 4 5 6 7 8 9 10 11 |
FROM tiangolo/uwsgi-nginx-flask:python3.6-alpine3.7 RUN apk --update add bash nano git ENV STATIC_URL /static ENV STATIC_PATH /var/www/app/static COPY ./dependencies.txt /var/www/dependencies.txt RUN pip install -r /var/www/dependencies.txt |
A primeira linha em um Dockerfile define a imagem base a partir da qual estamos construindo nossa imagem. Neste caso, construiremos com base no tiangolo/uwsgi-nginx-flask, disponível no DockerHub. Escolhemos esta imagem específica porque ela suporta muitas versões do Python.
Também especificamos que queremos atualizar a imagem. Em seguida, precisamos adicionar o bash comando processo , o nano texto editor, e o git cliente para fazer pull e push de código-fonte de repositórios de controle de versão como GitHub, Bitbucket, ou Gitlab. As linhas com ENV especificam variáveis de ambiente a serem usadas no contêiner.
O comando COPY copia as dependências para dentro do contêiner. O comando RUN invoca o gerenciador de pacotes pip para analisar o arquivo dependencies.txt e instalar as dependências. Salve e feche o arquivo quando terminar de editar.
Em seguida, você criará o script start.sh. Este script incluirá comandos do Docker para construir e executar a imagem. Embora você possa executar esses comandos progressivamente no terminal, achamos que é mais limpo adicioná-los a um script shell e apenas invocá-lo do terminal com um único comando.
Antes de podermos definir o conteúdo deste arquivo, devemos primeiro estabelecer uma porta livre que outros serviços não estejam usando. Usaremos a porta 45644. No entanto, você pode escolher uma porta diferente. Execute a seguinte linha para verificar se a porta está livre:
|
1 |
sudo nc localhost 45644 < /dev/null; echo $? |
Dependendo da porta que você escolheu, se a saída do comando acima for 1, então ela está livre. Caso contrário, você terá que escolher outra porta e tentar o comando novamente:

Como estabelecemos uma porta livre, agora podemos criar o arquivo com o nano dentro do diretório raiz do projeto executando o seguinte comando:
|
1 |
sudo nano start.sh |
Dentro deste arquivo, adicione o seguinte trecho de código:
|
1 2 3 4 5 6 7 |
#!/bin/bash app_name="docker-flask-demo" docker build -t ${app_name} . docker run -d -p 45644:80 --name=${app_name} -v $PWD:/app ${app_name} |
A primeira linha, referida como shebang, especifica que este é um arquivo bash e deve ser executado como comandos. A segunda linha declara uma variável chamada app_name. Usamos essa variável para definir os nomes da imagem e do contêiner. A terceira linha instrui o Docker a construir a imagem com base na definição do Dockerfile no diretório atual. A imagem será chamada docker-flask-demo de acordo com a variável.
A última linha cria um contêiner chamado docker-flask-demo de acordo com a variável que definimos. A flag -d mantém o contêiner rodando em segundo plano em um estado desanexado (detached) após a execução do comando terminar. A flag -p vincula uma porta no servidor a uma porta específica no contêiner. Neste caso, estamos mapeando a porta 45644 na máquina hospedeira para a porta 80 que o Docker exporá no contêiner.
We use the -v para especificar um volume do Docker a ser montado no contêiner. A variável $PWD é uma variável padrão do Linux que contém o caminho para o diretório atual em que você está em um determinado momento:

No nosso caso, estamos montando todo o diretório do projeto no diretório /var/www do contêiner. A configuração do Docker agora está pronta. Você pode construir a imagem e iniciar o contêiner com base na imagem construída executando o seguinte comando:
|
1 |
sudo bash start.sh |
Aguarde a execução do script terminar e, em seguida, execute o seguinte comando Docker para listar todos os contêineres em execução:
|
1 |
sudo docker ps |
The output will display running containers:

Você deverá ver o nosso contêiner com o nome docker-flask-demo na lista de contêineres em execução. Encontre o IP público do seu servidor e acesse-o no seu navegador na porta especificada: http://your-server-public-ip:45644.
Você deverá ver uma saída semelhante:

Se você vir o que está acima no seu navegador, significa que implantou com sucesso uma aplicação Flask. Em seguida, modificaremos arquivos e serviremos conteúdo aos usuários por meio de templates.
Passo 3: Servir Conteúdo por meio de Arquivos de Template
No Flask, Templates são usados para exibir conteúdo estático e dinâmico aos visitantes do site. Mostraremos como criar um template HTML e servi-lo aos seus usuários quando eles visitarem uma determinada rota. Por exemplo, pode ser uma página Inicial (Home) ou uma página Sobre (About).
Execute o seguinte comando no seu terminal para criar um arquivo index.html no diretório app/templates :
|
1 |
sudo nano app/templates/index.html |
Em seguida, adicione o seguinte trecho de código ao arquivo:
|
1 2 3 4 5 6 7 8 9 10 11 12 |
<!DOCTYPE html> <html lang="pt"> <head> <meta charset="UTF-8"> <title>Flask Demo</title> </head> <body> <h2>Você está em Home</h2> <p>Bem-vindo à página de demonstração do Flask com Docker</p> </body> </html> |
Salve e feche o arquivo quando terminar. Além disso, crie outra página, vamos chamá-la de página Sobre (About), com o seguinte comando:
|
1 |
sudo nano app/templates/about.html |
Adicione o seguinte trecho de código ao arquivo:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 |
<!DOCTYPE html> <html lang="pt"> <head> <meta charset="UTF-8"> <title>Sobre o Flask Demo</title> </head> <body> <h2>Página Sobre</h2> <p>Este foi um projeto de demonstração. . Ele mostra como to construir um app Flask com Docker e Nginx.</p> <p>Você pode adicionar quantas páginas e arquivos desejaras you like</p> </body> </html> |
Salve e feche o arquivo quando terminar. Em seguida, modifique o arquivo app/views.py para referenciar os templates, bem como as rotas para as páginas reais:
|
1 |
sudo nano app/views.py |
Modifique o arquivo para que ele fique assim:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
from flask import render_template from app import app @app.route('/') def home(): return "Nossa aplicação Flask está rodando!" @app.route('/index') def index(): return render_template('index.html') @app.route('/about') def about(): return render_template('about.html') |
Salve e feche o arquivo quando terminar. As alterações feitas não entrarão em vigor até que você pare e reinicie o contêiner. Execute os seguintes comandos do Docker para parar e iniciar o contêiner. Anote o nome do contêiner conforme definimos anteriormente:
|
1 |
sudo docker stop docker-flask-demo && sudo docker start docker-flask-demo |
Assim que o contêiner estiver ativo e em execução, visite a página inicial e a página Sobre para ver alguns dos novos conteúdos:
|
1 |
Página Home: http://your-server-public-ip:45644/index |

|
1 |
Página Sobre: http://your-server-public-ip:45644/about |

Até agora, você criou um aplicativo Flask que pode servir conteúdo para os visitantes do seu site. Aqui está a estrutura de arquivos do projeto:

Você provavelmente notou que tivemos que reiniciar o contêiner Docker para que ele aplicasse as novas alterações. Na próxima etapa, automatizaremos isso para garantir menos tempo de inatividade.
Etapa 4: Configurar as Atualizações dos Arquivos do Aplicativo para Recarregar Automaticamente
Frequentemente fazemos alterações em um aplicativo, para melhorar a lógica, as interfaces de usuário ou adicionar algumas dependências. Para que tais alterações entrem em vigor, pode ser necessário reiniciar o contêiner Docker. Felizmente, uWSGI tem um recurso chamado touch-reload para recarregar um script Python sem reiniciar o contêiner.
Pronto para uso, o Python possui um recurso de auto--recarregamento que monitora todo o sistema de arquivos em busca de alterações e atualiza o aplicativo quando ocorre uma alteração. Embora o recarregamento automático seja bom para minimizar o tempo de inatividade, ele pode consumir muitos recursos. Portanto, não é recomendado para ambientes de produção.
Vejamos como você pode usar o touch-reload para monitorar alterações em um arquivo específico e recarregar o aplicativo quando houver alterações. Modifique o arquivo uwsgi.ini com o editor nano:
|
1 |
sudo nano uwsgi.ini |
Adicione a linha destacada para que fique assim:
|
1 2 3 4 5 |
[uwsgi] module = main callable = app master = true touch-reload = /app/uwsgi.ini |
Salve e feche o arquivo quando terminar. A linha adicionada especificou um arquivo que será modificado para acionar o recarregamento do aplicativo. No entanto, para que essa condição seja ativada para modificações futuras, você deve primeiro reiniciar o contêiner:
|
1 |
sudo docker stop docker-flask-demo && sudo docker start docker-flask-demo |
Agora você pode modificar o arquivo app/views.py para demonstrar como funciona o recarregamento automático:
|
1 |
sudo nano app/views.py |
Altere a string retornada pela função home conforme destacado:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
from flask import render_template from app import app @app.route('/') def home(): return "<h3>Algumas alterações em nosso aplicativo Flask para recarregamento automático!</h3>" @app.route('/index') def index(): return render_template('index.html') @app.route('/about') def about(): return render_template('about.html') |
Salve e feche o arquivo assim que terminar.
Abra a página inicial do seu aplicativo no navegador: http://your-server-public-ip:45644.
Você ainda não verá nenhuma alteração. Isso ocorre porque a condição touch-reload detecta uma alteração no arquivo uwsgi.ini . Você pode usar touch para ativar a condição, recarregando assim todo o aplicativo com o seguinte comando:
|
1 |
sudo touch uwsgi.ini |
Agora, se você recarregar a página inicial, verá as novas alterações exibidas:

No futuro, se você fizer novas alterações, precisará apenas executar o comando sudo touch uwsgi.ini e todo o aplicativo será recarregado com menos tempo de inatividade. Isso nos traz ao final deste tutorial.
Conclusão
Neste tutorial, você implementou e implantou um aplicativo Flask com imagens e contêineres Docker. Para minimizar o tempo de inatividade, evitando a necessidade de reiniciar o contêiner, você configurou touch-reload para escutar alterações em um arquivo específico e recarregar automaticamente todo o aplicativo. Você finalmente testou tudo isso no navegador para garantir que funciona.
O Docker garante implantações mais rápidas e permite o dimensionamento fácil de aplicativos. Se você quiser saber mais sobre os vários comandos do Docker, dê uma olhada neste tutorial sobre como instalar e usar o Docker no Ubuntu.
Para mais recursos sobre o Docker em nosso blog, você pode conferir o seguinte:
- Tecnologia de Conteinerização: Tipos e Usos de Diferentes Contêineres na Plataforma PaaS da CloudSigma
- Como compartilhar dados entre um contêiner Docker e um host
- Instalando e Configurando o Docker no CentOS 7
- Implantando Laravel, Nginx e MySQL com Docker Compose
- Limpar Recursos do Docker – Imagens, Contêineres e Volumes
Feliz Computação!
Comentários
Nenhum comentário ainda. Seja o primeiro.