1660749420
Neste tutorial, implantaremos um aplicativo Django no AWS EC2 com o Docker. O aplicativo será executado por trás de um proxy HTTPS Nginx que usa certificados Let's Encrypt SSL. Usaremos o AWS RDS para servir nosso banco de dados Postgres junto com o AWS ECR para armazenar e gerenciar nossas imagens do Docker.
Ao final deste tutorial, você será capaz de:
Este post se baseia nos posts Dockerizing Django com Postgres, Gunicorn e Nginx e Protegendo um Aplicativo Django Containerizado com Let's Encrypt .
Ele assume que você pode:
Primeiro, crie uma conta da AWS , caso ainda não tenha uma.
Em seguida, navegue até o console do EC2 e clique em Launch instance :
Use o Ubuntu Server 18.04 LTS (HVM) para a imagem do servidor (AMI):
Na próxima etapa, fique com a instância t2.micro . Clique em Avançar: Configurar detalhes da instância :
Na etapa Configure Instance Details , deixe tudo como está para manter as coisas simples. Em seguida, clique em Avançar algumas vezes até chegar à etapa Configurar Grupo de Segurança .
Com Criar um novo grupo de segurança selecionado, defina o nome e a descrição django-ec2
e adicione duas regras:
Essas regras são necessárias para emitir certificados e acessar o aplicativo.
As regras de entrada do grupo de segurança são usadas para limitar o acesso à sua instância pela Internet. A menos que você tenha alguns requisitos de segurança adicionais, provavelmente desejará permitir tráfego HTTP e HTTPS de qualquer lugar para instâncias que hospedam aplicativos da web. O SSH deve ser permitido para você se conectar à instância para configuração e implantação.
Clique em Revisar e Iniciar . Na próxima tela, clique em Iniciar .
Você será solicitado a selecionar um par de chaves. Você precisa dele para conexão SSH com sua instância. Selecione Criar um novo par de chaves e nomeie-o djangoletsencrypt
. Em seguida, clique em Baixar par de chaves . Após o download do par de chaves, clique em Launch Instances :
Levará alguns minutos para a instância girar.
Nesta seção, instalaremos o Docker na instância, adicionaremos um IP elástico e configuraremos uma função do IAM.
Navegue de volta ao console do EC2 , selecione a instância recém-criada e pegue o endereço IP público:
Conecte-se à sua instância do EC2 usando a .pem
chave que baixamos na etapa "AWS EC2".
$ ssh -i /path/to/your/djangoletsencrypt.pem ubuntu@public-ip-or-domain-of-ec2-instance
Seu
.pem
provavelmente foi baixado em um caminho como ~/Downloads/djangoletsencrypt.pem. Se você não tiver certeza de onde armazená-lo, mova-o para o diretório ~/.ssh . Você também pode ter que alterar as permissões -- ou seja,chmod 400 -i /path/to/your/djangoletsencrypt.pem
.
Comece instalando a versão mais recente do Docker e a versão 1.29.2 do Docker Compose:
$ sudo apt update
$ sudo apt install apt-transport-https ca-certificates curl software-properties-common
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
$ sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu bionic stable"
$ sudo apt update
$ sudo apt install docker-ce
$ sudo usermod -aG docker ${USER}
$ sudo curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
$ sudo chmod +x /usr/local/bin/docker-compose
$ docker -v
Docker version 20.10.8, build 3967b7d
$ docker-compose -v
docker-compose version 1.29.2, build 5becea4c
Primeiro, instale o descompacte:
$ sudo apt install unzip
Faça download do ZIP da AWS CLI:
$ curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
Descompacte seu conteúdo:
$ unzip awscliv2.zip
Instale a AWS CLI:
$ sudo ./aws/install
Verifique a instalação:
$ aws --version
Por padrão, as instâncias recebem um novo endereço IP público sempre que são iniciadas e reiniciadas.
O IP elástico permite alocar IPs estáticos para suas instâncias do EC2, para que o IP permaneça o mesmo o tempo todo e possa ser reassociado entre as instâncias. É recomendável usar um para sua configuração de produção.
Navegue até Elastic IPs e clique em Allocate Elastic IP address :
Em seguida, clique em Alocar :
Clique em Associar este endereço IP elástico :
Selecione sua instância e clique em Associar :
Usaremos o AWS ECR para extrair imagens do AWS ECR para nossa instância do EC2 durante a implantação. Como não permitiremos acesso público à imagem do Docker no ECR, você precisará criar uma função do IAM com permissões para extrair imagens do Docker do ECR e anexá-las à sua instância do EC2.
Navegue até o console do IAM .
Clique em Funções na barra lateral esquerda e depois em Criar função :
Selecione AWS Service e EC2 e clique em Next: Permissions :
Digite container
na caixa de pesquisa, selecione a política AmazonEC2ContainerRegistryPowerUser e clique em Next: Tags :
Clique em Avançar: Revisar . Use django-ec2
para o nome e clique em Criar função :
Agora você precisa anexar a nova função à sua instância do EC2.
De volta ao console do EC2 , clique em Instâncias e selecione sua instância. Clique no menu suspenso Actions -> Instance settings -> Attach/Replace IAM Role :
Selecione a função django-ec2 e clique em Aplicar .
Clique em Fechar .
Adicione um registro A ao seu DNS, para o domínio que você está usando, para apontar para o IP público da sua instância do EC2.
É o IP elástico que você associou à sua instância.
O Amazon Elastic Container Registry (ECR) é um registro de imagem totalmente gerenciado do Docker que facilita o armazenamento e o gerenciamento de imagens para os desenvolvedores. Para imagens privadas, o acesso é gerenciado por meio de usuários e funções do IAM.
Navegue até o console do ECR . Clique em Repositórios na barra lateral e depois em Criar repositório :
Defina o nome django-ec2
e clique em Criar repositório :
Agora podemos configurar um banco de dados RDS Postgres.
Embora você possa executar seu próprio banco de dados Postgres em um contêiner, já que bancos de dados são serviços críticos , adicionar camadas adicionais, como o Docker, adiciona riscos desnecessários na produção. Para simplificar tarefas como atualizações de versões secundárias, backups regulares e dimensionamento, é recomendável usar um serviço gerenciado. Então, vamos usar RDS .
Navegue até o console do RDS . Clique em Criar banco de dados :
Selecione a versão mais recente do Postgres com o modelo de nível gratuito :
Em Configurações , defina:
djangoec2
webapp
Fique com as configurações padrão para:
Pule para a seção Conectividade e defina o seguinte:
django-ec2
Deixe a autenticação do banco de dados como está.
Abra a configuração adicional e altere o nome do banco de dados inicial para djangoec2
:
Deixe as outras configurações como estão.
Por fim, clique em Criar banco de dados .
Clique em Exibir detalhes das credenciais para ver a senha gerada para o usuário do webapp :
Guarde esta senha em algum lugar seguro. Você precisará fornecê-lo ao aplicativo Django aqui em breve.
Levará alguns minutos para a instância girar. Uma vez ativado, clique no DB Identifier do banco de dados recém-criado para ver seus detalhes. Anote o endpoint do banco de dados; você precisará configurá-lo em seu aplicativo Django.
No console do EC2 , clique em Grupos de segurança na barra lateral. Encontre e clique no ID do grupo django-ec2 para editar seus detalhes.
Clique em Editar regras de entrada :
Adicione uma regra de entrada que permitirá conexões Postgres com instâncias dentro desse grupo de segurança. Fazer isso:
Para limitar o acesso ao seu banco de dados, somente conexões de instâncias dentro do mesmo Security Group são permitidas. Nosso aplicativo pode se conectar porque definimos o mesmo grupo de segurança, django-ec2 , para as instâncias RDS e EC2. Instâncias dentro de outros grupos de segurança, portanto, não têm permissão para se conectar.
Com a infraestrutura da AWS configurada, agora precisamos configurar nosso projeto Django localmente antes de implantá-lo.
Primeiro, clone o conteúdo do repositório do projeto GitHub:
$ git clone https://github.com/testdrivenio/django-on-docker-letsencrypt django-on-docker-letsencrypt-aws
$ cd django-on-docker-letsencrypt-aws
Este repositório contém tudo o que você precisa para implantar um Django Dockerizado com certificados Let's Encrypt HTTPS.
Quando o aplicativo for implantado pela primeira vez, você deve seguir estas duas etapas para evitar problemas com certificados:
Você pode ler mais sobre as limitações do Let's Encrypt em ambientes de produção na seção Let's Encrypt do post anterior, Protegendo um aplicativo Django em contêiner com o Let's Encrypt .
Para testar, atualize o docker-compose.staging.yml. arquivo assim:
version: '3.8'
services:
web:
build:
context: ./app
dockerfile: Dockerfile.prod
image: <aws-account-id>.dkr.ecr.<aws-region>.amazonaws.com/django-ec2:web
command: gunicorn hello_django.wsgi:application --bind 0.0.0.0:8000
volumes:
- static_volume:/home/app/web/staticfiles
- media_volume:/home/app/web/mediafiles
expose:
- 8000
env_file:
- ./.env.staging
nginx-proxy:
container_name: nginx-proxy
build: nginx
image: <aws-account-id>.dkr.ecr.<aws-region>.amazonaws.com/django-ec2:nginx-proxy
restart: always
ports:
- 443:443
- 80:80
volumes:
- static_volume:/home/app/web/staticfiles
- media_volume:/home/app/web/mediafiles
- certs:/etc/nginx/certs
- html:/usr/share/nginx/html
- vhost:/etc/nginx/vhost.d
- /var/run/docker.sock:/tmp/docker.sock:ro
depends_on:
- web
nginx-proxy-letsencrypt:
image: jrcs/letsencrypt-nginx-proxy-companion
env_file:
- ./.env.staging.proxy-companion
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- certs:/etc/nginx/certs
- html:/usr/share/nginx/html
- vhost:/etc/nginx/vhost.d
- acme:/etc/acme.sh
depends_on:
- nginx-proxy
volumes:
static_volume:
media_volume:
certs:
html:
vhost:
acme:
Para os serviços web
e nginx-proxy
, atualize as image
propriedades para usar imagens do ECR (que adicionaremos em breve).
Exemplos:
image: 123456789.dkr.ecr.us-east-1.amazonaws.com/django-ec2:web
image: 123456789.dkr.ecr.us-east-1.amazonaws.com/django-ec2:nginx-proxy
Os valores consistem na URL do repositório ( 123456789.dkr.ecr.us-east-1.amazonaws.com
) junto com o nome da imagem ( django-ec2
) e as tags ( web
e nginx-proxy
).
Para simplificar, estamos usando um único registro para armazenar as duas imagens. Usamos o
web
enginx-proxy
para diferenciar entre os dois. Idealmente, você deve usar dois registros: um paraweb
e outro paranginx-proxy
. Atualize isso por conta própria, se desejar.
Além das image
propriedades, também removemos o db
serviço (e o volume relacionado), pois estamos usando o RDS em vez de gerenciar o Postgres em um contêiner.
É hora de configurar os arquivos de ambiente para os contêineres web
e nginx-proxy-letsencrypt
.
Primeiro, adicione um arquivo .env.staging para o web
contêiner:
DEBUG=0
SECRET_KEY=change_me
DJANGO_ALLOWED_HOSTS=<YOUR_DOMAIN.COM>
SQL_ENGINE=django.db.backends.postgresql
SQL_DATABASE=djangoec2
SQL_USER=webapp
SQL_PASSWORD=<PASSWORD-FROM-AWS-RDS>
SQL_HOST=<DATABASE-ENDPOINT-FROM-AWS-RDS>
SQL_PORT=5432
DATABASE=postgres
VIRTUAL_HOST=<YOUR_DOMAIN.COM>
VIRTUAL_PORT=8000
LETSENCRYPT_HOST=<YOUR_DOMAIN.COM>
Notas:
<YOUR_DOMAIN.COM>
para o seu domínio real.SQL_PASSWORD
e SQL_HOST
para corresponder aos criados na seção RDS.SECRET_KEY
para alguma string aleatória longa.VIRTUAL_HOST
e VIRTUAL_PORT
são necessários pelo nginx-proxy
contêiner para criar automaticamente a configuração do proxy reverso.LETSENCRYPT_HOST
existe para que nginx-proxy-companion
possa emitir o certificado Let's Encrypt para o seu domínio.Para fins de teste/depuração, você pode usar a
*
pelaDJANGO_ALLOWED_HOSTS
primeira vez para simplificar as coisas. Só não se esqueça de limitar os hosts permitidos assim que o teste for concluído.
Em segundo lugar, adicione um arquivo .env.staging.proxy-companion , certificando-se de atualizar o DEFAULT_EMAIL
valor:
DEFAULT_EMAIL=youremail@yourdomain.com
ACME_CA_URI=https://acme-staging-v02.api.letsencrypt.org/directory
NGINX_PROXY_CONTAINER=nginx-proxy
Agora estamos prontos para construir as imagens do Docker:
$ docker-compose -f docker-compose.staging.yml build
Pode levar alguns minutos para construir. Uma vez feito, estamos prontos para enviar as imagens para o ECR.
Primeiro, supondo que você tenha o awscli instalado e que tenha definido suas credenciais da AWS , faça login no repositório ECR Docker:
$ aws ecr get-login-password --region <aws-region> | docker login --username AWS --password-stdin <aws-account-id>.dkr.ecr.<aws-region>.amazonaws.com
# aws ecr get-login-password --region us-east-1 | docker login --username AWS --password-stdin 123456789.dkr.ecr.us-east-1.amazonaws.com
Você deveria ver:
Login Succeeded
Em seguida, envie as imagens para o ECR:
$ docker-compose -f docker-compose.staging.yml push
Abra seu repositório ECR django-ec2 para ver as imagens enviadas:
Tudo está configurado para implantação.
É hora de migrar para sua instância do EC2.
Supondo que você tenha um diretório de projeto criado em sua instância, como /home/ubuntu/django-on-docker , copie os arquivos e pastas com o SCP:
$ scp -i /path/to/your/djangoletsencrypt.pem \
-r $(pwd)/{app,nginx,.env.staging,.env.staging.proxy-companion,docker-compose.staging.yml} \
ubuntu@public-ip-or-domain-of-ec2-instance:/path/to/django-on-docker
Em seguida, conecte-se à sua instância via SSH e vá para o diretório do projeto:
$ ssh -i /path/to/your/djangoletsencrypt.pem ubuntu@public-ip-or-domain-of-ec2-instance
$ cd /path/to/django-on-docker
Faça login no repositório ECR Docker.
$ aws ecr get-login-password --region <aws-region> | docker login --username AWS --password-stdin <aws-account-id>.dkr.ecr.<aws-region>.amazonaws.com
Puxe as imagens:
$ docker pull <aws-account-id>.dkr.ecr.<aws-region>.amazonaws.com/django-ec2:web
$ docker pull <aws-account-id>.dkr.ecr.<aws-region>.amazonaws.com/django-ec2:nginx-proxy
Com isso, você está pronto para ativar os contêineres:
$ docker-compose -f docker-compose.staging.yml up -d
Quando os contêineres estiverem funcionando, navegue até seu domínio no navegador. Você deve ver algo como:
Isso é esperado. Essa tela é exibida porque o certificado foi emitido de um ambiente de teste .
Como saber se tudo funciona?
Clique em "Avançado" e depois em "Continuar". Agora você deve ver seu aplicativo. Carregue uma imagem e, em seguida, certifique-se de que pode visualizar a imagem em https://yourdomain.com/media/IMAGE_FILE_NAME
.
Agora que tudo funciona como esperado, podemos passar para o ambiente de produção do Let's Encrypt.
Desative os contêineres existentes e saia da sua instância:
$ docker-compose -f docker-compose.staging.yml down -v
$ exit
De volta à sua máquina local, abra docker-compose.prod.yml e faça as mesmas alterações que você fez para a versão de teste:
ìmage
propriedades para corresponder aos URLs do AWS ECR para os serviços ẁeb
enginx-proxy
db
serviço junto com o volume relacionadoversion: '3.8'
services:
web:
build:
context: ./app
dockerfile: Dockerfile.prod
image: 046505967931.dkr.ecr.us-east-1.amazonaws.com/django-ec2:web
command: gunicorn hello_django.wsgi:application --bind 0.0.0.0:8000
volumes:
- static_volume:/home/app/web/staticfiles
- media_volume:/home/app/web/mediafiles
expose:
- 8000
env_file:
- ./.env.prod
nginx-proxy:
container_name: nginx-proxy
build: nginx
image: 046505967931.dkr.ecr.us-east-1.amazonaws.com/django-ec2:nginx-proxy
restart: always
ports:
- 443:443
- 80:80
volumes:
- static_volume:/home/app/web/staticfiles
- media_volume:/home/app/web/mediafiles
- certs:/etc/nginx/certs
- html:/usr/share/nginx/html
- vhost:/etc/nginx/vhost.d
- /var/run/docker.sock:/tmp/docker.sock:ro
depends_on:
- web
nginx-proxy-letsencrypt:
image: jrcs/letsencrypt-nginx-proxy-companion
env_file:
- ./.env.prod.proxy-companion
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- certs:/etc/nginx/certs
- html:/usr/share/nginx/html
- vhost:/etc/nginx/vhost.d
- acme:/etc/acme.sh
depends_on:
- nginx-proxy
volumes:
static_volume:
media_volume:
certs:
html:
vhost:
acme:
Em seguida, crie um arquivo .env.prod duplicando o arquivo .env.staging . Você não precisa fazer nenhuma alteração nele.
Por fim, adicione um arquivo .env.prod.proxy-companion :
DEFAULT_EMAIL=youremail@yourdomain.com
NGINX_PROXY_CONTAINER=nginx-proxy
Crie e envie imagens novamente:
$ docker-compose -f docker-compose.prod.yml build
$ aws ecr get-login-password --region <aws-region> | docker login --username AWS --password-stdin <aws-account-id>.dkr.ecr.<aws-region>.amazonaws.com
$ docker-compose -f docker-compose.prod.yml push
Copie os novos arquivos e pastas para sua instância com SCP:
$ scp -i /path/to/your/djangoletsencrypt.pem \
$(pwd)/{.env.prod,.env.prod.proxy-companion,docker-compose.prod.yml} \
ubuntu@public-ip-or-domain-of-ec2-instance:/path/to/django-on-docker
Como antes, conecte-se à sua instância via SSH e vá para o diretório do projeto:
$ ssh -i /path/to/your/djangoletsencrypt.pem ubuntu@public-ip-or-domain-of-ec2-instance
$ cd /path/to/django-on-docker
Faça login no seu repositório ECR Docker novamente:
$ aws ecr get-login-password --region <aws-region> | docker login --username AWS --password-stdin <aws-account-id>.dkr.ecr.<aws-region>.amazonaws.com
Puxe as imagens:
$ docker pull <aws-account-id>.dkr.ecr.<aws-region>.amazonaws.com/django-ec2:web
$ docker pull <aws-account-id>.dkr.ecr.<aws-region>.amazonaws.com/django-ec2:nginx-proxy
E, finalmente, gire os contêineres:
$ docker-compose -f docker-compose.prod.yml up -d
Navegue até o seu domínio novamente. Você não deve mais ver um aviso.
Parabéns! Agora você está usando um certificado Let's Encrypt de produção para seu aplicativo Django em execução no AWS EC2.
Quer ver o processo de criação do certificado em ação, confira os logs:
$ docker-compose -f docker-compose.prod.yml logs nginx-proxy-letsencrypt
Neste tutorial, você implantou um aplicativo Django em contêiner no EC2. O aplicativo está sendo executado por trás de um proxy HTTPS Nginx com certificados Let's Encrypt SSL. Você também usou uma instância do RDS Postgres e armazenou imagens do Docker no ECR.
Fonte: https://testdrive.io
1660749420
Neste tutorial, implantaremos um aplicativo Django no AWS EC2 com o Docker. O aplicativo será executado por trás de um proxy HTTPS Nginx que usa certificados Let's Encrypt SSL. Usaremos o AWS RDS para servir nosso banco de dados Postgres junto com o AWS ECR para armazenar e gerenciar nossas imagens do Docker.
Ao final deste tutorial, você será capaz de:
Este post se baseia nos posts Dockerizing Django com Postgres, Gunicorn e Nginx e Protegendo um Aplicativo Django Containerizado com Let's Encrypt .
Ele assume que você pode:
Primeiro, crie uma conta da AWS , caso ainda não tenha uma.
Em seguida, navegue até o console do EC2 e clique em Launch instance :
Use o Ubuntu Server 18.04 LTS (HVM) para a imagem do servidor (AMI):
Na próxima etapa, fique com a instância t2.micro . Clique em Avançar: Configurar detalhes da instância :
Na etapa Configure Instance Details , deixe tudo como está para manter as coisas simples. Em seguida, clique em Avançar algumas vezes até chegar à etapa Configurar Grupo de Segurança .
Com Criar um novo grupo de segurança selecionado, defina o nome e a descrição django-ec2
e adicione duas regras:
Essas regras são necessárias para emitir certificados e acessar o aplicativo.
As regras de entrada do grupo de segurança são usadas para limitar o acesso à sua instância pela Internet. A menos que você tenha alguns requisitos de segurança adicionais, provavelmente desejará permitir tráfego HTTP e HTTPS de qualquer lugar para instâncias que hospedam aplicativos da web. O SSH deve ser permitido para você se conectar à instância para configuração e implantação.
Clique em Revisar e Iniciar . Na próxima tela, clique em Iniciar .
Você será solicitado a selecionar um par de chaves. Você precisa dele para conexão SSH com sua instância. Selecione Criar um novo par de chaves e nomeie-o djangoletsencrypt
. Em seguida, clique em Baixar par de chaves . Após o download do par de chaves, clique em Launch Instances :
Levará alguns minutos para a instância girar.
Nesta seção, instalaremos o Docker na instância, adicionaremos um IP elástico e configuraremos uma função do IAM.
Navegue de volta ao console do EC2 , selecione a instância recém-criada e pegue o endereço IP público:
Conecte-se à sua instância do EC2 usando a .pem
chave que baixamos na etapa "AWS EC2".
$ ssh -i /path/to/your/djangoletsencrypt.pem ubuntu@public-ip-or-domain-of-ec2-instance
Seu
.pem
provavelmente foi baixado em um caminho como ~/Downloads/djangoletsencrypt.pem. Se você não tiver certeza de onde armazená-lo, mova-o para o diretório ~/.ssh . Você também pode ter que alterar as permissões -- ou seja,chmod 400 -i /path/to/your/djangoletsencrypt.pem
.
Comece instalando a versão mais recente do Docker e a versão 1.29.2 do Docker Compose:
$ sudo apt update
$ sudo apt install apt-transport-https ca-certificates curl software-properties-common
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
$ sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu bionic stable"
$ sudo apt update
$ sudo apt install docker-ce
$ sudo usermod -aG docker ${USER}
$ sudo curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
$ sudo chmod +x /usr/local/bin/docker-compose
$ docker -v
Docker version 20.10.8, build 3967b7d
$ docker-compose -v
docker-compose version 1.29.2, build 5becea4c
Primeiro, instale o descompacte:
$ sudo apt install unzip
Faça download do ZIP da AWS CLI:
$ curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
Descompacte seu conteúdo:
$ unzip awscliv2.zip
Instale a AWS CLI:
$ sudo ./aws/install
Verifique a instalação:
$ aws --version
Por padrão, as instâncias recebem um novo endereço IP público sempre que são iniciadas e reiniciadas.
O IP elástico permite alocar IPs estáticos para suas instâncias do EC2, para que o IP permaneça o mesmo o tempo todo e possa ser reassociado entre as instâncias. É recomendável usar um para sua configuração de produção.
Navegue até Elastic IPs e clique em Allocate Elastic IP address :
Em seguida, clique em Alocar :
Clique em Associar este endereço IP elástico :
Selecione sua instância e clique em Associar :
Usaremos o AWS ECR para extrair imagens do AWS ECR para nossa instância do EC2 durante a implantação. Como não permitiremos acesso público à imagem do Docker no ECR, você precisará criar uma função do IAM com permissões para extrair imagens do Docker do ECR e anexá-las à sua instância do EC2.
Navegue até o console do IAM .
Clique em Funções na barra lateral esquerda e depois em Criar função :
Selecione AWS Service e EC2 e clique em Next: Permissions :
Digite container
na caixa de pesquisa, selecione a política AmazonEC2ContainerRegistryPowerUser e clique em Next: Tags :
Clique em Avançar: Revisar . Use django-ec2
para o nome e clique em Criar função :
Agora você precisa anexar a nova função à sua instância do EC2.
De volta ao console do EC2 , clique em Instâncias e selecione sua instância. Clique no menu suspenso Actions -> Instance settings -> Attach/Replace IAM Role :
Selecione a função django-ec2 e clique em Aplicar .
Clique em Fechar .
Adicione um registro A ao seu DNS, para o domínio que você está usando, para apontar para o IP público da sua instância do EC2.
É o IP elástico que você associou à sua instância.
O Amazon Elastic Container Registry (ECR) é um registro de imagem totalmente gerenciado do Docker que facilita o armazenamento e o gerenciamento de imagens para os desenvolvedores. Para imagens privadas, o acesso é gerenciado por meio de usuários e funções do IAM.
Navegue até o console do ECR . Clique em Repositórios na barra lateral e depois em Criar repositório :
Defina o nome django-ec2
e clique em Criar repositório :
Agora podemos configurar um banco de dados RDS Postgres.
Embora você possa executar seu próprio banco de dados Postgres em um contêiner, já que bancos de dados são serviços críticos , adicionar camadas adicionais, como o Docker, adiciona riscos desnecessários na produção. Para simplificar tarefas como atualizações de versões secundárias, backups regulares e dimensionamento, é recomendável usar um serviço gerenciado. Então, vamos usar RDS .
Navegue até o console do RDS . Clique em Criar banco de dados :
Selecione a versão mais recente do Postgres com o modelo de nível gratuito :
Em Configurações , defina:
djangoec2
webapp
Fique com as configurações padrão para:
Pule para a seção Conectividade e defina o seguinte:
django-ec2
Deixe a autenticação do banco de dados como está.
Abra a configuração adicional e altere o nome do banco de dados inicial para djangoec2
:
Deixe as outras configurações como estão.
Por fim, clique em Criar banco de dados .
Clique em Exibir detalhes das credenciais para ver a senha gerada para o usuário do webapp :
Guarde esta senha em algum lugar seguro. Você precisará fornecê-lo ao aplicativo Django aqui em breve.
Levará alguns minutos para a instância girar. Uma vez ativado, clique no DB Identifier do banco de dados recém-criado para ver seus detalhes. Anote o endpoint do banco de dados; você precisará configurá-lo em seu aplicativo Django.
No console do EC2 , clique em Grupos de segurança na barra lateral. Encontre e clique no ID do grupo django-ec2 para editar seus detalhes.
Clique em Editar regras de entrada :
Adicione uma regra de entrada que permitirá conexões Postgres com instâncias dentro desse grupo de segurança. Fazer isso:
Para limitar o acesso ao seu banco de dados, somente conexões de instâncias dentro do mesmo Security Group são permitidas. Nosso aplicativo pode se conectar porque definimos o mesmo grupo de segurança, django-ec2 , para as instâncias RDS e EC2. Instâncias dentro de outros grupos de segurança, portanto, não têm permissão para se conectar.
Com a infraestrutura da AWS configurada, agora precisamos configurar nosso projeto Django localmente antes de implantá-lo.
Primeiro, clone o conteúdo do repositório do projeto GitHub:
$ git clone https://github.com/testdrivenio/django-on-docker-letsencrypt django-on-docker-letsencrypt-aws
$ cd django-on-docker-letsencrypt-aws
Este repositório contém tudo o que você precisa para implantar um Django Dockerizado com certificados Let's Encrypt HTTPS.
Quando o aplicativo for implantado pela primeira vez, você deve seguir estas duas etapas para evitar problemas com certificados:
Você pode ler mais sobre as limitações do Let's Encrypt em ambientes de produção na seção Let's Encrypt do post anterior, Protegendo um aplicativo Django em contêiner com o Let's Encrypt .
Para testar, atualize o docker-compose.staging.yml. arquivo assim:
version: '3.8'
services:
web:
build:
context: ./app
dockerfile: Dockerfile.prod
image: <aws-account-id>.dkr.ecr.<aws-region>.amazonaws.com/django-ec2:web
command: gunicorn hello_django.wsgi:application --bind 0.0.0.0:8000
volumes:
- static_volume:/home/app/web/staticfiles
- media_volume:/home/app/web/mediafiles
expose:
- 8000
env_file:
- ./.env.staging
nginx-proxy:
container_name: nginx-proxy
build: nginx
image: <aws-account-id>.dkr.ecr.<aws-region>.amazonaws.com/django-ec2:nginx-proxy
restart: always
ports:
- 443:443
- 80:80
volumes:
- static_volume:/home/app/web/staticfiles
- media_volume:/home/app/web/mediafiles
- certs:/etc/nginx/certs
- html:/usr/share/nginx/html
- vhost:/etc/nginx/vhost.d
- /var/run/docker.sock:/tmp/docker.sock:ro
depends_on:
- web
nginx-proxy-letsencrypt:
image: jrcs/letsencrypt-nginx-proxy-companion
env_file:
- ./.env.staging.proxy-companion
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- certs:/etc/nginx/certs
- html:/usr/share/nginx/html
- vhost:/etc/nginx/vhost.d
- acme:/etc/acme.sh
depends_on:
- nginx-proxy
volumes:
static_volume:
media_volume:
certs:
html:
vhost:
acme:
Para os serviços web
e nginx-proxy
, atualize as image
propriedades para usar imagens do ECR (que adicionaremos em breve).
Exemplos:
image: 123456789.dkr.ecr.us-east-1.amazonaws.com/django-ec2:web
image: 123456789.dkr.ecr.us-east-1.amazonaws.com/django-ec2:nginx-proxy
Os valores consistem na URL do repositório ( 123456789.dkr.ecr.us-east-1.amazonaws.com
) junto com o nome da imagem ( django-ec2
) e as tags ( web
e nginx-proxy
).
Para simplificar, estamos usando um único registro para armazenar as duas imagens. Usamos o
web
enginx-proxy
para diferenciar entre os dois. Idealmente, você deve usar dois registros: um paraweb
e outro paranginx-proxy
. Atualize isso por conta própria, se desejar.
Além das image
propriedades, também removemos o db
serviço (e o volume relacionado), pois estamos usando o RDS em vez de gerenciar o Postgres em um contêiner.
É hora de configurar os arquivos de ambiente para os contêineres web
e nginx-proxy-letsencrypt
.
Primeiro, adicione um arquivo .env.staging para o web
contêiner:
DEBUG=0
SECRET_KEY=change_me
DJANGO_ALLOWED_HOSTS=<YOUR_DOMAIN.COM>
SQL_ENGINE=django.db.backends.postgresql
SQL_DATABASE=djangoec2
SQL_USER=webapp
SQL_PASSWORD=<PASSWORD-FROM-AWS-RDS>
SQL_HOST=<DATABASE-ENDPOINT-FROM-AWS-RDS>
SQL_PORT=5432
DATABASE=postgres
VIRTUAL_HOST=<YOUR_DOMAIN.COM>
VIRTUAL_PORT=8000
LETSENCRYPT_HOST=<YOUR_DOMAIN.COM>
Notas:
<YOUR_DOMAIN.COM>
para o seu domínio real.SQL_PASSWORD
e SQL_HOST
para corresponder aos criados na seção RDS.SECRET_KEY
para alguma string aleatória longa.VIRTUAL_HOST
e VIRTUAL_PORT
são necessários pelo nginx-proxy
contêiner para criar automaticamente a configuração do proxy reverso.LETSENCRYPT_HOST
existe para que nginx-proxy-companion
possa emitir o certificado Let's Encrypt para o seu domínio.Para fins de teste/depuração, você pode usar a
*
pelaDJANGO_ALLOWED_HOSTS
primeira vez para simplificar as coisas. Só não se esqueça de limitar os hosts permitidos assim que o teste for concluído.
Em segundo lugar, adicione um arquivo .env.staging.proxy-companion , certificando-se de atualizar o DEFAULT_EMAIL
valor:
DEFAULT_EMAIL=youremail@yourdomain.com
ACME_CA_URI=https://acme-staging-v02.api.letsencrypt.org/directory
NGINX_PROXY_CONTAINER=nginx-proxy
Agora estamos prontos para construir as imagens do Docker:
$ docker-compose -f docker-compose.staging.yml build
Pode levar alguns minutos para construir. Uma vez feito, estamos prontos para enviar as imagens para o ECR.
Primeiro, supondo que você tenha o awscli instalado e que tenha definido suas credenciais da AWS , faça login no repositório ECR Docker:
$ aws ecr get-login-password --region <aws-region> | docker login --username AWS --password-stdin <aws-account-id>.dkr.ecr.<aws-region>.amazonaws.com
# aws ecr get-login-password --region us-east-1 | docker login --username AWS --password-stdin 123456789.dkr.ecr.us-east-1.amazonaws.com
Você deveria ver:
Login Succeeded
Em seguida, envie as imagens para o ECR:
$ docker-compose -f docker-compose.staging.yml push
Abra seu repositório ECR django-ec2 para ver as imagens enviadas:
Tudo está configurado para implantação.
É hora de migrar para sua instância do EC2.
Supondo que você tenha um diretório de projeto criado em sua instância, como /home/ubuntu/django-on-docker , copie os arquivos e pastas com o SCP:
$ scp -i /path/to/your/djangoletsencrypt.pem \
-r $(pwd)/{app,nginx,.env.staging,.env.staging.proxy-companion,docker-compose.staging.yml} \
ubuntu@public-ip-or-domain-of-ec2-instance:/path/to/django-on-docker
Em seguida, conecte-se à sua instância via SSH e vá para o diretório do projeto:
$ ssh -i /path/to/your/djangoletsencrypt.pem ubuntu@public-ip-or-domain-of-ec2-instance
$ cd /path/to/django-on-docker
Faça login no repositório ECR Docker.
$ aws ecr get-login-password --region <aws-region> | docker login --username AWS --password-stdin <aws-account-id>.dkr.ecr.<aws-region>.amazonaws.com
Puxe as imagens:
$ docker pull <aws-account-id>.dkr.ecr.<aws-region>.amazonaws.com/django-ec2:web
$ docker pull <aws-account-id>.dkr.ecr.<aws-region>.amazonaws.com/django-ec2:nginx-proxy
Com isso, você está pronto para ativar os contêineres:
$ docker-compose -f docker-compose.staging.yml up -d
Quando os contêineres estiverem funcionando, navegue até seu domínio no navegador. Você deve ver algo como:
Isso é esperado. Essa tela é exibida porque o certificado foi emitido de um ambiente de teste .
Como saber se tudo funciona?
Clique em "Avançado" e depois em "Continuar". Agora você deve ver seu aplicativo. Carregue uma imagem e, em seguida, certifique-se de que pode visualizar a imagem em https://yourdomain.com/media/IMAGE_FILE_NAME
.
Agora que tudo funciona como esperado, podemos passar para o ambiente de produção do Let's Encrypt.
Desative os contêineres existentes e saia da sua instância:
$ docker-compose -f docker-compose.staging.yml down -v
$ exit
De volta à sua máquina local, abra docker-compose.prod.yml e faça as mesmas alterações que você fez para a versão de teste:
ìmage
propriedades para corresponder aos URLs do AWS ECR para os serviços ẁeb
enginx-proxy
db
serviço junto com o volume relacionadoversion: '3.8'
services:
web:
build:
context: ./app
dockerfile: Dockerfile.prod
image: 046505967931.dkr.ecr.us-east-1.amazonaws.com/django-ec2:web
command: gunicorn hello_django.wsgi:application --bind 0.0.0.0:8000
volumes:
- static_volume:/home/app/web/staticfiles
- media_volume:/home/app/web/mediafiles
expose:
- 8000
env_file:
- ./.env.prod
nginx-proxy:
container_name: nginx-proxy
build: nginx
image: 046505967931.dkr.ecr.us-east-1.amazonaws.com/django-ec2:nginx-proxy
restart: always
ports:
- 443:443
- 80:80
volumes:
- static_volume:/home/app/web/staticfiles
- media_volume:/home/app/web/mediafiles
- certs:/etc/nginx/certs
- html:/usr/share/nginx/html
- vhost:/etc/nginx/vhost.d
- /var/run/docker.sock:/tmp/docker.sock:ro
depends_on:
- web
nginx-proxy-letsencrypt:
image: jrcs/letsencrypt-nginx-proxy-companion
env_file:
- ./.env.prod.proxy-companion
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- certs:/etc/nginx/certs
- html:/usr/share/nginx/html
- vhost:/etc/nginx/vhost.d
- acme:/etc/acme.sh
depends_on:
- nginx-proxy
volumes:
static_volume:
media_volume:
certs:
html:
vhost:
acme:
Em seguida, crie um arquivo .env.prod duplicando o arquivo .env.staging . Você não precisa fazer nenhuma alteração nele.
Por fim, adicione um arquivo .env.prod.proxy-companion :
DEFAULT_EMAIL=youremail@yourdomain.com
NGINX_PROXY_CONTAINER=nginx-proxy
Crie e envie imagens novamente:
$ docker-compose -f docker-compose.prod.yml build
$ aws ecr get-login-password --region <aws-region> | docker login --username AWS --password-stdin <aws-account-id>.dkr.ecr.<aws-region>.amazonaws.com
$ docker-compose -f docker-compose.prod.yml push
Copie os novos arquivos e pastas para sua instância com SCP:
$ scp -i /path/to/your/djangoletsencrypt.pem \
$(pwd)/{.env.prod,.env.prod.proxy-companion,docker-compose.prod.yml} \
ubuntu@public-ip-or-domain-of-ec2-instance:/path/to/django-on-docker
Como antes, conecte-se à sua instância via SSH e vá para o diretório do projeto:
$ ssh -i /path/to/your/djangoletsencrypt.pem ubuntu@public-ip-or-domain-of-ec2-instance
$ cd /path/to/django-on-docker
Faça login no seu repositório ECR Docker novamente:
$ aws ecr get-login-password --region <aws-region> | docker login --username AWS --password-stdin <aws-account-id>.dkr.ecr.<aws-region>.amazonaws.com
Puxe as imagens:
$ docker pull <aws-account-id>.dkr.ecr.<aws-region>.amazonaws.com/django-ec2:web
$ docker pull <aws-account-id>.dkr.ecr.<aws-region>.amazonaws.com/django-ec2:nginx-proxy
E, finalmente, gire os contêineres:
$ docker-compose -f docker-compose.prod.yml up -d
Navegue até o seu domínio novamente. Você não deve mais ver um aviso.
Parabéns! Agora você está usando um certificado Let's Encrypt de produção para seu aplicativo Django em execução no AWS EC2.
Quer ver o processo de criação do certificado em ação, confira os logs:
$ docker-compose -f docker-compose.prod.yml logs nginx-proxy-letsencrypt
Neste tutorial, você implantou um aplicativo Django em contêiner no EC2. O aplicativo está sendo executado por trás de um proxy HTTPS Nginx com certificados Let's Encrypt SSL. Você também usou uma instância do RDS Postgres e armazenou imagens do Docker no ECR.
Fonte: https://testdrive.io
1620177818
Welcome to my blog , hey everyone in this article you learn how to customize the Django app and view in the article you will know how to register and unregister models from the admin view how to add filtering how to add a custom input field, and a button that triggers an action on all objects and even how to change the look of your app and page using the Django suit package let’s get started.
#django #create super user django #customize django admin dashboard #django admin #django admin custom field display #django admin customization #django admin full customization #django admin interface #django admin register all models #django customization
1660374600
Este artigo analisa como implantar um aplicativo Django no Heroku com o Docker por meio do Heroku Container Runtime.
Ao final deste tutorial, você será capaz de:
Juntamente com as implantações tradicionais do compilador Git plus slug ( git push heroku master
), o Heroku também oferece suporte a implantações baseadas em Docker, com o Heroku Container Runtime.
As implantações baseadas em Docker têm muitas vantagens sobre a abordagem tradicional:
Em geral, as implantações baseadas em Docker oferecem maior flexibilidade e controle sobre o ambiente de implantação. Você pode implantar os aplicativos desejados no ambiente desejado. Dito isso, agora você é responsável pelas atualizações de segurança. Com as implantações tradicionais baseadas em Git, o Heroku é responsável por isso. Eles aplicam atualizações de segurança relevantes em seus Stacks e migram seu aplicativo para os novos Stacks conforme necessário. Mantenha isso em mente.
Atualmente, existem duas maneiras de implantar aplicativos com o Docker no Heroku:
A principal diferença entre esses dois é que com a última abordagem -- por exemplo, através do Build Manifest -- você tem acesso aos recursos Pipelines , Review e Release . Portanto, se você estiver convertendo um aplicativo de uma implantação baseada em Git para o Docker e estiver usando qualquer um desses recursos, deverá usar a abordagem Build Manifest.
Fique tranquilo, veremos as duas abordagens neste artigo.
Em ambos os casos, você ainda terá acesso à CLI do Heroku, a todos os complementos poderosos e ao painel . Todos esses recursos funcionam com o Container Runtime, em outras palavras.
Tipo de implantação | Mecanismo de implantação | Atualizações de segurança (quem trata) | Acesso a pipelines, revisão, liberação | Acesso à CLI, complementos e painel | Limites de tamanho do slug |
---|---|---|---|---|---|
Compilador Git + Slug | Git Push | Heroku | Sim | Sim | Sim |
Docker + tempo de execução do contêiner | Docker Push | Você | Não | Sim | Não |
Docker + Build Manifest | Git Push | Você | Sim | Sim | Não |
Tenha em mente que as implantações baseadas em Docker são limitadas às mesmas restrições que as implantações baseadas em Git. Por exemplo, volumes persistentes não são suportados, pois o sistema de arquivos é efêmero e os processos da Web suportam apenas solicitações HTTP(S). Para saber mais sobre isso, revise os comandos do Dockerfile e o tempo de execução .
Janela de encaixe | Heroku |
---|---|
Dockerfile | BuildPack |
Imagem | lesma |
Recipiente | Dinâmico |
Crie um diretório de projeto, crie e ative um novo ambiente virtual e instale o Django:
$ mkdir django-heroku-docker
$ cd django-heroku-docker
$ python3.10 -m venv env
$ source env/bin/activate
(env)$ pip install django==3.2.9
Sinta-se à vontade para trocar virtualenv e Pip por Poetry ou Pipenv . Para saber mais, revise Ambientes Python Modernos .
Em seguida, crie um novo projeto Django, aplique as migrações e execute o servidor:
(env)$ django-admin startproject hello_django .
(env)$ python manage.py migrate
(env)$ python manage.py runserver
Navegue até http://localhost:8000/ para ver a tela de boas-vindas do Django. Mate o servidor e saia do ambiente virtual assim que terminar.
Adicione um Dockerfile à raiz do projeto:
# pull official base image
FROM python:3.10-alpine
# set work directory
WORKDIR /app
# set environment variables
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1
ENV DEBUG 0
# install psycopg2
RUN apk update \
&& apk add --virtual build-essential gcc python3-dev musl-dev \
&& apk add postgresql-dev \
&& pip install psycopg2
# install dependencies
COPY ./requirements.txt .
RUN pip install -r requirements.txt
# copy project
COPY . .
# add and run as non-root user
RUN adduser -D myuser
USER myuser
# run gunicorn
CMD gunicorn hello_django.wsgi:application --bind 0.0.0.0:$PORT
Aqui, começamos com uma imagem Docker baseada em Alpine para Python 3.10. Em seguida, definimos um diretório de trabalho junto com duas variáveis de ambiente:
PYTHONDONTWRITEBYTECODE
: Impede que o Python grave arquivos pyc no discoPYTHONUNBUFFERED
: Impede o Python de armazenar em buffer stdout e stderrEm seguida, instalamos dependências no nível do sistema e pacotes Python, copiamos os arquivos do projeto, criamos e mudamos para um usuário não root (o que é recomendado pelo Heroku ) e usamos o CMD para executar o Gunicorn quando um contêiner é executado em tempo de execução. Anote a $PORT
variável. Essencialmente, qualquer servidor da Web executado no Container Runtime deve escutar o tráfego HTTP na $PORT
variável de ambiente, que é definida pelo Heroku no runtime .
Crie um arquivo requirements.txt :
Django==3.2.9
gunicorn==20.1.0
Em seguida, adicione um arquivo .dockerignore :
__pycache__
*.pyc
env/
db.sqlite3
Atualize as variáveis SECRET_KEY
, DEBUG
e em settings.py :ALLOWED_HOSTS
SECRET_KEY = os.environ.get('SECRET_KEY', default='foo')
DEBUG = int(os.environ.get('DEBUG', default=0))
ALLOWED_HOSTS = ['localhost', '127.0.0.1']
Não esqueça da importação:
import os
Para testar localmente, crie a imagem e execute o contêiner, certificando-se de passar as variáveis de ambiente apropriadas:
$ docker build -t web:latest .
$ docker run -d --name django-heroku -e "PORT=8765" -e "DEBUG=1" -p 8007:8765 web:latest
Certifique-se de que o aplicativo esteja sendo executado em http://localhost:8007/ em seu navegador. Pare e remova o contêiner em execução assim que terminar:
$ docker stop django-heroku
$ docker rm django-heroku
Adicione um .gitignore :
__pycache__
*.pyc
env/
db.sqlite3
Em seguida, vamos criar uma visualização rápida do Django para testar facilmente o aplicativo quando o modo de depuração estiver desativado.
Adicione um arquivo views.py ao diretório "hello_django" :
from django.http import JsonResponse
def ping(request):
data = {'ping': 'pong!'}
return JsonResponse(data)
Em seguida, atualize urls.py :
from django.contrib import admin
from django.urls import path
from .views import ping
urlpatterns = [
path('admin/', admin.site.urls),
path('ping/', ping, name="ping"),
]
Teste isso novamente com o modo de depuração desativado:
$ docker build -t web:latest .
$ docker run -d --name django-heroku -e "PORT=8765" -e "DEBUG=0" -p 8007:8765 web:latest
Verifique se http://localhost:8007/ping/ funciona conforme o esperado:
{
"ping": "pong!"
}
Pare e remova o contêiner em execução assim que terminar:
$ docker stop django-heroku
$ docker rm django-heroku
Se você quiser usar o WhiteNoise para gerenciar seus ativos estáticos, primeiro adicione o pacote ao arquivo requirements.txt :
Django==3.2.9
gunicorn==20.1.0
whitenoise==5.3.0
Atualize o middleware em settings.py assim:
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'whitenoise.middleware.WhiteNoiseMiddleware', # new
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
Em seguida, configure o manuseio de seus arquivos estáticos com STATIC_ROOT
:
STATIC_ROOT = BASE_DIR / 'staticfiles'
Por fim, adicione suporte a compactação e armazenamento em cache:
STATICFILES_STORAGE = 'whitenoise.storage.CompressedManifestStaticFilesStorage'
Adicione o collectstatic
comando ao Dockerfile:
# pull official base image
FROM python:3.10-alpine
# set work directory
WORKDIR /app
# set environment variables
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1
ENV DEBUG 0
# install psycopg2
RUN apk update \
&& apk add --virtual build-essential gcc python3-dev musl-dev \
&& apk add postgresql-dev \
&& pip install psycopg2
# install dependencies
COPY ./requirements.txt .
RUN pip install -r requirements.txt
# copy project
COPY . .
# collect static files
RUN python manage.py collectstatic --noinput
# add and run as non-root user
RUN adduser -D myuser
USER myuser
# run gunicorn
CMD gunicorn hello_django.wsgi:application --bind 0.0.0.0:$PORT
Para testar, crie a nova imagem e ative um novo contêiner:
$ docker build -t web:latest .
$ docker run -d --name django-heroku -e "PORT=8765" -e "DEBUG=1" -p 8007:8765 web:latest
Você deve conseguir visualizar os arquivos estáticos ao executar:
$ docker exec django-heroku ls /app/staticfiles
$ docker exec django-heroku ls /app/staticfiles/admin
Pare e remova o contêiner em execução novamente:
$ docker stop django-heroku
$ docker rm django-heroku
Para colocar o Postgres em funcionamento, usaremos o pacote dj_database_url para gerar o dicionário de configuração de banco de dados adequado para as configurações do Django com base em uma DATABASE_URL
variável de ambiente.
Adicione a dependência ao arquivo de requisitos:
Django==3.2.9
dj-database-url==0.5.0
gunicorn==20.1.0
whitenoise==5.3.0
Em seguida, faça as seguintes alterações nas configurações para atualizar a configuração do banco de dados, se DATABASE_URL
estiver presente:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': BASE_DIR / 'db.sqlite3',
}
}
DATABASE_URL = os.environ.get('DATABASE_URL')
db_from_env = dj_database_url.config(default=DATABASE_URL, conn_max_age=500, ssl_require=True)
DATABASES['default'].update(db_from_env)
Portanto, se o DATABASE_URL
não estiver presente, o SQLite ainda será usado.
Adicione a importação ao topo também:
import dj_database_url
Testaremos isso daqui a pouco depois de criarmos um banco de dados Postgres no Heroku.
Inscreva-se na conta Heroku (se você ainda não tiver uma) e instale a CLI do Heroku (se ainda não tiver feito isso).
Crie um novo aplicativo:
$ heroku create
Creating app... done, ⬢ limitless-atoll-51647
https://limitless-atoll-51647.herokuapp.com/ | https://git.heroku.com/limitless-atoll-51647.git
Adicione a SECRET_KEY
variável de ambiente:
$ heroku config:set SECRET_KEY=SOME_SECRET_VALUE -a limitless-atoll-51647
Altere
SOME_SECRET_VALUE
para uma string gerada aleatoriamente com pelo menos 50 caracteres.
Adicione o URL do Heroku acima à lista de ALLOWED_HOSTS
em hello_django/settings.py assim:
ALLOWED_HOSTS = ['localhost', '127.0.0.1', 'limitless-atoll-51647.herokuapp.com']
Certifique-se de substituir
limitless-atoll-51647
cada um dos comandos acima pelo nome do seu aplicativo.
Neste ponto, estamos prontos para começar a implantar imagens do Docker no Heroku. Você decidiu qual abordagem gostaria de adotar?
Não tem certeza? Experimente os dois!
Pule esta seção se estiver usando a abordagem Build Manifest.
Novamente, com essa abordagem, você pode implantar imagens do Docker pré-criadas no Heroku.
Faça login no Heroku Container Registry , para indicar ao Heroku que queremos usar o Container Runtime:
$ heroku container:login
Reconstrua a imagem do Docker e marque-a com o seguinte formato:
registry.heroku.com/<app>/<process-type>
Certifique-se de substituir <app>
pelo nome do aplicativo Heroku que você acabou de criar e <process-type>
com web
o qual isso será para um processo da web .
Por exemplo:
$ docker build -t registry.heroku.com/limitless-atoll-51647/web .
Envie a imagem para o registro:
$ docker push registry.heroku.com/limitless-atoll-51647/web
Solte a imagem:
$ heroku container:release -a limitless-atoll-51647 web
Isso executará o contêiner. Você deve conseguir visualizar o aplicativo em https://APP_NAME.herokuapp.com . Deve retornar um 404.
Tente executar
heroku open -a limitless-atoll-51647
para abrir o aplicativo em seu navegador padrão.
Verifique se https://APP_NAME.herokuapp.com/ping também funciona:
{
"ping": "pong!"
}
Você também deve poder visualizar os arquivos estáticos:
$ heroku run ls /app/staticfiles -a limitless-atoll-51647
$ heroku run ls /app/staticfiles/admin -a limitless-atoll-51647
Certifique-se de substituir
limitless-atoll-51647
cada um dos comandos acima pelo nome do seu aplicativo.
Pule para a seção "Teste Postgres" uma vez feito.
Ignore esta seção se estiver usando a abordagem do Container Registry.
Novamente, com a abordagem Build Manifest , você pode fazer com que o Heroku crie e implante imagens do Docker com base em um arquivo de manifesto heroku.yml .
Defina a pilha do seu aplicativo como contêiner:
$ heroku stack:set container -a limitless-atoll-51647
Adicione um arquivo heroku.yml à raiz do projeto:
build:
docker:
web: Dockerfile
Aqui, estamos apenas dizendo ao Heroku qual Dockerfile usar para construir a imagem.
Junto com build
, você também pode definir as seguintes etapas:
setup
é usado para definir complementos e variáveis de configuração do Heroku a serem criados durante o provisionamento do aplicativo.release
é usado para definir tarefas que você gostaria de executar durante uma versão.run
é usado para definir quais comandos executar para os processos da Web e do trabalhador.Certifique-se de revisar a documentação do Heroku para saber mais sobre esses quatro estágios.
Vale a pena notar que o
gunicorn hello_django.wsgi:application --bind 0.0.0.0:$PORT
comando pode ser removido do Dockerfile e adicionado ao arquivo heroku.ymlrun
no estágio:build: docker: web: Dockerfile run: web: gunicorn hello_django.wsgi:application --bind 0.0.0.0:$PORT
Além disso, certifique-se de colocar o comando 'collectstatic' dentro do seu Dockerfile. Não o mova para o
release
palco. Para saber mais sobre isso, revise esta pergunta do Stack Overflow .
Em seguida, instale o heroku-manifest
plug-in do canal CLI beta:
$ heroku update beta
$ heroku plugins:install @heroku-cli/plugin-manifest
Com isso, inicialize um repositório Git e crie um commit.
Em seguida, adicione o controle remoto Heroku:
$ heroku git:remote -a limitless-atoll-51647
Envie o código para o Heroku para construir a imagem e executar o contêiner:
$ git push heroku master
Você deve conseguir visualizar o aplicativo em https://APP_NAME.herokuapp.com . Deve retornar um 404.
Tente executar
heroku open -a limitless-atoll-51647
para abrir o aplicativo em seu navegador padrão.
Verifique se https://APP_NAME.herokuapp.com/ping também funciona:
{
"ping": "pong!"
}
Você também deve poder visualizar os arquivos estáticos:
$ heroku run ls /app/staticfiles -a limitless-atoll-51647
$ heroku run ls /app/staticfiles/admin -a limitless-atoll-51647
Certifique-se de substituir
limitless-atoll-51647
cada um dos comandos acima pelo nome do seu aplicativo.
Crie o banco de dados:
$ heroku addons:create heroku-postgresql:hobby-dev -a limitless-atoll-51647
Este comando define automaticamente a
DATABASE_URL
variável de ambiente para o contêiner.
Quando o banco de dados estiver ativo, execute as migrações:
$ heroku run python manage.py makemigrations -a limitless-atoll-51647
$ heroku run python manage.py migrate -a limitless-atoll-51647
Em seguida, entre no psql para visualizar as tabelas recém-criadas:
$ heroku pg:psql -a limitless-atoll-51647
# \dt
List of relations
Schema | Name | Type | Owner
--------+----------------------------+-------+----------------
public | auth_group | table | siodzhzzcvnwwp
public | auth_group_permissions | table | siodzhzzcvnwwp
public | auth_permission | table | siodzhzzcvnwwp
public | auth_user | table | siodzhzzcvnwwp
public | auth_user_groups | table | siodzhzzcvnwwp
public | auth_user_user_permissions | table | siodzhzzcvnwwp
public | django_admin_log | table | siodzhzzcvnwwp
public | django_content_type | table | siodzhzzcvnwwp
public | django_migrations | table | siodzhzzcvnwwp
public | django_session | table | siodzhzzcvnwwp
(10 rows)
# \q
Novamente, certifique-se de substituir
limitless-atoll-51647
cada um dos comandos acima pelo nome do seu aplicativo Heroku.
Inscreva-se para uma conta do GitLab (se necessário) e crie um novo projeto (novamente, se necessário).
Recupere seu token de autenticação Heroku :
$ heroku auth:token
Em seguida, salve o token como uma nova variável chamada HEROKU_AUTH_TOKEN
nas configurações de CI/CD do seu projeto: Configurações > CI/CD > Variáveis.
Em seguida, precisamos adicionar um arquivo de configuração GitLab CI/CD chamado .gitlab-ci.yml à raiz do projeto. O conteúdo deste arquivo irá variar de acordo com a abordagem utilizada.
Pule esta seção se estiver usando a abordagem Build Manifest.
.gitlab-ci.yml :
image: docker:stable
services:
- docker:dind
variables:
DOCKER_DRIVER: overlay2
HEROKU_APP_NAME: <APP_NAME>
HEROKU_REGISTRY_IMAGE: registry.heroku.com/${HEROKU_APP_NAME}/web
stages:
- build_and_deploy
build_and_deploy:
stage: build_and_deploy
script:
- apk add --no-cache curl
- docker login -u _ -p $HEROKU_AUTH_TOKEN registry.heroku.com
- docker pull $HEROKU_REGISTRY_IMAGE || true
- docker build
--cache-from $HEROKU_REGISTRY_IMAGE
--tag $HEROKU_REGISTRY_IMAGE
--file ./Dockerfile
"."
- docker push $HEROKU_REGISTRY_IMAGE
- chmod +x ./release.sh
- ./release.sh
release.sh :
#!/bin/sh
IMAGE_ID=$(docker inspect ${HEROKU_REGISTRY_IMAGE} --format={{.Id}})
PAYLOAD='{"updates": [{"type": "web", "docker_image": "'"$IMAGE_ID"'"}]}'
curl -n -X PATCH https://api.heroku.com/apps/$HEROKU_APP_NAME/formation \
-d "${PAYLOAD}" \
-H "Content-Type: application/json" \
-H "Accept: application/vnd.heroku+json; version=3.docker-releases" \
-H "Authorization: Bearer ${HEROKU_AUTH_TOKEN}"
Aqui, definimos uma única build_and_deploy
etapa onde:
Certifique-se de substituir
<APP_NAME>
pelo nome do seu aplicativo Heroku.
Com isso, inicialize um repositório Git, confirme, adicione o controle remoto do GitLab e envie seu código para o GitLab para acionar um novo pipeline . Isso executará o build_and_deploy
estágio como um único trabalho. Depois de concluído, uma nova versão deve ser criada automaticamente no Heroku.
Ignore esta seção se estiver usando a abordagem do Container Registry.
.gitlab-ci.yml :
variables:
HEROKU_APP_NAME: <APP_NAME>
stages:
- deploy
deploy:
stage: deploy
script:
- apt-get update -qy
- apt-get install -y ruby-dev
- gem install dpl
- dpl --provider=heroku --app=$HEROKU_APP_NAME --api-key=$HEROKU_AUTH_TOKEN
Aqui, definimos uma única deploy
etapa onde:
Certifique-se de substituir
<APP_NAME>
pelo nome do seu aplicativo Heroku.
Confirme, adicione o controle remoto do GitLab e envie seu código para o GitLab para acionar um novo pipeline . Isso executará o deploy
estágio como um único trabalho. Depois de concluído, o código deve ser implantado no Heroku.
Em vez de apenas construir a imagem do Docker e criar uma versão no GitLab CI, vamos também executar os testes do Django, Flake8 , Black e isort .
Novamente, isso irá variar dependendo da abordagem que você usou.
Pule esta seção se estiver usando a abordagem Build Manifest.
Atualize .gitlab-ci.yml assim:
stages:
- build
- test
- deploy
variables:
IMAGE: ${CI_REGISTRY}/${CI_PROJECT_NAMESPACE}/${CI_PROJECT_NAME}
build:
stage: build
image: docker:stable
services:
- docker:dind
variables:
DOCKER_DRIVER: overlay2
script:
- docker login -u $CI_REGISTRY_USER -p $CI_JOB_TOKEN $CI_REGISTRY
- docker pull $IMAGE:latest || true
- docker build
--cache-from $IMAGE:latest
--tag $IMAGE:latest
--file ./Dockerfile
"."
- docker push $IMAGE:latest
test:
stage: test
image: $IMAGE:latest
services:
- postgres:latest
variables:
POSTGRES_DB: test
POSTGRES_USER: runner
POSTGRES_PASSWORD: ""
DATABASE_URL: postgresql://runner@postgres:5432/test
script:
- python manage.py test
- flake8 hello_django --max-line-length=100
- black hello_django --check
- isort hello_django --check --profile black
deploy:
stage: deploy
image: docker:stable
services:
- docker:dind
variables:
DOCKER_DRIVER: overlay2
HEROKU_APP_NAME: <APP_NAME>
HEROKU_REGISTRY_IMAGE: registry.heroku.com/${HEROKU_APP_NAME}/web
script:
- apk add --no-cache curl
- docker login -u _ -p $HEROKU_AUTH_TOKEN registry.heroku.com
- docker pull $HEROKU_REGISTRY_IMAGE || true
- docker build
--cache-from $HEROKU_REGISTRY_IMAGE
--tag $HEROKU_REGISTRY_IMAGE
--file ./Dockerfile
"."
- docker push $HEROKU_REGISTRY_IMAGE
- chmod +x ./release.sh
- ./release.sh
Certifique-se de substituir
<APP_NAME>
pelo nome do seu aplicativo Heroku.
Então, agora temos três estágios: build
, test
, e deploy
.
No build
palco, nós:
Então, no test
estágio nós configuramos o Postgres , configuramos a DATABASE_URL
variável de ambiente, e então rodamos os testes do Django, Flake8, Black, e isort usando a imagem que foi construída no estágio anterior.
No deploy
palco, nós:
Adicione as novas dependências ao arquivo de requisitos:
# prod
Django==3.2.9
dj-database-url==0.5.0
gunicorn==20.1.0
whitenoise==5.3.0
# dev and test
black==21.11b1
flake8==4.0.1
isort==5.10.1
Antes de enviar para o GitLab, execute os testes do Django localmente:
$ source env/bin/activate
(env)$ pip install -r requirements.txt
(env)$ python manage.py test
System check identified no issues (0 silenced).
----------------------------------------------------------------------
Ran 0 tests in 0.000s
OK
Certifique-se de que o Flake8 seja aprovado e atualize o código-fonte com base nas recomendações Black e isort:
(env)$ flake8 hello_django --max-line-length=100
(env)$ black hello_django
(env)$ isort hello_django --profile black
Confirme e envie seu código novamente. Certifique-se de que todos os estágios passem.
Ignore esta seção se estiver usando a abordagem do Container Registry.
Atualize .gitlab-ci.yml assim:
stages:
- build
- test
- deploy
variables:
IMAGE: ${CI_REGISTRY}/${CI_PROJECT_NAMESPACE}/${CI_PROJECT_NAME}
build:
stage: build
image: docker:stable
services:
- docker:dind
variables:
DOCKER_DRIVER: overlay2
script:
- docker login -u $CI_REGISTRY_USER -p $CI_JOB_TOKEN $CI_REGISTRY
- docker pull $IMAGE:latest || true
- docker build
--cache-from $IMAGE:latest
--tag $IMAGE:latest
--file ./Dockerfile
"."
- docker push $IMAGE:latest
test:
stage: test
image: $IMAGE:latest
services:
- postgres:latest
variables:
POSTGRES_DB: test
POSTGRES_USER: runner
POSTGRES_PASSWORD: ""
DATABASE_URL: postgresql://runner@postgres:5432/test
script:
- python manage.py test
- flake8 hello_django --max-line-length=100
- black hello_django --check
- isort hello_django --check --profile black
deploy:
stage: deploy
variables:
HEROKU_APP_NAME: <APP_NAME>
script:
- apt-get update -qy
- apt-get install -y ruby-dev
- gem install dpl
- dpl --provider=heroku --app=$HEROKU_APP_NAME --api-key=$HEROKU_AUTH_TOKEN
Certifique-se de substituir
<APP_NAME>
pelo nome do seu aplicativo Heroku.
Então, agora temos três estágios: build
, test
, e deploy
.
No build
palco, nós:
Então, no test
estágio nós configuramos o Postgres , configuramos a DATABASE_URL
variável de ambiente, e então rodamos os testes do Django, Flake8, Black, e isort usando a imagem que foi construída no estágio anterior.
No deploy
palco, nós:
Adicione as novas dependências ao arquivo de requisitos:
# prod
Django==3.2.9
dj-database-url==0.5.0
gunicorn==20.1.0
whitenoise==5.3.0
# dev and test
black==21.11b1
flake8==4.0.1
isort==5.10.1
Antes de enviar para o GitLab, execute os testes do Django localmente:
$ source env/bin/activate
(env)$ pip install -r requirements.txt
(env)$ python manage.py test
System check identified no issues (0 silenced).
----------------------------------------------------------------------
Ran 0 tests in 0.000s
OK
Certifique-se de que o Flake8 seja aprovado e atualize o código-fonte com base nas recomendações Black e isort:
(env)$ flake8 hello_django --max-line-length=100
(env)$ black hello_django
(env)$ isort hello_django --profile black
Confirme e envie seu código novamente. Certifique-se de que todos os estágios passem.
Por fim, atualize o Dockerfile dessa forma para usar uma compilação de vários estágios para reduzir o tamanho final da imagem:
FROM python:3.10-alpine AS build-python
RUN apk update && apk add --virtual build-essential gcc python3-dev musl-dev postgresql-dev
RUN python -m venv /opt/venv
ENV PATH="/opt/venv/bin:$PATH"
COPY ./requirements.txt .
RUN pip install -r requirements.txt
FROM python:3.10-alpine
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1
ENV DEBUG 0
ENV PATH="/opt/venv/bin:$PATH"
COPY --from=build-python /opt/venv /opt/venv
RUN apk update && apk add --virtual build-deps gcc python3-dev musl-dev postgresql-dev
RUN pip install psycopg2-binary
WORKDIR /app
COPY . .
RUN python manage.py collectstatic --noinput
RUN adduser -D myuser
USER myuser
CMD gunicorn hello_django.wsgi:application --bind 0.0.0.0:$PORT
Em seguida, precisamos atualizar a configuração do GitLab para aproveitar o cache de camada do Docker.
Pule esta seção se estiver usando a abordagem Build Manifest.
.gitlab-ci.yml :
stages:
- build
- test
- deploy
variables:
IMAGE: ${CI_REGISTRY}/${CI_PROJECT_NAMESPACE}/${CI_PROJECT_NAME}
HEROKU_APP_NAME: <APP_NAME>
HEROKU_REGISTRY_IMAGE: registry.heroku.com/${HEROKU_APP_NAME}/web
build:
stage: build
image: docker:stable
services:
- docker:dind
variables:
DOCKER_DRIVER: overlay2
script:
- docker login -u $CI_REGISTRY_USER -p $CI_JOB_TOKEN $CI_REGISTRY
- docker pull $IMAGE:build-python || true
- docker pull $IMAGE:production || true
- docker build
--target build-python
--cache-from $IMAGE:build-python
--tag $IMAGE:build-python
--file ./Dockerfile
"."
- docker build
--cache-from $IMAGE:production
--tag $IMAGE:production
--tag $HEROKU_REGISTRY_IMAGE
--file ./Dockerfile
"."
- docker push $IMAGE:build-python
- docker push $IMAGE:production
test:
stage: test
image: $IMAGE:production
services:
- postgres:latest
variables:
POSTGRES_DB: test
POSTGRES_USER: runner
POSTGRES_PASSWORD: ""
DATABASE_URL: postgresql://runner@postgres:5432/test
script:
- python manage.py test
- flake8 hello_django --max-line-length=100
- black hello_django --check
- isort hello_django --check --profile black
deploy:
stage: deploy
image: docker:stable
services:
- docker:dind
variables:
DOCKER_DRIVER: overlay2
script:
- apk add --no-cache curl
- docker login -u $CI_REGISTRY_USER -p $CI_JOB_TOKEN $CI_REGISTRY
- docker pull $IMAGE:build-python || true
- docker pull $IMAGE:production || true
- docker build
--target build-python
--cache-from $IMAGE:build-python
--tag $IMAGE:build-python
--file ./Dockerfile
"."
- docker build
--cache-from $IMAGE:production
--tag $IMAGE:production
--tag $HEROKU_REGISTRY_IMAGE
--file ./Dockerfile
"."
- docker push $IMAGE:build-python
- docker push $IMAGE:production
- docker login -u _ -p $HEROKU_AUTH_TOKEN registry.heroku.com
- docker push $HEROKU_REGISTRY_IMAGE
- chmod +x ./release.sh
- ./release.sh
Certifique-se de substituir
<APP_NAME>
pelo nome do seu aplicativo Heroku.
Revise as alterações por conta própria. Em seguida, teste-o uma última vez.
Para saber mais sobre esse padrão de cache, revise a seção "Multi-stage" do artigo Faster CI Builds with Docker Cache .
Ignore esta seção se estiver usando a abordagem do Container Registry.
.gitlab-ci.yml :
stages:
- build
- test
- deploy
variables:
IMAGE: ${CI_REGISTRY}/${CI_PROJECT_NAMESPACE}/${CI_PROJECT_NAME}
HEROKU_APP_NAME: <APP_NAME>
build:
stage: build
image: docker:stable
services:
- docker:dind
variables:
DOCKER_DRIVER: overlay2
script:
- docker login -u $CI_REGISTRY_USER -p $CI_JOB_TOKEN $CI_REGISTRY
- docker pull $IMAGE:build-python || true
- docker pull $IMAGE:production || true
- docker build
--target build-python
--cache-from $IMAGE:build-python
--tag $IMAGE:build-python
--file ./Dockerfile
"."
- docker build
--cache-from $IMAGE:production
--tag $IMAGE:production
--file ./Dockerfile
"."
- docker push $IMAGE:build-python
- docker push $IMAGE:production
test:
stage: test
image: $IMAGE:production
services:
- postgres:latest
variables:
POSTGRES_DB: test
POSTGRES_USER: runner
POSTGRES_PASSWORD: ""
DATABASE_URL: postgresql://runner@postgres:5432/test
script:
- python manage.py test
- flake8 hello_django --max-line-length=100
- black hello_django --check
- isort hello_django --check --profile black
deploy:
stage: deploy
script:
- apt-get update -qy
- apt-get install -y ruby-dev
- gem install dpl
- dpl --provider=heroku --app=$HEROKU_APP_NAME --api-key=$HEROKU_AUTH_TOKEN
Certifique-se de substituir
<APP_NAME>
pelo nome do seu aplicativo Heroku.
Revise as alterações por conta própria. Em seguida, teste-o uma última vez.
Para saber mais sobre esse padrão de cache, revise a seção "Multi-stage" do artigo Faster CI Builds with Docker Cache .
Neste artigo, percorremos duas abordagens para implantar um aplicativo Django no Heroku com o Docker -- o Container Registry e o Build Manifest.
Então, quando você deve pensar em usar o Heroku Container Runtime sobre o tradicional compilador Git e slug para implantações?
Quando você precisar de mais controle sobre o ambiente de implementação de produção.
Exemplos:
Fonte: https://testdrive.io
1620185280
Welcome to my blog, hey everyone in this article we are going to be working with queries in Django so for any web app that you build your going to want to write a query so you can retrieve information from your database so in this article I’ll be showing you all the different ways that you can write queries and it should cover about 90% of the cases that you’ll have when you’re writing your code the other 10% depend on your specific use case you may have to get more complicated but for the most part what I cover in this article should be able to help you so let’s start with the model that I have I’ve already created it.
**Read More : **How to make Chatbot in Python.
Read More : Django Admin Full Customization step by step
let’s just get into this diagram that I made so in here:
Describe each parameter in Django querset
we’re making a simple query for the myModel table so we want to pull out all the information in the database so we have this variable which is gonna hold a return value and we have our myModel models so this is simply the myModel model name so whatever you named your model just make sure you specify that and we’re gonna access the objects attribute once we get that object’s attribute we can simply use the all method and this will return all the information in the database so we’re gonna start with all and then we will go into getting single items filtering that data and go to our command prompt.
Here and we’ll actually start making our queries from here to do this let’s just go ahead and run** Python manage.py shell** and I am in my project file so make sure you’re in there when you start and what this does is it gives us an interactive shell to actually start working with our data so this is a lot like the Python shell but because we did manage.py it allows us to do things a Django way and actually query our database now open up the command prompt and let’s go ahead and start making our first queries.
#django #django model queries #django orm #django queries #django query #model django query #model query #query with django
1590378116
In this tutorial, we’ll look at how to configure GitLab CI to continuously deploy a Django and Docker application to AWS EC2.
#docker #django #gitlab #aws ec2