Skip to content

Docker

In this section you must write Dockerfile to both the frontend and backend. After that those files need to be built with CI/CD


Dockerfile

Write Dockerfile to the root of both backend and frontend

Backend

Write Dockerfile with the following requirements:

  1. Dockerfile needs to be multi-stage, i.e. build with one container and run with another
  2. Use golang:1.14.4-alpine container image for building and running the application

Build container:

  1. Name first container as builder
  2. WORKDIR needs to be /app/
  3. COPY backend golang files to the container
  4. Build Golang app with params: CGO_ENABLED=0 GOOS=linux
  5. Binary should be named backend

Run container:

  1. WORKDIR needs to be /app
  2. Use COPY --from=builder to get the binary from the first container
  3. EXPOSE port 8080
  4. Run application /app/backend

Help

File: backend/Dockerfile

ARG GOLANG_VERSION=1.14.4

FROM golang:${GOLANG_VERSION}-alpine as builder


WORKDIR /app

COPY main.go .
COPY go.mod .
COPY go.sum .

RUN CGO_ENABLED=0 GOOS=linux go build -o backend

FROM golang:${GOLANG_VERSION}-alpine

WORKDIR /app

COPY --from=builder /app/backend .

EXPOSE 8080
CMD ["/app/backend"]

Frontend

Write Dockerfile with the following requirements:

  1. Dockerfile needs to be multi-stage, i.e. build with one container and run with another
  2. Use node:14.4.0-alpine container image for building and running the application

Build container: 1. Name first container as builder 1. WORKDIR needs to be /node/src 1. COPY files/folders: 1. package.json 1. package-lock.json 1. public 1. src 1. Install NPM packages npm install 1. Build the project yarn run build

Run container: 1. WORKDIR needs to be /app 1. Use COPY --from=builder to copy following files/folders: 1. /node/src/public to public/ 1. /node/src/node_modules to node_modules/ 1. /node/src/build build/ 1. EXPOSE port 5000 1. Run application with node /app/server/server.js


Help

File: frontend/Dockerfile

ARG NODEJS_VERSION=14.4.0

FROM node:${NODEJS_VERSION}-alpine as builder

WORKDIR /node/src

COPY package.json .
COPY package-lock.json .
COPY public public/
COPY src src/

RUN npm install
RUN yarn run build


FROM node:${NODEJS_VERSION}-alpine

WORKDIR /app

COPY server server/

COPY --from=builder /node/src/public public/
COPY --from=builder /node/src/node_modules node_modules/
COPY --from=builder /node/src/build build/

EXPOSE 5000
CMD ["node", "/app/server/server.js"]


Building the containers

Use CI/CD to build the containers using the Dockerfiles. \ These images are to be pushed to ECR (Elastic Container Service) in AWS

Change DOCKER_REGISTRY to match AWS Accounts ECR Registry Name the Gitlab CI files accordingly, i.e. gitlab-ci-build-frontend.yml

Use this as base for both files:

variables:
  DOCKER_REGISTRY: XXXXXXXX.dkr.ecr.eu-west-1.amazonaws.com
  AWS_DEFAULT_REGION: eu-west-1
  DOCKER_HOST: tcp://docker:2375

stages:
  - build

build:<name>:
  image: 
    name: amazon/aws-cli
    entrypoint: [""]
  services:
    - docker:dind
  before_script:
    - amazon-linux-extras install docker
    - aws --version
    - docker --version
  script:
    - <list>

Backend

  1. Name the build step as backend
  2. Variable APP_NAME_BACKEND should be your username + backend, i.e. APP_NAME: apprentice-1-backend
  3. Before script:
    • CD to backend directory before running build commands
    • Log in to ECR: aws ecr get-login-password | docker login --username AWS --password-stdin $DOCKER_REGISTRY
  4. Sript:
    • Build the image with following parameters:
      1. Tag the image with format /:$CI_COMMIT_SHORT_SHA \

        $CI_COMMIT_SHORT_SHA is Gitlabs serial based pipeline identifier Use Variables in the Tag creation

    • Push the image to ECR

Help

File: backend/.gitlab-ci-backend-build.yml

image: golang:1.14.4-alpine

variables:
  DOCKER_REGISTRY: XXXXXXXXX.dkr.ecr.eu-west-1.amazonaws.com
  AWS_DEFAULT_REGION: eu-west-1
  DOCKER_HOST: tcp://docker:2375
  BACKEND_APP_NAME: apprentice-0-backend

stages:
  - publish

build:backend:
  stage: publish
  image:
    name: amazon/aws-cli
    entrypoint: [""]
  services:
    - docker:dind
  before_script:
    - amazon-linux-extras install docker
    - aws --version
    - docker --version
    - cd backend
  script:
    - aws ecr get-login-password | docker login --username AWS --password-stdin $DOCKER_REGISTRY
    - docker build -t ${DOCKER_REGISTRY}/${BACKEND_APP_NAME}:${CI_PIPELINE_IID} .
    - docker push ${DOCKER_REGISTRY}/${BACKEND_APP_NAME}:${CI_PIPELINE_IID}

Frontend

  1. Name the build step as frontend
  2. Variable APP_NAME_FRONTEND should be your username + frontend, i.e. APP_NAME: apprentice-1-frontend
  3. Before script:
    • CD to frontend directory before running build commands
    • Log in to ECR: aws ecr get-login-password | docker login --username AWS --password-stdin $DOCKER_REGISTRY
  4. Sript:
    • Build the image with following parameters:
      1. Tag the image with format /:$CI_COMMIT_SHORT_SHA \

        $CI_COMMIT_SHORT_SHA is Gitlabs serial based pipeline identifier Use Variables in the Tag creation

    • Push the image to ECR

Help

File: fronend/.gitlab-ci-frontend-build.yml

image: node:14.4.0-alpine

variables:
  DOCKER_REGISTRY: XXXXXXXXX.dkr.ecr.eu-west-1.amazonaws.com
  AWS_DEFAULT_REGION: eu-west-1
  DOCKER_HOST: tcp://docker:2375
  APP_NAME: apprentice-0-frontend

stages:
  - publish

build:frontend:
  stage: publish
  image:
    name: amazon/aws-cli
    entrypoint: [""]
  services:
    - docker:dind
  before_script:
    - amazon-linux-extras install docker
    - aws --version
    - docker --version
    - cd frontend
  script:
    - aws ecr get-login-password | docker login --username AWS --password-stdin $DOCKER_REGISTRY
    - docker build -t ${DOCKER_REGISTRY}/${APP_NAME}:${CI_PIPELINE_IID} .
    - docker push ${DOCKER_REGISTRY}/${APP_NAME}:${CI_PIPELINE_IID}

Commit the changes and make sure everything worked