Wednesday, July 14, 2021

how to pass dockerfile argument from docker-compose file?

 It should be very convenient and dynamic, if we can set our environment variable on docker build time.

since I want to turn graphql playground on and off during the production deployment, I already use the 

NODE_ENV to control the playground feature in the .env file.

in .net file

NODE_ENV=dev

GraphQLModule.forRoot({
      playground: process.env.NODE_ENV === 'dev',
      debug: process.env.NODE_ENV === 'dev',
      autoSchemaFile: true,
    }),


we can use ARG to set a variable in the dockerfile that we can pass in during docker build run.

ARG node_env_var
ENV NODE_ENV=$node_env_var
RUN echo $node_env_var

here is the full content of Dockfile

FROM node:14 as production

ARG node_env_var
ENV NODE_ENV=$node_env_var
RUN echo $node_env_var

WORKDIR /usr/src/api

COPY package.json .
COPY yarn.lock .

RUN yarn global add @nestjs/cli

RUN yarn install --production=true

## install NIC s a computer networking utility for reading from and 
# writing to network connections using TCP or UDP.
RUN apt-get -q update && apt-get -qy install netcat

COPY . .

RUN yarn build

CMD ["sh", "-c", "yarn typeorm migration:run && yarn start:prod"]



in the Docker-compose.yml file we can set the args variable. when I run the deployment in the production environment, i can simply change the node_env_var: production

build
            contextserver
            targetproduction
            dockerfileDockerfile
            args:
                node_env_vardev

here is the docker-compse.yml file

version"3.8"

services:
    mysqldb:
        imagemysql
        environment
            - MYSQL_ROOT_PASSWORD=Mys0l@123456
            - MYSQL_DATABASE=hyrecar
        ports
            - 3306:3306
        command--default-authentication-plugin=mysql_native_password
        networks:
            - shared-network
        volumes
            - db-config:/etc/mysql
            - db-data:/var/lib/mysql
            - ./db/backup/files:/data_backup/data
       
    #acting as a proxy

    nginx:
        imagenginx:latest
        container_namenginx-prod
        volumes
            - ./nginx/nginx.conf:/etc/nginx/nginx.conf
        ports
            - 81:80
        command/bin/sh -c "nginx -g 'daemon off;'"    
        depends_on
            api-prod:
                conditionservice_healthy
            app-prod:
                conditionservice_started
        networks
            - shared-network

    api-prod:
        container_namenestjs_api_prod
        imagenestjs_api_prod:1.0.0.0
        build
            contextserver
            targetproduction
            dockerfileDockerfile
            args:
                node_env_vardev
        commandsh -c './bin/wait-for -t 0 mysqldb:3306 -- yarn start:prod'
        depends_on
            - mysqldb
        networks
            - shared-network
        ports
            - 9000:9000
        restartunless-stopped
        healthcheck:
            test: ["CMD""curl""http://api-prod:9000"]
            interval5s
            timeout3s
            retries6     
        
    app-prod:
        container_namerect_app_prod
        imagerect_app_prod:1.0.0
        build:
            contextweb
            targetproduction
            dockerfileDockerfile
        commandyarn run start:prod
        ports
            - 3000:3000
        networks
            - shared-network
        restartunless-stopped

#intialize network
networks
    shared-network:

#Initializing docker compose volumes
volumes
    db-config:
    db-data:


for development and test environment deployment.

set node_env_var: dev in docker-compose.yml 

run docker-compose build to rebuilt the container

execute docker-compose up to run all containers

in the production, we just need to change node_env_var: production

then we can run docker-compose build & docker-compose up to turn off graphql playground feature for security reason.

 Please Note you can not simply update the variable in the docker-compose yaml file and run docker-compose up since the variable is passing in at docker-compose build time, not the run time. so We have to run docker-compose build process to take the effect.



No comments:

Post a Comment