O autor selecionou a Tech Education Fund para receber uma doação como parte do programa Write for DOnations.
O Docker é um aplicativo de código aberto que permite que os administradores criem, gerenciem, implantem e repliquem aplicativos usando contêineres. Os contêineres podem ser considerados como um pacote que abriga dependências que um aplicativo precisa para executar no nível do sistema operacional. Isso significa que cada aplicativo implantado usando o Docker vive em um ambiente próprio e seus requisitos são tratados separadamente.
O Flask é um microframework Web que é construído em Python. Ele é chamado de microframework porque não precisa de ferramentas específicas ou plugins para funcionar. O framework Flask é leve e flexível e, ainda sim, altamente estruturado, tornando-o preferido em relação a outros frameworks.
Implantar um aplicativo Flask com o Docker permitirá que você replique o aplicativo em diferentes servidores com uma reconfiguração mínima.
Neste tutorial, você criará um aplicativo Flask e irá implantá-lo com o Docker. Este tutorial também irá tratar sobre como atualizar um aplicativo após a implantação.
Para seguir este tutorial, você precisará do seguinte:
Para começar, você criará uma estrutura de diretórios que irá reter seu aplicativo Flask. Neste tutorial será criado um diretório chamado TestApp
em /var/www
, mas é possível modificar o comando para nomeá-lo como quiser.
- sudo mkdir /var/www/TestApp
Vá até o diretório TestApp
recém-criado:
- cd /var/www/TestApp
Em seguida, crie a estrutura base da pasta para o aplicativo Flask:
- sudo mkdir -p app/static app/templates
A sinalização -p
indica que o mkdir
criará um diretório e todos os diretórios pais que não existam. Neste caso, o mkdir
criará o diretório pai app
enquanto cria os diretórios static
e templates
.
O diretório app
abrigará todos os arquivos relacionados ao aplicativo Flask como suas visualizações e blueprints (planos gráficos). As visualizações são o código que você escreve para responder aos pedidos para seu aplicativo. Os Blueprints criam componentes do aplicativo e oferecem suporte aos padrões comuns dentro de um aplicativo ou de vários aplicativos.
O diretório static
é onde estão os ativos como imagens, CSS e arquivos JavaScript. O diretório templates
é onde você irá colocar os modelos HTML do seu projeto.
Agora que a estrutura base de pasta está completa, crie os arquivos necessários para executar o aplicativo Flask. Primeiro, crie um arquivo __init__.py
dentro do diretório app
. Esse arquivo informa o programa interpretador do Python que o diretório app
é um pacote e deve ser tratado como tal.
Execute o comando a seguir para criar o arquivo:
- sudo nano app/__init__.py
Os pacotes no Python permitem que você agrupe os módulos em namespaces ou hierarquisas lógicos. Esta abordagem permite que o código seja dividido em blocos individuais e gerenciáveis que desempenham funções específicas.
Em seguida, adicione código ao __init__.py
que criará uma instância de Flask e importará a lógica do arquivo views.py
, que você criará após salvar este arquivo. Adicione o código a seguir ao seu novo arquivo:
from flask import Flask
app = Flask(__name__)
from app import views
Uma vez adicionado tal código, salve e feche o arquivo.
Com o arquivo __init__.py
criado, está tudo pronto para criar o arquivo views.py
no diretório app
. Este arquivo conterá a maior parte da lógica do seu aplicativo.
- sudo nano app/views.py
Em seguida, adicione o código ao seu arquivo views.py
. Esse código retornará a string hello world!
para os usuários que visitarem sua Web page:
from app import app
@app.route('/')
def home():
return "hello world!"
A linha @app.route
acima da função é chamada de decorador. Os decoradores modificam a função que as segue. Neste caso, os decoradores avisam ao Flask qual URL irá desencadear a função home()
. O texto hello world
retornado pela função home
será exibido para o usuário no navegador.
Com o arquivo views.py
funcionando, estamos prontos para criar o arquivo uwsgi.ini
. O arquivo terá as configurações uWSGI para o nosso aplicativo. A uWSGI é uma opção de implantação do Nginx que é um protocolo e um servidor do aplicativo ao mesmo tempo; o servidor do aplicativo pode atender os protocolos uWSGI, FastCGI e HTTP.
Para criar esse arquivo, execute o seguinte comando:
- sudo nano uwsgi.ini
Em seguida, adicione o conteúdo seguinte ao seu arquivo para, assim, configurar o servidor do uWSGI:
[uwsgi]
module = main
callable = app
master = true
Este código define o módulo que irá servir o aplicativo Flask. Neste caso, trata-se do arquivo main.py
, referenciado aqui como main
. A opção callable
manda o uWSGI usar a instância app
exportada pelo aplicativo principal. A opção master
permite que seu aplicativo permaneça funcionando, de modo a reduzir o tempo de paralisação ao recarregar o aplicativo inteiro.
Em seguida, crie o arquivo main.py
, que é o ponto de entrada para o aplicativo. O ponto de entrada diz ao uWSGI como interagir com o aplicativo.
- sudo nano main.py
Em seguida, copie e cole o seguinte no arquivo. Este código irá importar a instância Flask chamada app
do pacote do aplicativo que foi criado anteriormente.
from app import app
Por fim, crie um arquivo requirements.txt
para especificar as dependências que o gerenciador de pacotes pip
instalará para sua implantação do Docker:
- sudo nano requirements.txt
Adicione a seguinte linha para adicionar o Flask como uma dependência:
Flask==1.0.2
Isso especifica a versão do Flask a ser instalada. No momento em que este tutorial está sendo escrito, a versão 1.0.2
é a versão do Flask mais recente. Você pode verificar as atualizações no site oficial do Flask.
Salve e feche o arquivo. Você configurou o aplicativo Flask com sucesso e está pronto para configurar o Docker.
Neste passo, serão criados dois arquivos, o Dockerfile
e o start.sh
, para criar sua implantação do Docker. O Dockerfile
é um documento de texto que contém os comandos usados para montar a imagem. O arquivo start.sh
é um script shell que irá construir uma imagem e criará um contêiner do Dockerfile
.
Primeiramente, crie o Dockerfile
.
- sudo nano Dockerfile
Em seguida, adicione a configuração desejada ao Dockerfile
. Estes comandos especificam como a imagem será construída e quais requisitos extras serão incluídos.
FROM tiangolo/uwsgi-nginx-flask:python3.6-alpine3.7
RUN apk --update add bash nano
ENV STATIC_URL /static
ENV STATIC_PATH /var/www/app/static
COPY ./requirements.txt /var/www/requirements.txt
RUN pip install -r /var/www/requirements.txt
Neste exemplo, a imagem do Docker será construída a partir de uma imagem existente, a tiangolo/uwsgi-nginx-flask
, que pode ser encontrada no DockerHub. Esta imagem do Docker em particular é uma boa escolha dentre as outras pois ela oferece suporte a uma ampla gama de versões do Python e imagens de SO.
As duas primeiras linhas especificam a imagem pai que será usada para executar o aplicativo e instalar o processador de comando bash, assim como o editor de texto nano
. O aplicativo também irá instalar o cliente git
para extração e envio para as plataformas de hospedagem com controle de versão tais como GitHub, GitLab e Bitbucket. A ENV STATIC_URL/static
é uma variável de ambiente específica para essa imagem do Docker. Ela define a pasta estática onde todos os ativos como imagens, arquivos CSS e arquivos JavaScript são atendidos.
As duas últimas linhas irão copiar o arquivo requirements.txt
para o contêiner, de modo a que ele possa ser executado e, em seguida, analisar o arquivo requirements.txt
para instalar as dependências especificadas.
Salve e feche o arquivo após adicionar sua configuração.
Com seu Dockerfile
funcionando, está quase tudo pronto para escrever seu script start.sh
que construirá o contêiner do Docker. Antes de escrever o script start.sh
, certifique-se primeiro de que você tenha uma porta aberta para usar na configuração. Para verificar se uma porta está livre, execute o seguinte comando:
- sudo nc localhost 56733 < /dev/null; echo $?
Se o resultado do comando acima for 1
, então a porta está livre e pode ser usada. Caso contrário, será necessário escolher uma porta diferente para usar no seu arquivo de configuração start.sh
.
Assim que você tiver encontrado uma porta aberta para usar, crie o script start.sh
:
- sudo nano start.sh
O script start.sh
é um script shell que irá construir uma imagem do Dockerfile
e criar um contêiner a partir da imagem do Docker resultante. Adicione sua configuração ao novo arquivo:
#!/bin/bash
app="docker.test"
docker build -t ${app} .
docker run -d -p 56733:80 \
--name=${app} \
-v $PWD:/app ${app}
A primeira linha é chamada de shebang. Ela especifica que este é um arquivo bash e ele será executado como comando. A linha seguinte especifica o nome que você quer dar à imagem e ao contêiner e salva o arquivo como uma variável chamada app
. A próxima linha de comando manda o Docker construir uma imagem a partir do seu Dockerfile
, localizado no diretório atual. Neste exemplo, a linha de código criará uma imagem chamada docker.test
.
As três últimas linhas criam um novo contêiner chamado docker.test
que está exposto na porta 56733
. Por fim, ele vincula o diretório atual ao diretório /var/www
do contêiner.
Você usará o sinalizador -d
para iniciar um contêiner no modo daemon ou para iniciar como um processo em segundo plano. Incluirá o sinalizador -p
para vincular uma porta no servidor a uma porta em particular no contêiner do Docker. Neste caso, você está ligando a porta 56733
à porta 80
no contêiner do Docker. O sinalizador -v
especifica um volume do Docker para ser montado no contêiner e, neste caso, você estará montando o diretório de projeto inteiro na pasta /var/www
no contêiner do Docker.
Execute o script start.sh
para criar a imagem do Docker e construir um contêiner a partir da imagem resultante:
- sudo bash start.sh
Assim que o script terminar de executar, use o comando a seguir para listar todos os contêineres em execução:
- sudo docker ps
Você receberá um resultado que mostra os contêineres:
OutputCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
58b05508f4dd docker.test "/entrypoint.sh /sta…" 12 seconds ago Up 3 seconds 443/tcp, 0.0.0.0:56733->80/tcp docker.test
Você verá que o contêiner docker.test
está em execução. Agora que ele está em execução, acesse o endereço IP na porta especificada no seu navegador: http://ip-address:56733
Você verá uma página parecida com a que segue:
Neste passo, seu aplicativo Flask foi implementado no Docker com sucesso. Em seguida, você usará modelos para mostrar o conteúdo aos usuários.
Os modelos são arquivos que mostram o conteúdo estático e dinâmico aos usuários que visitam seu aplicativo. Neste passo, você criará um modelo HTML para criar uma página inicial para o aplicativo.
Comece criando um arquivo home.html
no diretório app/template
:
- sudo nano app/templates/home.html
Adicione o código ao seu template. Este código irá criar uma página HTML5 que contém um título e algum texto nele.
<!doctype html>
<html lang="en-us">
<head>
<meta charset="utf-8">
<meta http-equiv="x-ua-compatible" content="ie=edge">
<title>Welcome home</title>
</head>
<body>
<h1>Home Page</h1>
<p>This is the home page of our application.</p>
</body>
</html>
Salve e feche o arquivo assim que tiver adicionado o seu modelo.
Em seguida, modifique o arquivo app/views.py
para atender o arquivo recém-criado:
- sudo nano app/views.py
Primeiramente, adicione a seguinte linha no início do seu arquivo para importar o método render_template
do Flask. Este método analisa um arquivo HTML para renderizar uma página da Web para o usuário.
from flask import render_template
...
No final do arquivo, você também irá adicionar uma nova rota para renderizar o arquivo do modelo. Este código especifica que os usuários recebem o conteúdo do arquivo home.html
sempre que visitam a rota /template
em seu aplicativo.
...
@app.route('/template')
def template():
return render_template('home.html')
O arquivo atualizado app/views.py
se parecerá com isto:
from flask import render_template
from app import app
@app.route('/')
def home():
return "Hello world!"
@app.route('/template')
def template():
return render_template('home.html')
Salve e feche o arquivo quando terminar.
Para que estas alterações passar a vigorar, será necessário parar e reiniciar os contêineres do Docker. Execute o comando a seguir para criar o contêiner novamente:
- sudo docker stop docker.test && sudo docker start docker.test
Visite seu aplicativo em http://your-ip-address:56733/template
para ver o novo modelo sendo mostrado.
Neste passo, você criou um arquivo modelo do Docker para atender os visitantes em seu aplicativo. No próximo passo, você verá como as alterações que você faz em seu aplicativo podem entrar em vigor sem a necessidade de reiniciar o contêiner do Docker.
Às vezes, você terá que fazer alterações no aplicativo, seja instalando novos requisitos, atualizando o contêiner do Docker ou do HTML e as alterações de lógica. Nesta seção, você irá configurar o touch-reload
para fazer essas alterações sem precisar reiniciar o contêiner do Docker.
O autoreloading do Python monitora todo o sistema de arquivos quanto a alterações e atualiza o aplicativo quando detecta uma mudança. Desencorajamos o uso do autoreloading em produção porque ele pode se tornar um recurso intensivo rapidamente. Neste passo, você usará o touch-reload
para monitorar as alterações em um arquivo em particular e recarregar quando o arquivo for atualizado ou substituído.
Para implementar isso, abra seu arquivo uwsgi.ini
:
- sudo nano uwsgi.ini
Em seguida, adicione a linha destacada ao final do arquivo:
module = main
callable = app
master = true
touch-reload = /app/uwsgi.ini
Ela especifica um arquivo que será modificado para desencadear o recarregamento de um aplicativo inteiro. Uma vez feitas as mudanças, salve e feche o arquivo.
Como uma demonstração, faça uma pequena alteração no seu aplicativo. Comece abrindo seu arquivo app/views.py
:
- sudo nano app/views.py
Substitua a string retornada pela função home
:
from flask import render_template
from app import app
@app.route('/')
def home():
return "<b>There has been a change</b>"
@app.route('/template')
def template():
return render_template('home.html')
Salve e feche o arquivo após fazer uma mudança.
Em seguida, se abrir a página inicial do seu aplicativo em http://ip-address:56733
, você verá que as mudanças não estão refletidas. Isso acontece porque a condição para que o recarregamento ocorra é uma alteração feita ao arquivo uwsgi.ini
. Para recarregar o aplicativo,utilize a opção touch
para ativar a condição:
- sudo touch uwsgi.ini
Recarregue a homepage do aplicativo em seu navegador novamente. Você verá que o aplicativo incorporou as mudanças:
Neste passo, você configurou uma condição touch-reload
para atualizar seu aplicativo após fazer alterações.
Neste tutorial, você criou e implantou um aplicativo Flask em um contêiner do Docker. Você também configurou o touch-reload
para atualizar seu aplicativo sem a necessidade de reiniciar o contêiner.
Com o seu novo aplicativo em Docker, agora é possível dimensionar com facilidade. Para aprender mais sobre como usar o Docker, verifique sua documentação oficial.
Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.
This textbox defaults to using Markdown to format your answer.
You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!
Sign up for Infrastructure as a Newsletter.
Working on improving health and education, reducing inequality, and spurring economic growth? We'd like to help.
Get paid to write technical tutorials and select a tech-focused charity to receive a matching donation.