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:
- Dockerfile needs to be multi-stage, i.e. build with one container and run with another
- Use
golang:1.14.4-alpine
container image for building and running the application
Build container:
- Name first container as
builder
WORKDIR
needs to be/app/
- COPY backend golang files to the container
- Build Golang app with params:
CGO_ENABLED=0 GOOS=linux
- Binary should be named
backend
Run container:
WORKDIR
needs to be/app
- Use
COPY --from=builder
to get the binary from the first container EXPOSE
port8080
- 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:
- Dockerfile needs to be multi-stage, i.e. build with one container and run with another
- 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
- Name the build step as backend
- Variable
APP_NAME_BACKEND
should be your username + backend, i.e.APP_NAME: apprentice-1-backend
- 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
- Sript:
- Build the image with following parameters:
- 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
- Tag the image with format
- Push the image to ECR
- Build the image with following parameters:
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
- Name the build step as frontend
- Variable
APP_NAME_FRONTEND
should be your username + frontend, i.e.APP_NAME: apprentice-1-frontend
- 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
- Sript:
- Build the image with following parameters:
- 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
- Tag the image with format
- Push the image to ECR
- Build the image with following parameters:
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