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

Discussion (0)