3

Why use docker

As we all know, we need to configure the corresponding environment to write and run any software, so why don't we configure it manually?

For example, we are writing two web projects at the same time, one uses the database mysql: 5.7, and the other uses the database mysql: 8.0, but mysql does not support running multiple versions locally at the same time, so every time we change the project, we will You need to delete the current mysql=”installation required mysql=” to reconfigure mysql.

On the other hand, we should have all experienced how many problems may occur when configuring the environment, and the above process will undoubtedly waste a lot of time. Not to mention the time wasted when the teammates installed the wrong version when working on a team.

So we need a unified configuration environment and easy to use items, which is docker.
We only need to determine the configuration file and execute one command to configure all the environment.

what is dockerfile

The role of Dockerfile is similar to that of docker-compose, and it also exists to configure the environment. So what is special about docker-file?
dockerFile official documentation

As far as we know, when we use docker-compose, we need to configure the image item, which is the environment item we need. For example, if we need the mysql environment, configure it as mysql:XXX, and the same is true for others.

What kind of environment we want to configure, we need to find the corresponding configuration items in the official website of docker-hub , and configure it according to its example. In other words, if the environment we need does not exist in the official website of docker-hub, we will You can't just use docker-compose for configuration.

For example, if we want to configure the environment for running angular unit tests with one click, we cannot find the corresponding environment in the official website of docker-hub.

At this time, we need to configure the image (image) by ourselves and upload it to Alibaba Cloud-Container Image Service through Dockerfile, so that we can call it remotely through its public network address plus version number (for example: registry.cn-beijing.aliyuncs.com/mengyunzhi_li/node_ding_push:14.16.2 ) Our custom image.

How to write a simple dockerfile

After understanding the function of dockerfile, the next step is to understand how to write dockerfile
dockerFile official documentation
First we need to know some basic instructions
1: FROM: used to specify the base image, configure when our custom image needs to be based on a certain image

 例如: FROM  node:14.16.0-stretch

2: RUN: There are many ways to use it. Personally, it is understood as the command executed when the image is built.

 例如:RUN "command" "param1" "param2"

Note: Execute at build time means that it will not be executed when the environment is pulled to create a container locally, because the image has already been built in Alibaba Cloud Image Service.

3: CMD: Similar to RUN, the difference is that the commands in it will be executed when the container is started

 例如:CMD "command" "param1" "param2"

Notice:
1. CMD can only appear once in the Dockerfile, there are multiple, only the last one will be valid.
2. Its function is to provide a default command item when starting the container. If the user provides a command item when executing docker run, this command will be overwritten. If not provided, the build-time command will be used.

4: COPY: Copy the local file or directory or remote file and add it to the specified container directory

 COPY ./send-ding.sh /

Note: Above we uploaded the local send-ding.sh to the container, which allows us to call this script in the dockerFile container
docker
--Dockerfile
--send-ding.sh

Practical problems

My goal below is to create an image that can automatically execute the specified script for DingTalk push when it is called.
Since there is no previous use experience, first try to push static information without passing parameters.

 FROM node:14.16.0-stretch
RUN apt-get update
RUN apt install -y curl
RUN apt-get clean
COPY ./send-ding.sh /
RUN sh send-ding.sh -a 1ab5179dd94ed62de026d96ba61b41b1dda42357fdf79a787f11c7708449a06d -t markdown -c pipeine运行失败 -T "tiT,,le"
CMD ["sh", "send-ding.sh", "-a","1ab5179dd94ed62de026d96ba61b41b1dda42357fdf79a787f11c7708449a06d", "-t", "markdown", "-c", "pipeine运行失败", "-T", "'tiT,,le'"]

Note: The commands after RUN and CMD are in two forms, which can be used in actual use.

local test

1. Create an image locally

 sudo docker build . -t=ding-file:1.2

2. View the image we created

 sudo docker image ls

image.png
3. Create a container based on the image

 sudo docker run -it ding-file:1.2

image.png
4. Check DingTalk and find that it has been pushed and executed as scheduled

Push to Alibaba Cloud to build a custom image

Open Alibaba Cloud Container Image Service and create a personal instance.
图片.png
1. Create a mirror warehouse
图片.png
2. Bind with your own code repository to upload the required files
图片.png
3. Set build rules to locate the required files
图片.png
4. After the build is completed, use the public network address plus the version number to call
图片.png
It was found that everything was executed normally, and the .sh file was executed as scheduled and pushed to Dingding.

try to use this image in gitlab.yaml

gitlab.yaml:

 . . .

# 设置步骤(步骤间串行)
stages:
  - unit-test
  - notify


# 设置自动执行的管道名称
angular-test:
  # 前台使用docker来构建
  tags:
    - docker
  # 设置该管道属于的步骤,同步骤的管道并行执行
  stage: unit-test
  image: registry.cn-beijing.aliyuncs.com/mengyunzhi/node-chrome:14.16.0

  before_script:
    - cd web
  script:
    - pwd
    - npm install
    - npm run test -- --no-watch --no-progress --browsers=ChromeHeadlessCI

success-notify:
  # 前台使用docker来构建
  tags:
    - docker
  # 设置该管道属于的步骤,同步骤的管道并行执行
  stage: notify
  image: registry.cn-beijing.aliyuncs.com/mengyunzhi_li/node_ding_push:14.16.3
  script:
    - env

error-notify:
  # 前台使用docker来构建
  tags:
    - docker
  # 设置该管道属于的步骤,同步骤的管道并行执行
  stage: notify
  image: registry.cn-beijing.aliyuncs.com/mengyunzhi_li/node_ding_push:14.16.3
  script:
    - env
  when: on_failure

Results of the:
图片.png
It was found that there was no execution error but the DingTalk push was not performed. According to the log, our custom mirror was also called during the execution, but I don't know why the corresponding push was not performed.
图片.png

Problems finding the cause

At first, it was suspected that dockerfile does not support adding .sh files to the image or that it was not added correctly due to an operation error. However, after calling the image on Alibaba Cloud locally, it was found that the DingTalk push was performed, and it was known that the .sh file had been added to the image. among.
Guess: CMD is executed when the container is created, but it may be overwritten, as suggested in the official documentation
图片.png
1. If you want to run the same program every time you execute the container, you need to use ENTRYPOINT and CMD in combination
2. If the user specifies parameters for docker run, they will override the default values specified in CMD
3. Don't confuse RUN and CMD, RUN is executed at build time, and CMD will not perform any operation during build, but will specify the corresponding command to the image, that is, it will be executed when the container is running, so it is guessed that when gitlab calls the image, it may pass in some Default parameters cause this command to be overridden.
To be tested: Change the CMD to ENTRYPOINT to build again and re-run the pipeline to see if it will push


李明
441 声望19 粉丝