Como criar e implementar um aplicativo Python?
Python é uma linguagem de programação gratuita e de código aberto que tem muitas aplicações. Ela foi criada por Guido Van Rossum em 1991 e, desde então, evoluiu para uma das linguagens de programação mais populares.
Neste artigo, falaremos sobre Python, suas vantagens, desvantagens, casos de uso e opções de implantação. Além disso, demonstraremos como criar, dockerizar e implantar um aplicativo Python simples nos contêineres do Back4app.
Continue lendo para saber mais sobre como criar e implantar um projeto Python.
Contents
- 1 Visão geral do Python
- 2 Vantagens do Python
- 3 Limitações do Python
- 4 Opções de implantação do Python
- 5 Processo de implantação do Python
- 6 Conclusão
Visão geral do Python
Python é uma linguagem de programação de alto nível para fins gerais. Ela é interpretada, tipada dinamicamente e pode ser usada tanto para scripts quanto para programação. Os desenvolvedores geralmente descrevem Python como uma linguagem com “baterias incluídas” devido à sua extensa biblioteca padrão.
A linguagem apareceu pela primeira vez em 1991 e, desde então, tornou-se uma das linguagens de programação mais populares e adoradas devido à sua sintaxe simples e legível. Os principais princípios de design do Python são abordados em The Zen of Python, escrito por Tim Peters.
O Python tem uma enorme comunidade de desenvolvedores e pacotes prontos para uso. Atualmente, o Python é usado em praticamente qualquer lugar: na administração de servidores, na computação científica, no aprendizado de máquina, na criação de APIs RESTful e assim por diante. O Python pode ser considerado uma das habilidades essenciais de um desenvolvedor moderno.
Vantagens do Python
Fácil de usar
Python é uma das linguagens mais fáceis de usar e aprender. Sua curva de aprendizado é quase inexistente porque sua principal filosofia de design enfatiza a simplicidade e a legibilidade do código. A linguagem Python também é muito usada na educação, pois é uma ótima ferramenta para aprender conceitos básicos de programação.
Desenvolvimento rápido
Outra grande vantagem do Python é que ele permite o desenvolvimento rápido. É uma linguagem excelente para criar protótipos e realizar o trabalho rapidamente. Ao usar Python, você não precisa se preocupar com sintaxe complexa, alocação de memória etc. Em vez disso, pode se concentrar no aplicativo.
Versátil
Python é uma das linguagens de programação mais versáteis. Ela é usada em uma ampla gama de setores e campos. Alguns dos campos em que o Python é usado incluem contabilidade, pesquisa científica, ciência de dados, desenvolvimento da Web, desenvolvimento de jogos e automação.
Portátil
Python é uma linguagem portátil, pois é interpretada (como Java) e não compilada (como C++). Isso significa que o código escrito em uma plataforma pode ser facilmente transferido para outra plataforma. Isso torna o Python uma escolha popular para desenvolvedores que precisam oferecer suporte a várias plataformas, incluindo Windows, macOS, Linux e Android.
Bibliotecas extensas
A linguagem de programação Python é apoiada por uma enorme comunidade de desenvolvedores. Há uma biblioteca para quase tudo que você possa imaginar. Algumas das bibliotecas mais populares incluem:
- Desenvolvimento web(Django, Flask, FastAPI)
- Aprendizado de máquina e ciência de dados(TensorFlow, PyTorch)
- Visão computacional(OpenCV, Pillow, Scikit-image)
- Computação científica(NumPy, SciPy)
- Interface gráfica do usuário(Qt, GTK)
E isso mal arranha a superfície. Se quiser ver uma lista completa de pacotes Python incríveis, dê uma olhada no awesome-python no GitHub.
Dinamicamente tipado
Python é uma linguagem tipada dinamicamente, o que significa que você não precisa declarar o tipo de dados ao criar variáveis. O tipo de variável só é atribuído quando o código está sendo executado.
Por melhor que sejam, as linguagens tipadas dinamicamente podem, às vezes, ser uma faca de dois gumes. Em geral, elas são mais propensas a erros e têm um nível mais baixo de controle de memória em comparação com as linguagens tipadas estaticamente.
Extensível
Se os requisitos do seu projeto incluírem tarefas de computação pesada, você poderá escrevê-las em linguagens mais rápidas, como C ou C++, e invocá-las a partir do código Python.
Para saber mais sobre como invocar C/C++ a partir do Python, consulte este excelente artigo.
Limitações do Python
Desempenho ruim
O Python é relativamente lento em comparação com outras linguagens de programação. Os dois fatores que mais prejudicam seu desempenho são o fato de o Python ser uma linguagem interpretada e tipada dinamicamente. Se os requisitos de seu projeto incluem computação pesada ou multi-threading, o Python talvez não seja a ferramenta mais adequada. Será muito melhor usar C, C++ ou alguma outra linguagem compilada.
Memória intensiva
Os programas Python, comparados aos programas escritos em linguagens com tipagem estática, geralmente consomem mais memória e oferecem um nível menor de controle sobre a memória. Isso pode ser um pouco problemático se seus aplicativos precisarem ser eficientes em termos de memória.
Propenso a erros de tempo de execução
O Python, por ser uma linguagem interpretada, é mais propenso a erros de tempo de execução. Como não há processo de compilação, os erros não podem ser descobertos em tempo de compilação. Além disso, o Python é tipado dinamicamente, o que significa que os desenvolvedores podem alterar o tipo de uma variável a qualquer momento. Isso às vezes pode levar a erros e exige que os desenvolvedores estejam atentos aos tipos de variáveis.
Bloqueio global do intérprete (GIL)
O Global Interpreter Lock (GIL) em Python é um mecanismo que garante que apenas um thread execute o bytecode Python por vez. Embora isso simplifique a implementação da linguagem e ofereça alguns benefícios de desempenho para determinados tipos de programas, também limita a capacidade de utilizar totalmente os processadores de vários núcleos em aplicativos vinculados à CPU.
Não otimizado para acesso a banco de dados
Trabalhar com bancos de dados em aplicativos Python pode ser mais desafiador devido à falta de interfaces poderosas e fáceis de usar, como o Java Database Connectivity (JDBC). Embora o Python ainda possa ser usado para operações de banco de dados que envolvam tarefas simples de leitura e gravação, ele pode não ser a opção mais adequada para aplicativos que precisem trabalhar com bancos de dados grandes e complexos.
Opções de implantação do Python
Os aplicativos Python podem ser implantados em várias plataformas de nuvem. Em geral, podemos dividi-los nas três categorias a seguir:
- Infraestrutura como serviço (IaaS)
- Plataforma como serviço (PaaS)
- Contêineres como serviço (CaaS)
A IaaS é a menos abstraída e a CaaS é a mais abstraída. Há também a hospedagem convencional, mas tenho certeza de que você já está familiarizado com isso.
Infraestrutura como serviço (IaaS)
Infraestrutura como serviço ou IaaS é um modelo de computação em nuvem no qual um fornecedor terceirizado oferece recursos de computação virtualizados, como servidores, armazenamento, sistemas operacionais e redes pela Internet. Os recursos fornecidos podem então ser gerenciados por meio de painéis avançados ou APIs de alto nível, dando aos clientes controle total sobre toda a infraestrutura.
Os principais benefícios da IaaS são escalabilidade, economia de custos, maior suporte, desempenho e segurança. A estrutura de pagamento adotada pela maioria dos provedores de IaaS é baseada em um sistema de pagamento conforme o uso, em que você só paga pelos recursos que utiliza.
O IaaS é o modelo de computação em nuvem mais flexível e continua sendo a opção mais popular desde seu lançamento no início da década de 2010. A maior desvantagem desse modelo é que o cliente é totalmente responsável por seus aplicativos, sistemas operacionais e dados.
Os exemplos mais populares de IaaS são:
- Microsoft Azure
- Serviços da Web da Amazon (AWS)
- Plataforma de nuvem do Google (GCP)
- Infraestrutura de nuvem da Oracle (OCI)
- DigitalOcean
Plataforma como serviço (PaaS)
A PaaS (Platform as a Service) é um serviço de computação em nuvem que fornece aos usuários um ambiente de nuvem para criar, gerenciar e fornecer aplicativos. A PaaS oferece ferramentas pré-criadas para desenvolvimento, personalização e teste de aplicativos. Com a PaaS, os usuários podem se concentrar em seu aplicativo, pois o provedor de serviços cuida da infraestrutura subjacente, incluindo servidores, sistemas operacionais, software, backups e muito mais.
Os benefícios da PaaS incluem maior velocidade de lançamento no mercado, maior segurança, custo-benefício, escalabilidade, alta disponibilidade e, em geral, exigem menos código. No entanto, há algumas desvantagens. As três principais desvantagens são a falta de flexibilidade, a falta de controle e o risco de dependência do fornecedor. No entanto, a PaaS ainda permite que os usuários criem aplicativos mais rapidamente e com menos sobrecarga de gerenciamento.
Os fornecedores de PaaS incluem:
- Heroku
- Fly.io
- Renderizar
- Plataforma de aplicativos da DigitalOcean
- Serviço de aplicativos do Microsoft Azure
Contêineres como serviço (CaaS)
Os contêineres como serviço (CaaS) são um modelo de computação em nuvem que permite que as organizações carreguem, executem, dimensionem e gerenciem seus contêineres por meio do uso da tecnologia de virtualização de contêineres. Os fornecedores de CaaS abstraem grande parte do trabalho necessário, como a infraestrutura, os sistemas operacionais, o software, os mecanismos de conteinerização e muito mais.
O melhor dos contêineres é que, uma vez que seu aplicativo esteja em contêineres, você pode implantá-lo em praticamente qualquer lugar e é garantido que ele se comporte da mesma maneira. Se houver necessidade, você pode mudar de um fornecedor de CaaS para outro. Normalmente, os clientes de CaaS são cobrados por contêiner (com base nas especificações do contêiner).
Em geral, o CaaS é mais caro em comparação com o IaaS e o PaaS, oferece um nível menor de flexibilidade e controle e exige algum trabalho inicial, por exemplo, colocar o aplicativo em contêineres e assim por diante. No entanto, é um dos modelos de computação em nuvem mais fáceis de usar depois que seu aplicativo é colocado em contêineres.
Alguns dos melhores provedores de CaaS incluem:
- Contêineres do Back4app
- Amazon Elastic Container Service (ECS)
- Mecanismo do Google Kubernetes (GKE)
- Red Hat OpenShift
Para saber mais sobre contêineres, consulte O que são contêineres na computação em nuvem?
Processo de implantação do Python
Nesta seção do tutorial, demonstraremos como criar e implantar um aplicativo Python simples, passo a passo. O aplicativo Web será implementado usando a estrutura do Flask e implantado nos contêineres do Back4app.
Pré-requisitos
- Experiência com Python e Flask
- Conhecimento básico do Docker
- Python versão 3.8 ou posterior e Docker Desktop instalado
O que é o Back4app Containers?
O Back4app Containers é uma plataforma gratuita e de código aberto que permite implantar e dimensionar aplicativos usando contêineres distribuídos globalmente.
Com o Back4app Containers, você pode se concentrar na criação de seu software e no envio rápido dele, sem precisar se preocupar com o DevOps.
A plataforma é totalmente integrada ao GitHub e vem equipada com um sistema CI/CD integrado. Ao usar o Back4app Containers, você poderá colocar seu aplicativo on-line em questão de minutos.
Por que usar os contêineres do Back4app?
- Integra-se bem com o GitHub
- Dimensionamento e implementações sem tempo de inatividade
- Extremamente fácil de usar
- Excelente suporte ao cliente
Introdução ao projeto
Neste artigo, criaremos e implantaremos uma API RESTful simples que servirá como uma lista de tarefas. A API da Web permitirá que os usuários executem operações CRUD básicas, como adicionar tarefas, excluir tarefas, marcá-las como concluídas e assim por diante.
Primeiro, trabalharemos no código-fonte e, depois, o implantaremos em um contêiner Flask do Back4app. O aplicativo da Web será implementado usando a estrutura da Web do Flask.
Sinta-se à vontade para pular a seção “Code App” e seguir com seu próprio projeto Python.
Aplicativo de código
Projeto Init
Comece criando um diretório dedicado para o aplicativo Flask e navegando até ele:
$ mkdir flask-todo
$ cd flask-todo
Crie um ambiente virtual e ative-o:
$ python3 -m venv venv && source venv/bin/activate
Em seguida, instale o Flask via pip:
$ (venv) pip install Flask==2.2.2
Para garantir que tudo funcione, vamos substituir o conteúdo do app.py pelo seguinte:
# app.py
from flask import Flask
app = Flask(__name__)
@app.route('/')
def index_view():
return {
'detail': 'Hello world'
}
Esse código inicializa o Flask e cria um endpoint simples que retorna uma mensagem.
Inicie o servidor com:
$ (venv) flask run
Por fim, navegue até http://localhost:5000/ em seu navegador favorito. Você deverá ver uma mensagem dizendo Hello world
.
Banco de dados
Continuando, vamos cuidar do banco de dados.
Em vez de executar o SQL bruto, usaremos o Flask-SQLAlchemy, um ORM simples do Flask. Para instalá-lo, execute:
$ (venv) pip install Flask-SQLAlchemy
Em seguida, substitua o conteúdo do app.py pelo seguinte:
# app.py
from datetime import datetime
from flask import Flask, jsonify, request
from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy()
app = Flask(__name__)
app.config['SECRET_KEY'] = '5b3ef5s80gl3b217c20fb37044fe4k33'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:///default.db"
db.init_app(app)
class Task(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(128), nullable=False)
description = db.Column(db.String(256), nullable=False)
is_done = db.Column(db.Boolean, default=False)
created_at = db.Column(db.DateTime, default=datetime.now(), nullable=True)
updated_at = db.Column(db.DateTime, default=None, nullable=True)
def as_dict(self):
return {c.name: getattr(self, c.name) for c in self.__table__.columns}
def __repr__(self):
return f'<Task {self.title}>'
@app.route('/')
def index_view():
return {
'name': 'flask-todo',
'description': 'a simple todo app written in flask',
'version': 1,
}
Esse código configura o Flask e define um novo modelo chamado Task
. O modelo de tarefa tem um nome
, uma descrição
, is_done
e algumas outras variáveis, como created_at
e updated_at
, que atualizaremos dinamicamente.
Em seguida, crie um script Python chamado init_db.py que inicializa e preenche o banco de dados SQLite:
# init_db.py
from app import db, app
from app import Task
with app.app_context():
db.create_all()
if Task.query.count() == 0:
tasks = [
Task(name='Backup the database', description='Make sure to backup the database with all the tables.'),
Task(name='Setup 2FA', description='Setup the two factor authentication to secure your account.'),
Task(name='Malware scan', description='Perform a malware scan.'),
]
for task in tasks:
db.session.add(task)
db.session.commit()
Execute o script na linha de comando:
$ (venv) python init_db.py
Você perceberá que foi criado um novo diretório chamado instance. Dentro do diretório, haverá default.db, que é o banco de dados padrão.
API
O aplicativo Flask terá os seguintes URLs:
/api/
retorna a lista de todas as tarefas/api/
/ exibe ou exclui uma tarefa específica/api/create/
cria uma nova tarefa/api/toggle/
/ alterna a propriedadeis_done
de uma tarefa específica
Para implementá-los, acrescente o seguinte ao final do app.py:
# app.py
@app.route('/api/')
def list_view():
json = [task.as_dict() for task in Task.query.all()]
return jsonify(json)
@app.route('/api/<int:task_id>/', methods=['GET', 'DELETE'])
def detail_view(task_id):
task = db.get_or_404(Task, task_id)
if request.method == 'DELETE':
db.session.delete(task)
db.session.commit()
return {
'detail': 'Task has been successfully deleted.'
}
else:
return task.as_dict()
@app.route('/api/create/', methods=['POST'])
def create_view():
name = request.form.get('name')
description = request.form.get('name')
if name is None or description is None:
return {
'detail': 'Please provide the name and the description.'
}, 400
task = Task(name=name, description=description)
db.session.add(task)
db.session.commit()
return task.as_dict()
@app.route('/api/toggle/<int:task_id>/')
def toggle_view(task_id):
task = db.get_or_404(Task, task_id)
if task.is_done:
task.is_done = False
else:
task.is_done = True
task.updated_at = datetime.now()
db.session.commit()
return task.as_dict()
Esse código é bastante autoexplicativo. Definimos as rotas necessárias e implementamos a lógica necessária. Toda vez que quisermos fazer alterações no banco de dados, teremos de fazer commit()
delas.
Ótimo, isso é tudo para o aplicativo Flask. Nas próximas seções, prepararemos nosso projeto para implantação.
Gunicórnio
O servidor Web do Flask não é recomendado na produção, pois foi projetado para lidar com uma solicitação por vez e pode não ser capaz de lidar com grandes quantidades de tráfego. Por esse motivo, vamos trocá-lo pelo Gunicorn, um servidor Python WSGI pronto para produção.
Primeiro, instale-o via pip:
$ (venv) pip install gunicorn==20.1.0
Após a instalação bem-sucedida, você pode iniciar o servidor da seguinte forma:
$ (venv) gunicorn -w 2 -b 0.0.0.0:5000 app:app
[INFO] Starting gunicorn 20.1.0
[INFO] Listening at: http://0.0.0.0:5000 (1)
[INFO] Using worker: sync
[INFO] Booting worker with pid: 3
[INFO] Booting worker with pid: 4
Lembre-se de que esse comando só funciona em sistemas operacionais baseados em UNIX.
Isso iniciará dois workers do Gunicorn e exporá seu aplicativo na porta 5000
. Para acessar seu aplicativo, abra seu navegador da Web favorito e navegue até http://localhost:5000.
requisitos.txt
A última coisa que precisamos fazer antes de colocar nosso aplicativo no Docker é criar um arquivo requirements.txt. O arquivo requirements.txt é usado para especificar as dependências do projeto.
Gere-o executando o seguinte comando:
$ (venv) pip freeze > requirements.txt
Outros (incluindo contêineres do Docker) podem utilizar o arquivo requirements.txt da seguinte forma:
$ (venv) pip install -r requirements.txt
Aplicativo Dockerize
Para dockerizar o aplicativo, usaremos um Dockerfile. Os Dockerfiles são usados para definir as instruções para a criação de imagens do Docker. Eles permitem que você defina a imagem base, o diretório de trabalho, as variáveis de ambiente, a execução de comandos e muito mais.
.dockerignore
Antes de trabalhar no Dockerfile, vamos criar um arquivo .dockerignore. Um arquivo .dockerignore é usado para especificar quais pastas e arquivos devem ser omitidos da imagem.
.git/
.idea/
instance/
__pycache__/
Certifique-se de modificar o .dockerignore de acordo com suas necessidades.
Dockerfile
Crie um novo arquivo na raiz do projeto chamado Dockerfile com o seguinte conteúdo:
# syntax=docker/dockerfile:1.4
FROM --platform=$BUILDPLATFORM python:3.10-alpine
WORKDIR /app
# set environment variables
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1
# install the requirements
COPY requirements.txt /app
RUN --mount=type=cache,target=/root/.cache/pip \
pip3 install -r requirements.txt
COPY . .
# initialize the database (create DB, tables, populate)
RUN python init_db.py
EXPOSE 5000/tcp
CMD ["gunicorn", "-w", "2", "-b", "0.0.0.0:5000", "app:app"]
Esse Dockerfile utiliza python:3.10-alpine
como imagem de base. Em seguida, ele define o diretório de trabalho, instala os requisitos, copia o projeto, inicializa o banco de dados e, por fim, inicia o servidor Gunicorn na porta 5000
.
Para saber mais sobre Dockerfiles, consulte areferência Dockerfile .
Teste
Para garantir que o Dockerfile funcione, podemos criá-lo e executá-lo localmente. Para criar a imagem, execute:
$ docker build -t flask-todo:1.0 .
Se você listar as imagens, deverá ver uma nova imagem:
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
flask-todo 1.0 7ege66240eb1 3 hours ago 109MB
Por fim, use a imagem para ativar um novo contêiner do Docker:
$ docker run -it -p 5000:5000 flask-todo:1.0
[2023-02-02 20:08:57 +0000] [1] [INFO] Starting gunicorn 20.1.0
[2023-02-02 20:08:57 +0000] [1] [INFO] Listening at: http://0.0.0.0:5000 (1)
[2023-02-02 20:08:57 +0000] [1] [INFO] Using worker: sync
[2023-02-02 20:08:57 +0000] [7] [INFO] Booting worker with pid: 3
[2023-02-02 20:08:57 +0000] [8] [INFO] Booting worker with pid: 4
Você pode usar
-d
para iniciar o contêiner do Docker no modo desanexado. Isso significa que o contêiner é executado em segundo plano no seu terminal e não recebe entrada nem exibe saída.
Ótimo, seu aplicativo agora está sendo executado em um contêiner. Navegue até http://localhost:5000 em seu navegador da Web favorito para ver seu aplicativo Web em ação.
{
"name": "flask-todo",
"description": "a simple todo app written in flask",
"version": 1
}
Enviar para o GitHub
As etapas a seguir exigirão que você tenha uma conta no GitHub. Se você ainda não tiver uma, vá em frente e inscreva-se ou faça login. Além disso, certifique-se de que você tenha o Git instalado e configurado.
Depois de fazer login no GitHub, use o botão “mais” no canto superior direito da tela para abrir o menu suspenso. Em seguida, selecione “New repository” (Novo repositório):
Escolha um nome personalizado para seu repositório. Vou usar “flask-todo” e, em seguida, clicar em “Create repository” (Criar repositório):
Depois que o repositório for criado, anote o URL remoto:
Agora, vamos navegar de volta ao nosso projeto local e enviar o código.
Como temos alguns arquivos que não queremos enviar para o Git, crie um arquivo .gitignore na raiz do projeto. Adicionarei o seguinte a ele, mas fique à vontade para modificá-lo de acordo com suas necessidades:
instance/*
!instance/.gitignore
.webassets-cache
.env
__pycache__/
*.py[cod]
*$py.class
Em seguida, abra a linha de comando e execute os seguintes comandos:
$ git init
$ git remote add origin <your_remote_url>
$ git add .
$ git commit -m "init"
$ git push origin master
Isso inicializará um novo repositório do Git, adicionará a origem remota, o VCS de todos os arquivos e criará o commit inicial. Por fim, ele enviará o código-fonte para o repositório do GitHub.
Ótimo, deve ser isso. Se agora você navegar até o repositório no navegador, poderá ver que todos os arquivos foram confirmados.
Implantar aplicativo
As etapas a seguir exigirão que você tenha uma conta no Back4app. Se você já tiver uma, faça login; caso contrário, vá em frente e inscreva-se na conta gratuita.
Depois de fazer login, você será redirecionado para o painel do seu aplicativo. Clique no botão “Build new app” (Criar novo aplicativo) para iniciar o processo de criação do aplicativo.
O Back4app permite que você crie e implemente dois tipos de aplicativos: Backend as a Service (BaaS) e Containers as a Service (CaaS). Como queremos implantar um aplicativo em docker, vamos optar pelo “Container as a Service”.
Em seguida, vá em frente e conecte seu GitHub à sua conta do Back4app. Certifique-se de conceder permissões ao Back4app para o repositório que criamos na etapa anterior. Em seguida, clique no botão verde “Select” (Selecionar) para selecioná-lo.
O Back4app Containers permite que você configure o processo de implantação. Você pode definir o branch padrão, o diretório raiz, ativar/desativar a implantação automática e definir variáveis de ambiente. Não precisamos de nada disso, portanto, vamos apenas dar um nome ao nosso aplicativo e clicar em “Create app”.
A Back4app levará alguns instantes para criar o contêiner, carregá-lo no registro de contêineres e executá-lo. Quando o contêiner estiver pronto, o status mudará para “Ready” (Pronto) e você poderá ver um URL verde no lado esquerdo da tela.
Ao clicar no URL, o aplicativo da Web será aberto em seu navegador. Você perceberá que o Back4app emitiu automaticamente um certificado SSL para o seu aplicativo e permitiu que você hospedasse um aplicativo Python gratuitamente.
Conclusão
Neste artigo, você aprendeu sobre Python, suas vantagens, desvantagens e opções de implementação. Você também implantou com êxito uma API RESTful Python simples. Agora você deve ser capaz de criar suas APIs simples e implantá-las nos contêineres do Back4app.
O código-fonte final pode ser encontrado no GitHub.
Etapas futuras
- No momento, todos os dados são apagados a cada reimplantação. Isso ocorre porque o banco de dados está incluído na imagem do Docker. Considere a possibilidade de mudar para uma instância de banco de dados gerenciada.
- Procure por compilações em vários estágios para acelerar o processo de implementação.