DEV Community

Tobias Mesquita for Quasar Framework Brasil

Posted on

QPANC - Parte 19 - Docker - Registro e Build

QPANC são as iniciais de Quasar PostgreSQL ASP NET Core.

38 Criando um Container Registry no Azure.

para podemos continuar, iremos precisar de um Container Registry, novamente, você pode usar qual quer provedor, como por exemplo, o Docker Hub porém estarei criando um no azure.

Então comece o processo para adicionar um novo recurso, e busque por Container Registry:

Alt Text

É interessante que o Container Registry use o mesmo grupo de recursos e esteja localizado na mesma região que a VM, assim como estaremos ativando o usuário admin, e como estamos criando este registro apenas para testes, use o SKU Basic.

Alt Text

Agora à confirmação da criação do registro, precisamos esperar alguns instantes, até que o azure configure tudo.

Por fim, vá até a guia Access Keys e copie o nome do Login server, username e o password.

Alt Text

Agora, temos um registro para onde podemos enviar as nossas imagens.

39 Fazendo o Build para produção

Antes de realizamos o build para produção, precisamos desativar o redirecionamento HTTPS da API, pois este procedimento será feito por outro serviço, o traefik.

então, no docker-compose.yml remova qual quer referencia à porta 443.

- "34513:443" => // remova completamente esta linha - ASPNETCORE_URLS=http://+:443;http://+:80 => - ASPNETCORE_URLS=;http://+:80 

E no QPANC.Api/Startup.cs, remova a seguinte linha:

app.UseHttpsRedirection(); 

Então, faça uma copia do docker-compose.override.yml e renomeie ela para docker-compose.production.yml.

QPANC/docker-compose.production.yml

version: '3.4' services: qpanc.api: environment: - ASPNETCORE_ENVIRONMENT=Production - ASPNETCORE_URLS=https://+:443;http://+:80 - DEFAULT_CONNECTION=Server=qpanc.database;Port=5432;Database=postgres;User Id=postgres;Password=keepitsupersecret; - JWTBEARER_VALIDISSUER=https://api.qpanc.tobiasmesquita.dev/ - JWTBEARER_VALIDAUDIENCE=https://api.qpanc.tobiasmesquita.dev/ - JWTBEARER_ISSUERSIGNINGKEY=itUXC7iVRsofSDWNeg/aLYpc4bMzHAsMPzeItE1PQi2tMK2f4t0InRgTE5B/4IAjhAX5LQSIGL1CaUHSSzED8A== - JWTBEARER_TOKENDECRYPTIONKEY=7hfboHG0d4GnXjVng0ukMo+IgrKKrPLUMtOvnt4S514= - CORS_HOSTS__0=qpanc.tobiasmesquita.dev ports: - "34512:80" - "34513:443" volumes: - ${APPDATA}/Microsoft/UserSecrets:/root/.microsoft/usersecrets:ro - ${APPDATA}/ASP.NET/Https:/root/.aspnet/https:ro qpanc.app: container_name: qpanc_app_prod build: context: ./QPANC.App target: 'prod-stage' dockerfile: .docker/prod.Dockerfile volumes: - app:/app ports: - "34514:3000" qpanc.database: volumes: - database:/var/lib/postgresql/database environment: POSTGRES_USER: postgres POSTGRES_PASSWORD: keepitsupersecret POSTGRES_DB: postgres volumes: app: database: 

No service qpanc.api nós alteramos o environment, adicionando algumas variáveis de ambiente e modificando outras: ASPNETCORE_ENVIRONMENT, JWTBEARER_VALIDISSUER, JWTBEARER_VALIDAUDIENCE e CORS_HOSTS__0.

No service qpanc.app, temos mais alterações, a primeira é o nome do contêiner em container_name: qpanc_app_prod, no caso do build, estamos usando um outro Dockerfile, nos volumes, app vai está apontando para um volume interno, na porta, estaremos usando a porta 3000 ao invés de 8080, assim como, foi removido o commands.

Por fim, o qpanc.database teve alterações menos relevantes, como o volumes e o container_name.

O próximo passo, é preparar o prod.Dockerfile

QPANC.App/.docker/prod.Dockerfile

# develop stage FROM node:12.16-alpine as develop-stage WORKDIR /app/source COPY package*.json ./ RUN npm i -g @quasar/cli@latest COPY . . # local-deps FROM develop-stage as local-deps-stage RUN ls RUN rm -r -f .quasar RUN rm -r -f dist RUN rm -r -f node_moduless RUN rm -f yarn.lock RUN yarn # build stage FROM local-deps-stage as build-stage ENV API_CLIENT_URL=https://api.qpanc.tobiasmesquita.dev/ ENV API_SERVER_URL=https://api.qpanc.tobiasmesquita.dev/ RUN quasar build -m ssr # prod stage FROM build-stage as prod-stage WORKDIR /app/source/dist/ssr RUN mv * ../../../ WORKDIR /app RUN rm -r -f source RUN yarn CMD ["node", "index.js"] 

Basicamente, estamos copiando o source, apagando node_moduless, dist, locks, e baixamos novamente, então é feito o build, copiamos os arquivos do build para a raiz, por fim apagamos o source

Agora, execute o seguinte comando.:

docker-compose -f docker-compose.yml -f docker-compose.production.yml build docker image ls -a 

Alt Text

Vai levar alguns longos segundos, para que o build do app e da api seja realizado, então devemos anotar o ID das imagens, no meu caso 516a0d428a28para a api e eb3ec1b5548e para o app.

Então, execute o seguinte comando para o app e para a api, para que consigamos criar as suas respectivas tags.

docker tag {image} {registry_name}/{container_name}:{tag_name} 

no meu caso:

docker tag 516a0d428a28 qpanc.azurecr.io/api:latest docker tag eb3ec1b5548e qpanc.azurecr.io/app:latest docker image ls -a 

Alt Text

Agora que criamos as nossas imagens e as suas respectivas tags, precisamos subir relas para o container, para que isto seja possível, teremos de logar no docker usando uma conta com permissão:

docker login -u ${username} -p ${password} ${login_server} 

no meu caso

docker login -u qpanc -p ************************ qpanc.azurecr.io 

agora que efetuamos o login, podemos fazer o push das imagens, então execute o seguinte comando, tanto para o app como para a api.

docker push {registry_name}/{container_name}:{tag_name} 

no meu caso

docker push qpanc.azurecr.io/api:latest docker push qpanc.azurecr.io/app:latest 

Alt Text

Feito isto, as imagens já estão disponíveis, já podemos ser acessadas a partir da VM

Caso tenha feito o upload para um Registro criado no portal do Azure, eles vão ser listados da seguinte forma:

Alt Text

Note que latest é o valor default para as tags, porém é interessante, que a cada publicação seja criado uma nova tag, como por exemplo 1.0.0, 1.0.1 ou 1.1.0, e a latest deverá ser apenas um alias para a mais recente.

Por fim, deixo um script que fazer a limpeza dos containers/imagens, faz o build, cria as tags e realiza o upload. Porém que fique claro, que esta solução é um tanto quanto drástica.

docker container stop $(docker container ls -aq) docker container rm $(docker container ls -aq) docker image rm $(docker image ls -aq) -f docker-compose -f docker-compose.yml -f docker-compose.production.yml build --no-cache --force-rm --compress docker tag $(docker image ls -f=reference="qpancapi" -q) qpanc.azurecr.io/api:latest docker tag $(docker image ls -f=reference="qpancapp" -q) qpanc.azurecr.io/app:latest docker push qpanc.azurecr.io/api:latest docker push qpanc.azurecr.io/app:latest 

Top comments (0)