30 minutes to get started with Docker, just read this!
Learn Dockerfile with questions
1, doubt
We all know that we can pull a tomcat image from the remote repository, and then docker run starts the container, and then docker exec-it container id /bin/bash goes into the container, and throws our program into the webapps. All these operations need manual operation step by step, so I ask you: you do not have the deployment authority of QA and production environment, how do you operate these? This involves writing all the manual steps into a Dockerfile, and then giving the file to operations, who build the image and start it.
2, for example,
For example, if you want to deploy a war package using Tomcat, your Dockerfile will contain the following contents:
-
Pull Tomcat down from the remote repository
-
Go to the Tomcat webapps directory
-
Drop the host’s WAR package into the container’s Webapps directory
Then the operation takes the Dockerfile and builds it into an image, and starts the container with a run. You’re done
3, good
The benefits of the above example are not hard to see
-
Dockerfile frees up many of the steps of manual manipulation
-
Dockerfile ensures a unified environment
It’s no longer possible for QA to work, but not online (if it’s due to environmental issues), because dockerfiles are the same, from environment to version. If there is a problem, it is also a code problem, saving a lot of “close contact” time with operations personnel.
What is Dockerfile
What is the definition of a Dockerfile?
Dockerfile is a text document that contains directories for combining images, or “scripts”. It automatically mirrors the installation steps by reading instructions in the Dockerfile.
Add: the file name must be Dockerfile
Dockerfile command
1. Build the image command
<:tags> Dockerfile directory # for example, the last one. It's the current directory, because my Dockerfile is right here, Can also use absolute paths docker build - t chentongwei.com/mywebapp:1.0.0. # then execute the docker to view images can find we just build a mirror image of the docker imagesCopy the code
2. Basic commands
2.1, the FROM
For example, if we want to publish an application to Tomcat, the first step is FROM tomcat FROM tomcat<:tags>Copy the code
First have an impression, below will be actual combat operation.
2.2, LABEL&MAINTAINER
MAINTAINER, general write personal ID or organization ID # LABEL is an easy to read, pure annotation description. MAINTAINER baidu.com LABEL version = "1.0.0" LABEL Description = "We are big Baidu!" #... And so forth descriptive information, pure notes.Copy the code
2.3, WORKDIR
WORKDIR /usr/local/testdir WORKDIR /usr/local/testdir WORKDIR /usr/local/testdir WORKDIR /usr/local/testdir WORKDIR /usr/local/testdir WORKDIR /usr/local/testdir WORKDIR /usr/local/testdirCopy the code
Absolute paths are recommended for this path.
2.4, the ADD ©
Against 2.4.1, COPY
Copy 1.txt to the root directory. TXT / # COPY all files starting with ABC to testdir. COPY ABC * /testdir/ #? Is a placeholder for a single character, such as the matching file abc1.log COPY ABC? .log /testdir/Copy the code
2.4.2, ADD
Copy 1.txt to the ABC directory of the root directory. If/ABC does not exist, ADD 1.txt/ABC # Unzip test.tar.gz and copy it to /home/work/test ADD test.tar.gz /home/work/testCopy the code
Docker recommends using curl/wget instead of ADD when copying files from a remote location. Because you create more mirroring layers with ADD. The mirror layer is also large in size.
2.4.3, contrast
-
Both copy only the files in the directory, not the directory itself.
-
COPY can do things ADD can do, and even additional functions.
-
ADD supports unzipping files while copying and adding remote files (files that are not on the local host).
-
For copying files, you can use COPY. For additional operations, you can use ADD instead.
2.5, ENV
Set environment constants for reference in the following example: ENV JAVA_HOME /usr/local/jdk1.8 RUN ${JAVA_HOME}/bin/ java-jar xxx.jarCopy the code
${XXX} ${XXX} ${XXX} ${XXX}
3. Operation instructions
There are three: RUN&CMD&ENTRYPOINT
1, the RUN
1.1. Execution timing
The RUN command is RUN during image building and modifies files inside the image during build.
1.2. Command format
The command format is not unique to RUN, but is common to CMD and ENTRYPOINT below.
-
SHELL Command Format
Such as
RUN yum -y install vim
Copy the code
-
EXEC command format
Such as
RUN ["yum","-y","install","vim"]
Copy the code
-
The two contrast
SHELL: The current SHELL is the parent process. A subshell process is generated to execute the script. After the script is executed, the subshell process exits and the current parent SHELL process returns.
EXEC: Replace the current process with the EXEC process and keep the PID unchanged. Exit the process directly after execution without returning to the original process.
Summary: Shell creates child processes for execution, EXEC does not create child processes.
-
The EXEC command format is recommended
1.3, for example,
For example, if you want to output a sentence while building an image, you can write the following in a Dockerfile:
RUN ["echo", "image is building!!!"]
Copy the code
For example, if you want to download vim, you can write the following in Dockerfile:
RUN ["yum","-y","install","vim"]
Copy the code
Don’t panic, there will be actual combat to complete the demonstration.
2, CMD
2.1 Execution time
It is executed when the container is started, not when the image is built.
2.2. Explanation
This command is executed when the container is started, and only the last ENTRYPOINT in the Dockerfile will be executed. The EXEC format is recommended. The point is that CMD directives do not take effect if the container is started with additional commands.
2.3, for example,
CMD ["echo", "container starting..."]
Copy the code
3, ENTRYPOINT
3.1 Execution time
It is executed when the container is created, not when the image is built.
3.2. Explanation
This command is executed when the container is started, and only the last ENTRYPOINT in the Dockerfile will be executed. The EXEC format is recommended.
3.3, for example,
ENTRYPOINT ["ps","-ef"]
Copy the code
4. Code demonstration
4.1 demonstration of execution timing
FROM centos RUN ["echo", "image building!!!"] CMD ["echo", "container starting..."]Copy the code
docker build -t chentongwei.com/test-docker-run .
Copy the code
The image building of our RUN was found during the image building process!! So the RUN command is executed when the image is built. There is no container starting… The output.
docker run chentongwei.com/test-docker-run
Copy the code
Result: Container starting… Enough to see that CMD is executed when the container is started.
4.2 CMD and ENTRYPOINT demo
ENTRYPOINT and CMD can be shared, and if they are, they are executed together. The following Demo:
FROM centos RUN ["echo", "image building!!!"] ENTRYPOINT ["ps"] CMD ["-ef"]Copy the code
# build image docker build-t chentongwei.com/docker-run. # Start container docker run chentongwei.com/docker-runCopy the code
Output result:
UID PID PPID C STIME TTY TIME CMD
root 1 0 0 13:02 ? 00:00:00 ps -ef
Copy the code
He gave us the merge execution: ps -ef. The advantage of this is that if the container is started with additional instructions, CMD will be inactivated. We can dynamically change the contents of CMD without rebuilding the image. Such as
docker run chentongwei.com/docker-run -aux
Copy the code
Output result:
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND root 1 2.0 0.0 46340 1692? Rs 13:02 0:00 ps -auxCopy the code
The result is ps-aux, CMD is not executed. But ENTRYPOINT must be executed, which is one of the differences between CMD and ENTRYPOINT.
Four, in actual combat
1. Deploy the application to Tomcat
1.1. Preparation
Mkdir test-dockerfile # mkdir test-dockerfile # mkdir test-dockerfile # mkdir test-dockerfile Hello dockerFile CD HelloWorld/vim index.htmlCopy the code
The effect is shown below:
1.2, Dockerfile
Create dockerfile from test-dockerFile with capital D, no suffix touch DockerfileCopy the code
Write the following in the Dockerfile
FROM tomcat:latest
MAINTAINER baidu.com
WORKDIR /usr/local/tomcat/webapps
ADD helloworld ./helloworld
Copy the code
Line by line explanation:
Line 1: Since we are deploying the application to Tomcat, we need to pull Tomcat from the remote repository as the base image.
Second line: describe things, you can also LABEL XXX XXX to add more detailed comment information.
The third line: CD to/usr/local/tomcat/webapps, found that don’t have the catalog, I automatically created, and then in CD inside
Why this directory? Because tomcat is in /usr/local/tomcat when we run the image, we add /webapps because we need to throw our application under webapps to run. If confused, just keep reading.
Fourth line: Tomcat is available, tomcat webapps have been CD in, so what are we waiting for? Just copy our application to webapps. So the contents of the helloWorld folder on the ADD host are copied to the helloWorld folder in the current directory (webapps, which was just CD in the previous step).
1.3. Create a Mirror
Docker build-t baidu.com/test-helloworld:1.0.0Copy the code
. Indicates the current directory. Dockerfile Dockerfile Dockerfile Nothing new.
Result after the command is executed
[root@izm5e3qug7oee4q1y4opibz test-dockerfile]# docker build-t baidu.com/test-helloworld:1.0.0. Sending build context To Docker daemon 3.584kB Step 1/4: FROM tomcat:latest --> 1b6b1fe7261e Step 3/4: MAINTAINER baidu.com ---> Running in ac58299b3f38 Removing intermediate container ac58299b3f38 ---> 5d0da6398f7e Step Three quarters: WORKDIR /usr/local/tomcat/webapps ---> Running in 1c21c39fc58e Removing intermediate container 1c21c39fc58e ---> 9bf9672cd60e Step 4/4 : ADD helloworld ./helloworld ---> 6d67c0d48c20 Successfully built 6d67c0d48c20 Successfully tagged baidu.com/test-helloworld:1.0.0Copy the code
Looks like 1/2/3/4 steps? What does that mean? This is the idea of mirror layering. Are you successful?
Now, does our mirror image actually exist?
docker images
Copy the code
perfect
1.4. Start the container
Docker run -d -p 81:8080 baidu.com/test-helloworld:1.0.0 # Then check whether docker ps exists in the containerCopy the code
Browser visit: http:// server IP: 8100 / helloworld/index. HTML, perfect. This helloWorld is our own application in our Dockerfile.
1.5. Enter the container
docker exec -it 730f9e144f68 /bin/bash
Copy the code
Question 1: How to enter the container directly in the webapps directory, this is because our image is made with Dockerfile, Dockerfile above our own WORKDIR to the webapps directory.
Question 1: We can see the HelloWorld application in Dockerfile under ls here
root@730f9e144f68:/usr/local/tomcat/webapps# ls
helloworld
Copy the code
Answer 2: the WORKDIR Dockerfile/usr/local/tomcat/webapps, why is this directory is also very clear. The Tomcat in the container is right here
root@730f9e144f68:/usr/local/tomcat/webapps# pwd
usr/local/tomcat/webapps
Copy the code
2. Create Redis image from 0
Generally no one makes Redis image, Redis has an official docker image, docker pull on the line. This is to demonstrate the above command, from 0 to 1.
2.1. Preparation
1. Go to the official website to download the source package of Redis, because we demonstrate the process of Redis from scratch.
2. Prepare the Redis configuration file redis-6379.conf
2.2, Dockerfile
RUN ["yum", "install", "-y", "GCC "," gcc-C ++", "net-tools", ADD redis-4.0.14.tag.gz. WORKDIR = /usr/local WORKDIR = /usr/local /usr/local/redis-4.0.14/ SRC /usr/local/redis-4.0.14/ SRC Redis-6379.conf. # EXPOSE ["redis-server", "redis-6379.conf"]Copy the code
2.3 Make an image && Start the container
Docker run -p 6379:6379 chentongwei.com/docker-redisCopy the code
After the execution of the above three sets of small lianzhao redis up, you can redis- CLI to link. It is also possible for Docker Exec to enter the container to view it.
3. Deploy jar packages with Docker
FROM openJDK: 8-jdK-alpine :latest ADD target/helloworld-0.0.1 -snapshot.jar /helloworld.jar ENTRYPOINT ["java","-jar","/helloworld.jar"]Copy the code
Build the image and run the container. It’s pretty simple.
5. Supplementary: The concept of mirror layer
1, Dockerfile
FROM tomcat:latest
MAINTAINER baidu.com
WORKDIR /usr/local/tomcat/webapps
ADD helloworld ./helloworld
Copy the code
2. Mirror layer
Build a Dockerfile like this:
Sending build context to Docker Daemon 3.584kB Step 1/4: FROM tomcat:latest --> 1b6b1fe7261e Step 2/4: MAINTAINER baidu.com ---> Running in ac58299b3f38 Removing intermediate container ac58299b3f38 ---> 5d0da6398f7e Step Three quarters: WORKDIR /usr/local/tomcat/webapps ---> Running in 1c21c39fc58e Removing intermediate container 1c21c39fc58e ---> 9bf9672cd60e Step 4/4 : ADD helloworld ./helloworld ---> 6d67c0d48c20 Successfully built 6d67c0d48c20 Successfully tagged baidu.com/test-helloworld:1.0.0Copy the code
The number of lines in the Dockerfile determines the number of steps in Step. The number of lines in the Dockerfile determines the number of steps.
So what does each step mean?
Each step will create a temporary container for us. The advantage of this is that the next time we build the Dockerfile, we will read the existing container directly from the cache instead of creating the container repeatedly. This will save a lot of build time and resources to create the container repeatedly. For example:
FROM tomcat:latest
MAINTAINER baidu.com
WORKDIR /usr/local/tomcat/webapps
ADD helloworld ./helloworld
ADD helloworld ./helloworld2
Copy the code
Nothing is done, just deploy one more copy of HelloWorld and rename it helloWorld2 inside the container
Step 1/5 : FROM tomcat:latest
---> 1b6b1fe7261e
Step 2/5 : MAINTAINER baidu.com
---> Using cache
---> 5d0da6398f7e
Step 3/5 : WORKDIR /usr/local/tomcat/webapps
---> Using cache
---> 9bf9672cd60e
Step 4/5 : ADD helloworld ./helloworld
---> Using cache
---> 6d67c0d48c20
Step 5/5 : ADD helloworld ./helloworld2
---> 4e5ffc24522f
Successfully built 4e5ffc24522f
Successfully tagged baidu.com/test-helloworld:1.0.1
Copy the code
The first can be found as follows:
1.Step becomes 5.
2. The first four steps used the Cache Using Cache, and did not create the container repeatedly. Step 1 does not use Cache because it pulls tomcat:latest directly from the local repository as the base image. Run creates the container.
Step 5 recreates the temporary container.
END
Java interview questions column
Interviewer: Talk about capacity and expansion implementation in HashMap
【82 】 When asked about SQL optimization in an interview, you should read this article.
[83] What is the difference between Redis and MongoDB? Just look here
What can Design patterns ask in an interview? For example, there are three singleton implementations
[issue 85] Six principles of Java object-oriented design
A String of interview Questions and answers
Q: Why should Java serialization and deserialization implement Serializable interface
Interviewer: Can you talk about how interface beans are injected in Spring?
Q: How many HTTP requests can a TCP connection send?
Interviewer: Talk about the idea of using Redis to achieve a large-scale post count
I know you're "watching."Copy the code
Interviewer: You say you are proficient in Docker, so why don’t you tell me more about Dockerfile