Deploy on Azure

Everything described here is also possible in the graphical interface: https://portal.azure.com/

Create the azure resources

  • Install the azure-cli
  • Login to the azure-cli

$ az login

  • If they don’t exist yet create a Resourcegroup, App Service-plan, App Service and Container registry.

$ az group create --name <ResourcegroupName> --location westeurope $ az appservice plan create --name <ServicePlanName> --resource-group <ResourcegroupName> --sku S1 --is-linux # --ski is de pricing tier $ az webapp create --resource-group <ResourcegroupName> --plan <ServicePlanName> --name <WebAppName> $ az acr create --name <ContainerRegisterName> --resource-group <ResourcegroupName> --sku Basic

Create the docker image & push to the Container registry

  • Make sure sensitive data for production is inserted with environment variables in config/production.js
  • Create a dockerfile for production in env/Dockerfile if it doesn’t exist. Example:

``` FROM node:10.15.0-alpine LABEL maintainer="Codifly info@codifly.be"

EXPOSE 9300

RUN mkdir -p /app && chown node /app WORKDIR /app

RUN apk update && \ apk upgrade && \ apk add --no-cache git

USER node

COPY --chown=node package.json yarn.lock ./ RUN yarn

ENV PATH=$PATH:/home/node/.yarn/bin RUN yarn global add wait-port

COPY --chown=node ./ /app/

ENV NODE_ENV=production CMD wait-port db:5432 && \ yarn dbmigrate && \ ./init.sh && \ node index.js ```

  • Build the docker image locally

$ docker build -t <ImageName>:<Version> -f ./env/Dockerfile .

  • Rename the image in order to push it to the registry

$ docker tag <ImageName>:<Version> <ContainerRegisterName>.azurecr.io/<ImageName>:<Version>

  • Push the image to the registry

$ az acr login --name <ContainerRegisterName>$ docker push <ContainerRegisterName>.azurecr.io/<ImageName>:<Version>

Create compose config & set environment variables in azure

  • Create a docker-compose for production in env/docker-compose.yaml if it doesn’t exist.

    • Set the images of the services to the ones pushed to your azure registry (all images used must be pushed to the same registry).
    • All services defined in this file will be able to connect to each other by their name.
    • Pass the correct environment variables to the services.
    • Expose the api port to port 80.
    • Example:

    version: '2' services: api: image: weersynchronisatie.azurecr.io/weersynchronisatie_prod:1.0.0 environment: DB_POSTGRES_USER: ${DB_POSTGRES_USER} DB_POSTGRES_PASSWORD: ${DB_POSTGRES_PASSWORD} DB_POSTGRES_DB: ${DB_POSTGRES_DB} FTP_HOST: ${FTP_HOST} FTP_USERNAME: ${FTP_USERNAME} FTP_PASSWORD: ${FTP_PASSWORD} GOOGLE_EMAIL: ${GOOGLE_EMAIL} GOOGLE_REFRESH_TOKEN: ${GOOGLE_REFRESH_TOKEN} GOOGLE_CLIENT_ID: ${GOOGLE_CLIENT_ID} GOOGLE_CLIENT_SECRET: ${GOOGLE_CLIENT_SECRET} ports: - '80:9300' restart: on-failure db: image: weersynchronisatie.azurecr.io/postgres:9.6.2 environment: POSTGRES_USER: ${DB_POSTGRES_USER} POSTGRES_PASSWORD: ${DB_POSTGRES_PASSWORD} POSTGRES_DB: ${DB_POSTGRES_DB}

  • Set the timeout of the azure container startup to the maximum

$ az webapp config appsettings set --resource-group <ResourcegroupName> --name <WebAppName> --settings WEBSITES_CONTAINER_START_TIME_LIMIT=1800

  • Set all environment variables of the app

$ az webapp config appsettings set --resource-group <ResourcegroupName> --name <WebAppName> --settings ENV_1=VALUE1 ENV2=VALUE2 ENV3=VALUE3

  • Get the Container Registry credentials (we need ‘username’ and ‘password’)

$ az acr credential show --name <ContainerRegisterName>

  • Set the compose config for the app

$ az webapp config container set --resource-group <ResourcegroupName> --name <WebAppName> --multicontainer-config-type compose --multicontainer-config-file ./env/docker-compose.yaml --docker-registry-server-user <ACRUsername> --docker-registry-server-password <ACRPassword> --docker-registry-server-url https://<ContainerRegisterName>.azurecr.io

Start the webapp

$ az webapp start --resource-group <ResourcegroupName> --name <WebAppName>

Get the logs

$ az webapp log download --resource-group <ResourcegroupName> --name <WebAppName>

The useful logs are in webapp_logs/LogFiles/<DATE>_…_docker.log for the docker startup logs and in webapp_logs/LogFiles/<DATE>_…<CONTAINER_NAME>_docker.log for the logs of the individual containers.

Test local

To test the containers locally make sure you ran 'az acr login --name <ContainerRegisterName>' so you can pull the images from the registry. Also set the necessary environment variables on the command line.

$ ENV1=ENV1 ENV2=ENV2 ENV3=ENV3 docker-compose -f env/docker-compose.yaml up --build --force-recreate