Tutorial: Criar e implantar um aplicativo Web Python com Os Aplicativos de Contêiner do Azure e o PostgreSQL
Este artigo faz parte de uma série de tutoriais sobre como containerizar e implantar um aplicativo web Python nos aplicativos de contêiner do Azure. Os Aplicativos de Contêiner do Azure permitem que você implemente aplicativos em contêineres sem gerenciar infraestruturas complexas.
Neste tutorial, você:
- Conteinerize um aplicativo Web de exemplo do Python (Django ou Flask) criando uma imagem de contêiner na nuvem.
- Implante a imagem de contêiner nos Aplicativos de Contêiner do Azure.
- Defina variáveis de ambiente que permitem que o aplicativo de contêiner se conecte a uma instância Banco de Dados do Azure para PostgreSQL – Servidor Flexível, em que o aplicativo de exemplo armazena dados.
O diagrama a seguir realça as tarefas neste tutorial: compilar e implantar uma imagem de contêiner.
Pré-requisitos
Se você não tiver uma assinatura do Azure, crie uma conta gratuita antes de começar.
Você pode executar comandos da CLI do Azure no do Azure Cloud Shell ou em uma estação de trabalho com o CLI do Azure instalado.
Se você estiver executando localmente, siga estas etapas para entrar e instalar os módulos necessários para este tutorial:
Entre no Azure e autentique-se, se necessário:
az login
Verifique se você está executando a versão mais recente da CLI do Azure:
az upgrade
Instale ou atualize as extensões de containerapp e rdbms-connect da CLI do Azure usando o comando az extension add:
az extension add --name containerapp --upgrade az extension add --name rdbms-connect --upgrade
Observação
Para listar as extensões instaladas em seu sistema, você pode usar o comando az extension list. Por exemplo:
az extension list --query [].name --output tsv
Obter o aplicativo de exemplo
Bifurque e clone o código de exemplo em seu ambiente de desenvolvedor:
Vá para o repositório GitHub do aplicativo de exemplo (Django ou Flask) e selecione Bifurcar.
Siga as etapas para bifurcar o repositório para sua conta do GitHub. Você também pode baixar o repositório de código diretamente para seu computador local sem fazer um fork e sem precisar de uma conta no GitHub. Porém, se você usar o método de download, não poderá configurar a CI/CD (integração contínua e entrega contínua) no próximo tutorial desta série.
Use o comando git clone para clonar o repositório bifurcado na pasta python-container :
# Django git clone https://github.com/$USERNAME/msdocs-python-django-azure-container-apps.git python-container # Flask # git clone https://github.com/$USERNAME/msdocs-python-flask-azure-container-apps.git python-container
Altere o diretório:
cd python-container
Criar uma imagem de contêiner a partir do código do aplicativo Web
Depois de seguir estas etapas, você terá uma instância do Registro de Contêiner do Azure que contém uma imagem de contêiner do Docker criada a partir do código de exemplo.
Crie um grupo de recursos usando o comando az group create:
az group create \ --name pythoncontainer-rg \ --location <location>
Substitua <> por um dos valores de localização do Azure
Name
da saída do comandoaz account list-locations -o table
.Crie um registro de contêiner usando o comando az acr create:
az acr create \ --resource-group pythoncontainer-rg \ --name <registry-name> \ --sku Basic \ --admin-enabled
O nome usado para <nome do registro> deve ser exclusivo no Azure e deve conter de 5 a 50 caracteres alfanuméricos.
Entre no Registro usando o comando az acr login:
az acr login --name <registry-name>
O comando adiciona "azurecr.io" ao nome para criar o nome do Registro totalmente qualificado. Se a entrada for bem-sucedida, a mensagem "Login Bem-sucedido" aparecerá. Se você estiver acessando o registro de uma assinatura diferente daquela em que criou o registro, use a opção
--suffix
.Se a entrada falhar, verifique se o daemon do Docker está em execução em seu sistema.
Crie a imagem usando o comando az acr build:
az acr build \ --registry <registry-name> \ --resource-group pythoncontainer-rg \ --image pythoncontainer:latest .
Estas considerações se aplicam:
O ponto (
.
) no final do comando indica o local do código-fonte a ser compilado. Se você não estiver executando esse comando no diretório raiz do aplicativo de exemplo, especifique o caminho para o código.Se você estiver executando o comando no Azure Cloud Shell, use
git clone
para primeiro efetuar pull do repositório para o ambiente do Cloud Shell. Em seguida, altere o diretório para a raiz do projeto para que o ponto (.
) seja interpretado corretamente.Se você deixar de fora a opção (igual a
-t
--image
), o comando enfileira uma compilação de contexto local sem enviá-la para o registro. Construir sem empurrar pode ser útil para verificar se a imagem é construída.
Confirme se a imagem de container foi criada usando o comando az acr repository list:
az acr repository list --name <registry-name>
Observação
As etapas nesta seção criam um registro de contêiner na camada de serviço Básica. Essa camada é otimizada em termos de custo, com um conjunto de recursos e uma taxa de transferência orientados para cenários de desenvolvedor, e é adequada para os requisitos deste tutorial. Em cenários de produção, provavelmente você usaria a camada de serviço Standard ou Premium. Essas camadas fornecem níveis aprimorados de armazenamento e taxa de transferência.
Para saber mais, consulte Criar camadas de serviço do Registro de Contêiner do Azure. Para mais informações sobre preços, consulte Preço de Registro de Contêiner do Azure.
Crie uma instância de Servidor Flexível do PostgreSQL
O aplicativo de exemplo (Django ou Flask) armazena dados de avaliação de restaurantes em um banco de dados PostgreSQL. Nestas etapas, você cria o servidor que conterá o banco de dados.
Use o comando az postgres flexible-server create para criar o servidor PostgreSQL no Azure. Não é incomum que esse comando seja executado por alguns minutos antes de ser concluído.
az postgres flexible-server create \ --resource-group pythoncontainer-rg \ --name <postgres-server-name> \ --location <location> \ --admin-user demoadmin \ --admin-password <admin-password> \ --active-directory-auth Enabled \ --tier burstable \ --sku-name standard_b1ms \ --public-access 0.0.0.0
Use estes valores:
pythoncontainer-rg
: o nome do grupo de recursos que este tutorial usa. Se você usou um nome diferente, altere este valor.<postgres-server-name>: o nome do servidor de banco de dados PostgreSQL. Esse nome deve ser exclusivo em todo o Azure. O ponto de extremidade do servidor é
https://<postgres-server-name>.postgres.database.azure.com
. Os caracteres permitidos sãoA
paraZ
,0
para9
e hífen (-
).<local>: use o mesmo local usado para o aplicativo Web. <local> é um dos valores
Name
do local do Azure da saída do comandoaz account list-locations -o table
.<nome de usuário do admin>: o nome de usuário da conta do administrador. Não pode ser
azure_superuser
,admin
,administrator
,root
,guest
oupublic
. Usedemoadmin
para esse tutorial.<senha do administrador>: a senha do usuário administrador. Ela precisa conter de 8 a 128 caracteres de três das seguintes categorias: Letras maiúsculas, letras minúsculas, números e caracteres não alfanuméricos.
Importante
Ao criar nomes de usuário ou senhas, não use o caractere de cifrão ($). Posteriormente, quando você cria variáveis de ambiente com esses valores, esse caractere tem um significado especial dentro do contêiner do Linux que você usa para executar aplicativos Python.
--active-directory-auth
: esse valor especifica se a autenticação do Microsoft Entra está habilitada no servidor PostgreSQL. Defina-o comoEnabled
.--sku-name
: o nome do tipo de preço e da configuração de computação; por exemplo,Standard_B1ms
. Para obter mais informações, confira Preços do Banco de Dados do Azure para PostgreSQL. Para listar as camadas disponíveis, useaz postgres flexible-server list-skus --location <location>
.--public-access
: use0.0.0.0
. Ele permite o acesso público ao servidor de qualquer serviço do Azure, como Aplicativos de Contêiner.
Observação
Se você planeja trabalhar com o servidor PostgreSQL da estação de trabalho local usando ferramentas, precisará adicionar uma regra de firewall para o endereço IP da estação de trabalho usando o comando az postgres flexible-server firewall-rule create.
Use o comando az ad signed-in-user show para obter a ID do objeto da sua conta de usuário. Use essa ID no próximo comando.
az ad signed-in-user show --query id --output tsv
Use o comando az postgres flexible-server ad-admin create para adicionar sua conta de usuário como administrador do Microsoft Entra no servidor PostgreSQL:
az postgres flexible-server ad-admin create \ --resource-group pythoncontainer-rg \ --server-name <postgres-server-name> \ --display-name <your-email-address> \ --object-id <your-account-object-id>
Para a ID do objeto de conta, use o valor que você obteve na etapa anterior.
Observação
As etapas desta seção criam um servidor PostgreSQL com um único vCore e memória limitada na camada de preço com capacidade de intermitência. A camada Burstable é uma opção de menor custo para cargas de trabalho que não precisam da CPU completa continuamente e é adequada para os requisitos deste tutorial. Para workloads de produção, você pode fazer upgrade para o nível de preço Uso geral ou Memória otimizada. Essas camadas fornecem um desempenho mais alto, mas aumentam os custos.
Para saber mais, consulte Opções de computação no Banco de Dados do Azure para PostgreSQL – Servidor Flexível. Para obter mais informações sobre precificação, consulte Preços do Banco de Dados do Azure para PostgreSQL.
Crie um banco de dados no servidor
Neste ponto, você tem um servidor PostgreSQL. Nesta seção, você criará um banco de dados no servidor.
Use o comando az postgres flexible-server db create para criar um banco de dados chamado restaurants_reviews:
az postgres flexible-server db create \
--resource-group pythoncontainer-rg \
--server-name <postgres-server-name> \
--database-name restaurants_reviews
Use estes valores:
pythoncontainer-rg
: o nome do grupo de recursos que este tutorial usa. Se você usou um nome diferente, altere este valor.<postgres-server-name>
: o nome do servidor PostgreSQL.
Você também pode usar o comando az postgres flexible-server connect para se conectar ao banco de dados e, em seguida, trabalhar com comandos psql . Ao trabalhar com psql, geralmente é mais fácil usar o Azure Cloud Shell porque o shell inclui todas as dependências para você.
Você também pode se conectar ao servidor flexível do Banco de Dados do Azure para PostgreSQL e criar um banco de dados usando psql ou um IDE que dê suporte ao PostgreSQL, como do Azure Data Studio. Para as etapas usando psql, consulte Configurar a identidade gerenciada no banco de dados PostgreSQL mais adiante neste artigo.
Criar uma identidade gerenciada atribuída pelo usuário
Crie uma identidade gerenciada atribuída pelo usuário para usar como a identidade do aplicativo de contêiner quando ele estiver em execução no Azure.
Observação
Para criar uma identidade gerenciada atribuída pelo usuário, sua conta precisa da atribuição de função Administrador de identidade gerenciada.
Use o comando az identity create para criar uma identidade gerenciada atribuída pelo usuário:
az identity create --name my-ua-managed-id --resource-group pythoncontainer-rg
Configurar a identidade gerenciada no banco de dados PostgreSQL
Configure a identidade gerenciada como uma função no servidor PostgreSQL e conceda permissões necessárias para o banco de dados restaurants_reviews. Se você estiver usando a CLI do Azure ou o psql, deverá se conectar ao servidor PostgreSQL do Azure com um usuário que esteja configurado como administrador do Microsoft Entra na instância do servidor. Somente contas do Microsoft Entra configuradas como um administrador do PostgreSQL podem configurar identidades gerenciadas e outras funções de administrador da Microsoft em seu servidor.
Obtenha um token de acesso para sua conta do Azure usando o comando az account get-access-token. Use o token de acesso nas próximas etapas.
az account get-access-token --resource-type oss-rdbms --output tsv --query accessToken
O token retornado é longo. Defina seu valor em uma variável de ambiente a ser usada nos comandos na próxima etapa:
MY_ACCESS_TOKEN=<your-access-token>
Adicione a identidade gerenciada atribuída pelo usuário como função de banco de dados em seu servidor PostgreSQL usando o comando az postgres flexible-server execute.
az postgres flexible-server execute \ --name <postgres-server-name> \ --database-name postgres \ --querytext "select * from pgaadauth_create_principal('"my-ua-managed-id"', false, false);select * from pgaadauth_list_principals(false);" \ --admin-user <your-Azure-account-email> \ --admin-password $MY_ACCESS_TOKEN
Use estes valores:
Se você usou um nome diferente para sua identidade gerenciada, substitua
my-ua-managed-id
no comandopgaadauth_create_principal
pelo nome de sua identidade gerenciada.Para o valor
--admin-user
, use o endereço de email para sua conta do Azure.Para o valor
--admin-password
, use o token de acesso da saída do comando anterior, sem aspas.Verifique se o nome do banco de dados é
postgres
.
Observação
Se você estiver executando o comando
az postgres flexible-server execute
em sua estação de trabalho local, verifique se adicionou uma regra de firewall para o endereço IP da estação de trabalho. Você pode adicionar uma regra usando o comando az postgres flexible-server firewall-rule create. O mesmo requisito também existe para o comando na próxima etapa.Conceda à identidade gerenciada atribuída pelo usuário as permissões necessárias no banco de dados restaurants_reviews usando o seguinte comando az postgres flexible-server execute:
az postgres flexible-server execute \ --name <postgres-server-name> \ --database-name restaurants_reviews \ --querytext "GRANT CONNECT ON DATABASE restaurants_reviews TO \"my-ua-managed-id\";GRANT USAGE ON SCHEMA public TO \"my-ua-managed-id\";GRANT CREATE ON SCHEMA public TO \"my-ua-managed-id\";GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO \"my-ua-managed-id\";ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT, INSERT, UPDATE, DELETE ON TABLES TO \"my-ua-managed-id\";" \ --admin-user <your-Azure-account-email> \ --admin-password $MY_ACCESS_TOKEN
Use estes valores:
Se você usou um nome diferente para sua identidade gerenciada, substitua todas as instâncias de
my-ua-managed-id
no comando pelo nome de sua identidade gerenciada. Há cinco instâncias na cadeia de caracteres de consulta.Para o valor
--admin-user
, use o endereço de email da sua conta do Azure.Para o valor
--admin-password
, use o token de acesso da saída anterior, sem aspas.Verifique se o nome do banco de dados é
restaurants_reviews
.
Este comando da CLI do Azure conecta-se ao banco de dados restaurants_reviews no servidor e emite os seguintes comandos SQL:
GRANT CONNECT ON DATABASE restaurants_reviews TO "my-ua-managed-id"; GRANT USAGE ON SCHEMA public TO "my-ua-managed-id"; GRANT CREATE ON SCHEMA public TO "my-ua-managed-id"; GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO "my-ua-managed-id"; ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT, INSERT, UPDATE, DELETE ON TABLES TO "my-ua-managed-id";
Implantar o aplicativo Web em Aplicativos de Contêiner
Os aplicativos de contêiner são implantados em ambientes de Aplicativos de Contêiner do Azure , que atuam como uma fronteira segura. Nas etapas a seguir, você cria o ambiente e um contêiner dentro do ambiente. Em seguida, configure o contêiner para que o site fique visível externamente.
Essas etapas exigem a extensão Aplicativos de contêiner do Azure containerapp.
Crie um ambiente de aplicativos de contêiner usando o comando az containerapp env create:
az containerapp env create \ --name python-container-env \ --resource-group pythoncontainer-rg \ --location <location>
<local> é um dos valores
Name
do local do Azure da saída do comandoaz account list-locations -o table
.Obtenha as credenciais de autenticação para a instância do Registro de Contêiner do Azure usando o comando az acr credential show:
az acr credential show -n <registry-name>
Use o nome de usuário e uma das senhas retornadas da saída do comando ao criar o aplicativo de contêiner na etapa 5.
Use o comando az identity show para obter o ID do cliente e o ID do recurso da identidade gerenciada atribuída ao usuário:
az identity show --name my-ua-managed-id --resource-group pythoncontainer-rg --query "[clientId, id]" --output tsv
Use o valor da ID do cliente (GUID) e a ID do recurso da saída do comando ao criar o aplicativo de contêiner na etapa 5. O ID do recurso tem o seguinte formato:
/subscriptions/<subscription-id>/resourcegroups/pythoncontainer-rg/providers/Microsoft.ManagedIdentity/userAssignedIdentities/my-ua-managed-id
.Execute o seguinte comando para gerar um valor de chave secreta:
python -c 'import secrets; print(secrets.token_hex())'
Use o valor da chave secreta para definir uma variável de ambiente ao criar o aplicativo de contêiner na etapa 5.
Observação
O comando que esta etapa mostra é para um shell Bash. Dependendo do seu ambiente, talvez seja necessário invocar o Python usando
python3
. No Windows, você precisa colocar o comando no parâmetro-c
entre aspas duplas em vez de aspas simples. Talvez você também precise invocar o Python usandopy
oupy -3
, dependendo do seu ambiente.Crie um aplicativo contêiner no ambiente usando o comando az containerapp create:
az containerapp create \ --name python-container-app \ --resource-group pythoncontainer-rg \ --image <registry-name>.azurecr.io/pythoncontainer:latest \ --environment python-container-env \ --ingress external \ --target-port <5000 for Flask or 8000 for Django> \ --registry-server <registry-name>.azurecr.io \ --registry-username <registry-username> \ --registry-password <registry-password> \ --user-assigned <managed-identity-resource-id> \ --query properties.configuration.ingress.fqdn \ --env-vars DBHOST="<postgres-server-name>" \ DBNAME="restaurants_reviews" \ DBUSER="my-ua-managed-id" \ RUNNING_IN_PRODUCTION="1" \ AZURE_CLIENT_ID="<managed-identity-client-id>" \ AZURE_SECRET_KEY="<your-secret-key>"
Substitua todos os valores em colchetes angulares por valores que você está usando neste tutorial. Lembre-se de que o nome do aplicativo de contêiner deve ser exclusivo no Azure.
O valor do parâmetro
é uma cadeia de caracteres composta de valores separados por espaço no formato key="value" com os seguintes valores: DBHOST="\<postgres-server-name>"
DBNAME="restaurants_reviews"
DBUSER="my-ua-managed-id"
RUNNING_IN_PRODUCTION="1"
AZURE_CLIENT_ID="\<managed-identity-client-id>"
AZURE_SECRET_KEY="\<your-secret-key>"
O valor para
DBUSER
é o nome da identidade gerenciada atribuída pelo usuário.O valor para
AZURE_CLIENT_ID
é o ID de cliente da identidade gerenciada atribuída pelo usuário. Você obteve esse valor em uma etapa anterior.O valor de
AZURE_SECRET_KEY
é o valor da chave secreta que você gerou em uma etapa anterior.Para Django apenas, migre e crie um esquema de banco de dados. (No aplicativo de exemplo Flask, isso é feito automaticamente e você pode ignorar esta etapa.)
Conecte-se usando o comando az containerapp exec:
az containerapp exec \ --name python-container-app \ --resource-group pythoncontainer-rg
Em seguida, no prompt de comando do shell, insira
python manage.py migrate
.Você não precisa migrar para revisões do contêiner.
Testar o site.
O comando
az containerapp create
que você inseriu anteriormente gera uma URL de aplicativo que você pode usar para navegar até o aplicativo. A URL termina emazurecontainerapps.io
. Abra a URL em um navegador. Como alternativa, você pode usar o comando az containerapp browse .
Aqui está um exemplo do site de exemplo após a adição de um restaurante e duas avaliações.
Solucionar problemas de implantação
Você esqueceu a URL do aplicativo para acessar o site
No portal do Azure:
- Acesse a página Visão Geral do aplicativo contêiner e procure por URL do Aplicativo.
No VS Code:
- Acesse a Exibição do Azure (Ctrl+Shift+A) e expanda a assinatura em que está trabalhando.
- Expanda o nó Aplicativos de contêiner, e em seguida, expanda o ambiente gerenciado, clique com o botão direito do mouse em python-container-app e então selecione Procurar. O VS Code abre o navegador com a URL do aplicativo.
Na CLI do Azure:
- Use o comando
az containerapp show -g pythoncontainer-rg -n python-container-app --query properties.configuration.ingress.fqdn
.
No VS Code, a tarefa de criação de imagem na Azure retorna um erro
Se você vir a mensagem "Erro: falha ao baixar o contexto. Verifique se a URL está incorreta." na janela Saída do VS Code e atualize o registro na extensão do Docker. Para atualizar, selecione a extensão do Docker, vá para a seção Registros, localize o registro e selecione-o.
Se você executar a tarefa Criar imagem no Azure novamente, verifique se o registro de uma execução anterior está presente. Em caso afirmativo, use-o.
No portal do Azure, um erro de acesso é exibido durante a criação de um aplicativo de contêiner
Um erro de acesso que contém "Não é possível acessar o ACR '<nome>.azurecr.io'" ocorre quando as credenciais de administrador em uma instância do Registro de Contêiner do Azure são desabilitadas.
Para verificar o status do administrador no portal, acesse a instância do Registro de Contêiner do Azure, selecione o recurso chaves de acesso e verifique se o Usuário Administrador está habilitado.
Sua imagem de contêiner não aparece na instância do Registro de Contêiner do Azure
- Verifique a saída do comando da CLI do Azure ou a saída do VS Code e procure mensagens que confirmem o êxito.
- Verifique se o nome do registro foi especificado corretamente no comando de build com a CLI do Azure ou nos prompts de tarefa do VS Code.
- Certifique-se de que suas credenciais não estejam expiradas. Por exemplo, no VS Code, localize o registro de destino na extensão do Docker e atualize. Na CLI do Azure, execute
az login
.
O site retorna "Solicitação Incorreta (400)"
Se você receber um erro "Solicitação Incorreta (400)", verifique as variáveis de ambiente postgreSQL passadas para o contêiner. O erro 400 geralmente indica que o código Python não pode se conectar à instância do PostgreSQL.
O código de exemplo usado neste tutorial verifica a existência da variável de ambiente de contêiner RUNNING_IN_PRODUCTION
, que pode ser definida como qualquer valor (como 1
).
O site retorna "Não Encontrado (404)"
- Verifique o valor de URL do aplicativo na página Visão geral do contêiner. Se o URL do aplicativo contiver a palavra "internal", o ingresso não está definido corretamente.
- Verifique a entrada do contêiner. Por exemplo, no portal do Azure, vá para o recurso Ingress do contêiner. Verifique se a Entrada HTTP está habilitada e Aceitar tráfego de qualquer lugar está selecionado.
O site não começa, você obtém "tempo limite do fluxo" ou nada é retornado
- Verifique os logs:
- No portal do Azure, acesse o recurso de gerenciamento de revisão do aplicativo contêiner e verifique Status de Provisionamento para o contêiner:
- Se o status for Provisionando, aguarde até o provisionamento estar completo.
- Se o status for Falhou, selecione a revisão e exiba os logs do console. Escolha a ordem das colunas para mostrar o Hora da Geração, Stream_s e Log_s. Classifique os logs pelo mais recente e procure mensagens de
stderr
estdout
do Python na coluna Stream_s. A saída do Pythonprint
são mensagensstdout
.
- No Azure CLI, use o comando az containerapp logs show.
- No portal do Azure, acesse o recurso de gerenciamento de revisão do aplicativo contêiner e verifique Status de Provisionamento para o contêiner:
- Se você estiver usando a estrutura do Django, verifique se as tabelas restaurants_reviews existem no banco de dados. Caso contrário, use um console para acessar o contêiner e executar
python manage.py migrate
o .