Michael
Michael

Reputation: 3239

Integrating docker with gitlab-ci - how does the docker image get built and used?

I was previously using the shell for my gitlab runner to build my project. So far I have set up the pipeline that will run whatever commands I have set in the gitlab-ci.yml file seen below:

gitlab-ci.yml using shell runner

before_script:
  - npm install
  - npm install --save @angular/material @angular/cdk

cache:
  paths:
    - node_modules/

stages:
  - dev
  - staging
  - production

build_dev:
  stage: dev

  script:
    - rm ./package-lock.json
    - npm run build 
    - ./node_modules/@angular/cli/bin/ng test --browsers PhantomJS --watch false

Now, I want to switch to a docker image. I have reconfigured the runner to use a docker image, and I specified the image in my new gitlab-ci.yml file seen below. I followed the gitlab-ci docker tutorial and this is where it left off so I'm not entirely sure where to go from here:

gitlab-ci.yml using docker runner

image: node:8.10.0

before_script:
  - npm install
  - npm install --save @angular/material @angular/cdk

cache:
  paths:
    - node_modules/

stages:
  - dev
  - staging
  - production

build_dev:
  stage: dev

  script:
    - rm ./package-lock.json
    - npm run build 
    - ./node_modules/@angular/cli/bin/ng test --browsers PhantomJS --watch false

Questions:

  1. With my current gitlab-ci.yml file, how does this build a docker image/does it even build one? If it does, what does that mean? Currently the pipeline passed, but I have no idea if it did in a docker image or not (am I supposed to be able to tell?).

    Also, let's say the docker image was created, ran the tests, and the pipeline passed; it should push the code to a new repository (not included in yml file yet). From what I gathered, the image isn't being pushed, it's just the code, right? So what do I do with this created docker image?

  2. How does the Dockerfile get used? I see no link between the gitlab-ci.yml file and Dockerfile.

  3. Do I need to surround all commands in the gitlab-ci.yml file in docker run <commands> or docker exec <commands>? Without including one of these 2 commands, it seems like it would just run on the server and not in a docker image.

  4. I've seen people specify an image in both the gitlab-ci.yml file and Dockerfile. I have an angular project, and I specified an image of image: node:8.10.0. In the Dockerfile, should I specify the same image? I've seen some projects where they are completely different and I'm wondering what the use of both images are/if picking one image over another will severely impact my builds.

Upvotes: 3

Views: 2049

Answers (1)

trust512
trust512

Reputation: 2256

You have to take a different approach on building your app if you want to fully dockerize it. Export angular things into Dockerfile and get docker operations inside your .gitlab-ci instead of angular stuff like here:

stages:
  - build
#  - release
#  - deploy

.build_template: &build_definition
  stage: build
  image: docker:17.06
  services:
    - docker:17.06-dind
  script:
    - docker login -u gitlab-ci-token -p $CI_JOB_TOKEN $CI_REGISTRY
    - docker pull $CONTAINER_RELEASE_IMAGE || true
    - docker build --cache-from $CONTAINER_RELEASE_IMAGE -t $CONTAINER_IMAGE -f $DOCKERFILE ./
    - docker push $CONTAINER_IMAGE

build_app_job:
  <<: *build_definition
  variables:
    CONTAINER_IMAGE: $CI_REGISTRY_IMAGE/app:$CI_COMMIT_REF_SLUG
    CONTAINER_RELEASE_IMAGE: $CI_REGISTRY_IMAGE/app:latest
    DOCKERFILE: ./Dockerfile.app

build_nginx_job:
  <<: *build_definition
  variables:
    CONTAINER_IMAGE: $CI_REGISTRY_IMAGE/nginx:$CI_COMMIT_REF_SLUG
    CONTAINER_RELEASE_IMAGE: $CI_REGISTRY_IMAGE/nginx:latest
    DOCKERFILE: ./Dockerfile

You can set up a few build jobs - for production, development, staging etc. Right next to your .gitlab-ci.yaml you can put Dockerfile and Dockerfile.app - Dockerfile.app stands for building you angular app:

FROM node:10.5.0-stretch
RUN mkdir -p /usr/src/app
RUN mkdir -p /usr/src/remote
WORKDIR /usr/src/app
COPY . .
# do your commands here

Now with your app built, it can be served via a web server - it's your choice and a different configuration that follows with each choice - cant even scratch a surface here. That'd be implemented in Dockerfile - we usually use Nginx in our company.

From here on it's about releasing your images and deploying them. I've only specified how to build them in docker as it seems this is what the question is about.

If you want to deploy your image and run it somewhere - choose a provider - AWS, Heroku, own infrastructure - have it your way, but this is far too much to cover all those in a single answer so I'll leave it for another question when you specify where'd you like to deploy your newly built images and how would you like to serve it. In our company, we orchestrate things with Rancher, but there are multiple awesome and competing options in the market.


Edit for a custom registry

The above .gitlab-ci configuration works with Gitlab's "internal" registry only, in case you want to utilize your own registry, change the values accordingly:

#previous configs
script:
        - docker login -u mysecretlogin -p mysecretpasswd registry.local.com
        # further configs
  • from -u gitlab-ci-token to your login in the registry,
  • from $CI_JOB_TOKEN to your password
  • from $CI_REGISTRY to your registry address

Those values should be stored in Gitlab's CI secret variables and referenced via env variables so that they are not saved in the repository.

Finally, your script might look like below in case you decided to protect these values. Refer to Gitlab's official docs on how to add secret CI variables - super easy task.

#previous configs
script:
        - docker login -u $registrylogin -p $registrypasswd $registryaddress
        # further configs

Upvotes: 4

Related Questions