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
3. Create a container based on the image
sudo docker run -it ding-file:1.2
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.
1. Create a mirror warehouse
2. Bind with your own code repository to upload the required files
3. Set build rules to locate the required files
4. After the build is completed, use the public network address plus the version number to call
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:
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.
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
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
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。