Docker
Docker is a platform for developing, shipping, and deploying applications quickly in portable, self-sufficient containers, and is used in the Continuous Deployment (CD) stage of the DevOps ecosystem.
INSTALLATION
Environment: CentOS 7 Minimal on VMware Player 17
1$ yun update
2$ yum install -y \
3 yum-utils \
4 device-mapper-persistent-data \
5 lvm2
6$ yum-config-manager \
7 --add-repo https://download.docker.com/linux/centos/docker-ce.repo
8$ yum install -y docker-ce
9$ docker -v
DOCKER COMMANDS
DAEMON
Daemon is a special process of Docker, To start/stop/restart Docker, or to get the status of Docker:
1$ systemctl start docker
2$ systemctl stop docker
3$ systemctl restart docker
4$ systemctl status docker
To enable autostart:
1$ systemctl enable docker
IMAGE
List Images
To list local images, type:
1$ docker images
and it will return a table like:
REPOSITORY | TAG | IMAGE ID | CREATED | SIZE |
---|---|---|---|---|
Note:
- REPOSITORY: the software or service name
- TAG: version number
If we just need Docker Image ID, we can add a parameter -q
1$ docker images -q
Search Images
1$ docker search redis
and it will return a table like:
NAME | DESCRIPTION | STARS | OFFICIAL | AUTOMATED |
---|---|---|---|---|
redis | Redis is an open source key-value store that… | 12156 | [OK] |
Note: OFFICIAL is [OK]
meaning that this image is maintained by Redis team.
Pull Images
If we want to pull Redis, we just type:
1$ docker pull redis
And the latest Redis (i.e., TAG "redis:latest") will be pulled into local machine. However, if we want to pull Redis 5.0, open Docker Hub to verify if it is available, and then:
1$ docker pull redis:5.0
Remove Images
to remove a Docker Image (called redis:5.0
or Image ID is c5da061a611a
), we can type any one of them:
1$ docker rmi redis:5.0
2$ docker rmi c5da061a611a
Trick: If we want to remove all the images, we can use:
1$ docker rmi `docker images -q`
CONTAINER
A Container is built out of Docker Image.
Container Status and Inspection
The status for a container can be UP or Exited.
1$ docker ps # List all the running container
2$ docker ps --all # List all the history container(s)
3$ docker ps -a # Also List all the history container(s)
Or, we can inspect a container for more details:
1$ docker inspect CONTAINER_NAME
Create Container
To create a docker container out of an image, we will first pull image centos:7
from remote repository:
1$ docker pull centos:7
- Interactive Container: create docker image container with
centos:7
, and then enter the container. These threedocker run
commands are equivalent:
1$ docker run --interactive --tty --name=test_container centos:7 /bin/bash
2$ docker run -i -t --name=test_container centos:7 /bin/bash
3$ docker run -it --name=test_container centos:7 /bin/bash
Note:
--interactive
or-i
: keeps STDIN open even if not attached--tty
or-t
: allocates a pseudo-TTY--name=test_container
: assigns a name "test_container" to this containercentos:7
: this container is built on the image called 'centos:7'/bin/bash
: docker will run/bin/bash
of container.- the terminal identidy will switch from
root@localhost
toroot@9b7d0441909b
, meaning the container (9b7d0441909b) is now started.
- Detached Container: Detached Container will not be executed once created, and will not be terminated after
$ exit
. These three commands are equivalent:
1$ docker run --interactive --detach --name=test_container2 centos:7
2$ docker run -i -d --name=test_container2 centos:7
3$ docker run -id --name=test_container2 centos:7
Enter Container
In the last section, we created a container but not enter into it, and we can enter by these 3 equivalent docker exec
commands:
1$ docker exec --interactive --tty test_container2 /bin/bash
2$ docker exec -i -t test_container2 /bin/bash
3$ docker exec -it test_container2 /bin/bash
Stop or Start Container
1$ docker stop CONTAINER_NAME
2$ docker start CONTAINER_NAME
where CONTAINER_NAME
is set accordingly by command $ docker ps --all
.
Remove Container
1$ docker rm CONTAINER_NAME
Note:
- An UP-status docker container cannot be removed, we have to bring it to Exited before removal
- Note the difference between the removal of image and container: to remove image, we type:
docker rmi
, and to remove container, we type:docker rm
.
VOLUMES
Volumes are the preferred mechanism for persisting data generated by and used by Docker containers.
Volume Mapping
To persist data, we can use volume to map the folders. These two commands are equivalent:
1$ docker run -it \
2 --name=testVol1 \
3 --volume ~/data1:/root/container_data1 \
4 --volume ~/data2:/root/container_data2 \
5 centos:7 \
6 /bin/bash
7
8$ docker run -it \
9 --name=testVol1 \
10 -v ~/data1:/root/container_data1 \
11 -v ~/data2:/root/container_data2 \
12 centos:7 \
13 /bin/bash
Note:
--volume
or-v
: map the folder to the container with synchronization. Outside container, we use folders~/data1/
and~/data2/
; Inside container, we use/root/container_data1
and/root/container_data2
- we can only explicitlly use the path
/root/*
(not~/*
) inside container
Volume Container
We first create a container called c3
, and this will be our Volume Container: (Note the parameter -v /Volume
)
1$ docker run -it \
2 --name=c3 \
3 -v /Volume \
4 centos:7 \
5 /bin/bash
Then, we will create two containers, and mount them onto c3
in two separate SSH sessions:
1$ docker run -it --name=c1 \
2 --volumes-from c3 \
3 centos:7 /bin/bash
4$ docker run -it --name=c2 \
5 --volumes-from c3 \
6 centos:7 /bin/bash
you can use $ docker inspect c3
to find out where where c3
is mounted, and snippet of docker inspect
response shown below:
1......
2"Mounts": [
3 {
4 "Type": "volume",
5 "Name": "266**298fb7",
6 "Source": "/var/lib/docker/volumes/266**298fb7/_data",
7 ......
8 }
9 ......
10]
11......
so, we can see that /var/lib/docker/volumes/266**298fb7/_data
outside of container c3
is mapped into /Volume
folder in Docker containers c1
, c2
and c3
.
DEPLOYMENT
MySQL
Deploy MySQL 5.6 into container, and map its port from 3306 (inside container) to port 3307 (outside container).
First, we need to pull MySQL 5.6
1$ docker search mysql
2$ docker pull mysql:5.6
Second, we need to create container:
1$ mkdir ~/mysql
2$ docker run -id \
3 -p 3307:3306 \
4 --name=c_mysql \
5 -v ~/mysql/conf:/etc/mysql/conf.d \
6 -v ~/mysql/logs:/logs \
7 -v ~/mysql/data:/var/lib/mysql \
8 -e MYSQL_ROOT_PASSWORD=toor \
9 mysql:5.6
Note:
-p 3307:3306
or--expose 3307:3306
: map the port 3307 (outside container) to the container's port 3306.-e
or--env
: set the environment variableMYSQL_ROOT_PASSWORD
astoor
, which is the root password set for MySQL.
Third, we start and enter the container and test it:
1$ docker exec -it c_mysql /bin/bash
2$ mysql -uroot -p toor
Fourth, open MySQL with visual tool such as SQLyog Community
Tomcat
Map the port 8081 (outside container) to port 8080 (inside container):
1$ docker search tomcat
2$ docker pull tomcat
3$ mkdir ~/tomcat
4$ docker run -id \
5 --name=c_tomcat \
6 -p 8081:8080 \
7 -v ~/tomcat:/usr/local/tomcat/webapps \
8 tomcat
Now we can publish Servlet to folder ~/tomcat/
(outside container), and Tomcat inside container will find it in path /usr/local/tomcat/webapps
. For demo, I just put a simple HTML ~/tomcat/test/index.html
:
1$ mkdir ~/tomcat/test
2$ echo "Hello Tomcat in Container" > ~/tomcat/test/index.html
Now that the IP address outside container is 192.168.109.128
, I open http://192.168.109.128:8081/test/index.html
, and it will display "Hello Tomcat in Container".
NGINX
First, search and pull NGINX image.
1$ docker search nginx
2$ docker pull nginx
3$ mkdir ~/nginx
4$ mkdir ~/nginx/conf
Second, Copy the nginx.conf
at /etc/conf/nginx.conf
(inside contanier), and paste into ~/nginx/conf/nginx.conf
(inside container):
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log notice;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
#tcp_nopush on;
keepalive_timeout 65;
#gzip on;
include /etc/nginx/conf.d/*.conf;
}
Third, start container:
1$ docker run -id \
2 --name=c_nginx \
3 -p 80:80 \
4 -v ~/nginx/conf/nginx.conf:/etc/nginx/nginx.conf \
5 -v ~/nginx/logs:/var/log/nginx \
6 -v ~/nginx/html:/usr/share/nginx/html \
7 nginx
Now that the IP address outside container is 192.168.109.128
, I open http://192.168.109.128:80
, and it will display "Hello NGINX in Container".
Redis
1$ docker search redis
2$ docker pull redis:5.0
3$ docker run -id \
4 --name=c_redis \
5 -p 6379:6379 \
6 redis:5.0
DOCKERFILE
A Dockerfile is a text document that contains all the instructions a user could call on the command line to build an image. And Docker runs instructions in a Dockerfile in order.
Examples
Deploy Spring Boot
Frist, prepare the Spring Boot project. In this case, we will @RequestMapping("/helloworld")
to print "Hello World" on http://localhost:8080/hello
.
Second, pack the project to single *.jar
file. In tab Maven Projects
- <Your Spring Boot Project Name>
- Lifecycle
- package
, and test *.jar
file with: (the complete path is shown in Console))
1$ java -jar /path/to/springboot-hello.jar
Third, upload to CentOS 7 with SFTP command:
1sftp> PUT /path/to/springboot-hello.jar
And springboot-hello.jar
will be uploaded as springboot-hello.jar
(outside container). Later this file will be moved into ~/springboot-docker/springboot-hello.jar
(also outside container).
Fourth, write springboot_dockerfile
in path ~/springboot-docker/
(outside container):
1# 1. Require Parent Docker Image: `java:8`
2FROM java:8
3
4# 2. Add `springboot-hello.jar` into container as `app.jar`
5ADD springboot-hello.jar app.jar
6
7# 3. command to execute Spring Boot app
8CMD java -jar app.jar
Fifth, build the Docker;
1$ docker build \
2 --file ./springboot_dockerfile \
3 --tag springboot-hello-app \
4 ~/springboot-docker
Note:
--file
or-f
: specifies the Dockerfile namedspringboot_dockerfile
.--tag
or-t
: tags the image asspringboot-hello-app
Sixth, start the image springboot-hello-app
1$ docker run -id -p 9090:8080 springboot-hello-app
Now that the IP address outside container is 192.168.109.128
, we can display the Spring Boot app at http://192.168.109.128:9090/hello
Tailored CentOS
In path ~/tailored_centos/
, create Dockerfile called centos_tailored_dockerfile
:
1# 1. Specify the parent Docker Image: `centos:7`
2FROM centos:7
3
4# 2. Specify the software to be installed
5RUN yum install -y tomcat
6
7# 3. Change to directory
8WORKDIR /usr/local/tomcat/webapps
9
10# 4. Set command to be executed
11CMD /bin/bash
12
13# 5. Expose port
14EXPOSE 8080/tcp
15EXPOSE 8080/udp
16## this also can be done with shell:
17## $ docker run \
18## -p 8080:8080/tcp \
19## -p 8080:8080/udp \
20## <the rest parameters...>
Then we will build the docker:
1$ docker build \
2 -f ./centos_tailored_dockerfile \
3 -t tailored_centos:1
4 ~/tailored_centos
Next, we will run the container out of the docker image:
1$ docker run -it \
2 --name=c_tailored_centos \
3 tailored_centos:1
Syntax
Syntax of Dockerfile:
Name | Description |
---|---|
FROM |
specifies the Parent Image from which you are building |
RUN |
execute commands in a new layer on top of the current image and commit the results |
CMD |
sets the command to be executed when running the image. |
LABEL |
adds metadata (key-value pairs) to a docker image |
EXPOSE |
informs Docker that the container listens on the specified network ports at runtime (tcp by default) |
ENV |
sets the environment variable |
ADD |
copies new files, directories or remote file URLs from <src> and adds them to the filesystem of the image at the path <dest> |
COPY |
copies new files or directories from <src> and adds them to the filesystem of the container at the path <dest> |
ENTRYPOINT |
allows you to configure a container that will run as an executable |
VOLUME |
creates a mount point and marks it as holding externally mounted volumes from native host or other containers |
USER |
sets the user name (UID) and optionally the user group (GID) to use as the default user and group for the remainder of the current stage |
WORKDIR |
sets the working directory for any RUN , CMD , ENTRYPOINT , COPY and ADD instructions that follow it in the Dockerfile |
ARG |
defines a variable that users can pass at build-time to the builder with the $ docker build command |
ONBUILD |
adds to the image a trigger instruction to be executed at a later time, when the image is used as the base for another build |
STOPSIGNAL |
sets the system call signal that will be sent to the container to exit |
HEALTHCHECK |
tells Docker how to test a container to check that it is still working |
SHELL |
allows the default shell used for the shell form of commands to be overridden |