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.
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.
Environment: CentOS 7 Minimal on VMware Player 17
$ yun update$ yum install -y \ yum-utils \ device-mapper-persistent-data \ lvm2$ yum-config-manager \ --add-repo https://download.docker.com/linux/centos/docker-ce.repo$ yum install -y docker-ce$ docker -vDaemon is a special process of Docker, To start/stop/restart Docker, or to get the status of Docker:
$ systemctl start docker$ systemctl stop docker$ systemctl restart docker$ systemctl status dockerTo enable autostart:
$ systemctl enable dockerTo list local images, type:
$ docker imagesand 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
$ docker images -q$ docker search redisand 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.
If we want to pull Redis, we just type:
$ docker pull redisAnd 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:
$ docker pull redis:5.0to remove a Docker Image (called redis:5.0 or Image ID is c5da061a611a), we can type any one of them:
$ docker rmi redis:5.0$ docker rmi c5da061a611aTrick: If we want to remove all the images, we can use:
$ docker rmi `docker images -q`A Container is built out of Docker Image.
The status for a container can be UP or Exited.
$ docker ps # List all the running container$ docker ps --all # List all the history container(s)$ docker ps -a # Also List all the history container(s)Or, we can inspect a container for more details:
$ docker inspect CONTAINER_NAMETo create a docker container out of an image, we will first pull image centos:7 from remote repository:
$ docker pull centos:7- Interactive Container: create docker image container with
centos:7, and then enter the container. These threedocker runcommands are equivalent:
$ docker run --interactive --tty --name=test_container centos:7 /bin/bash$ docker run -i -t --name=test_container centos:7 /bin/bash$ docker run -it --name=test_container centos:7 /bin/bashNote:
--interactiveor-i: keeps STDIN open even if not attached--ttyor-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/bashof container.- the terminal identidy will switch from
root@localhosttoroot@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:
$ docker run --interactive --detach --name=test_container2 centos:7$ docker run -i -d --name=test_container2 centos:7$ docker run -id --name=test_container2 centos:7In the last section, we created a container but not enter into it, and we can enter by these 3 equivalent docker exec commands:
$ docker exec --interactive --tty test_container2 /bin/bash$ docker exec -i -t test_container2 /bin/bash$ docker exec -it test_container2 /bin/bash$ docker stop CONTAINER_NAME$ docker start CONTAINER_NAMEwhere CONTAINER_NAME is set accordingly by command $ docker ps --all.
$ docker rm CONTAINER_NAMENote:
- 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 are the preferred mechanism for persisting data generated by and used by Docker containers.
To persist data, we can use volume to map the folders. These two commands are equivalent:
$ docker run -it \ --name=testVol1 \ --volume ~/data1:/root/container_data1 \ --volume ~/data2:/root/container_data2 \ centos:7 \ /bin/bash
$ docker run -it \ --name=testVol1 \ -v ~/data1:/root/container_data1 \ -v ~/data2:/root/container_data2 \ centos:7 \ /bin/bashNote:
--volumeor-v: map the folder to the container with synchronization. Outside container, we use folders~/data1/and~/data2/; Inside container, we use/root/container_data1and/root/container_data2- we can only explicitlly use the path
/root/*(not~/*) inside container
We first create a container called c3, and this will be our Volume Container: (Note the parameter -v /Volume)
$ docker run -it \ --name=c3 \ -v /Volume \ centos:7 \ /bin/bashThen, we will create two containers, and mount them onto c3 in two separate SSH sessions:
$ docker run -it --name=c1 \ --volumes-from c3 \ centos:7 /bin/bash$ docker run -it --name=c2 \ --volumes-from c3 \ centos:7 /bin/bashyou can use $ docker inspect c3 to find out where where c3 is mounted, and snippet of docker inspect response shown below:
......"Mounts": [ { "Type": "volume", "Name": "266**298fb7", "Source": "/var/lib/docker/volumes/266**298fb7/_data", ...... } ......]......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.
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
$ docker search mysql$ docker pull mysql:5.6Second, we need to create container:
$ mkdir ~/mysql$ docker run -id \ -p 3307:3306 \ --name=c_mysql \ -v ~/mysql/conf:/etc/mysql/conf.d \ -v ~/mysql/logs:/logs \ -v ~/mysql/data:/var/lib/mysql \ -e MYSQL_ROOT_PASSWORD=toor \ mysql:5.6Note:
-p 3307:3306or--expose 3307:3306: map the port 3307 (outside container) to the container’s port 3306.-eor--env: set the environment variableMYSQL_ROOT_PASSWORDastoor, which is the root password set for MySQL.
Third, we start and enter the container and test it:
$ docker exec -it c_mysql /bin/bash$ mysql -uroot -p toorFourth, open MySQL with visual tool such as SQLyog Community
Map the port 8081 (outside container) to port 8080 (inside container):
$ docker search tomcat$ docker pull tomcat$ mkdir ~/tomcat$ docker run -id \ --name=c_tomcat \ -p 8081:8080 \ -v ~/tomcat:/usr/local/tomcat/webapps \ tomcatNow 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:
$ mkdir ~/tomcat/test$ echo "Hello Tomcat in Container" > ~/tomcat/test/index.htmlNow 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”.
First, search and pull NGINX image.
$ docker search nginx$ docker pull nginx$ mkdir ~/nginx$ mkdir ~/nginx/confSecond, 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:
$ docker run -id \ --name=c_nginx \ -p 80:80 \ -v ~/nginx/conf/nginx.conf:/etc/nginx/nginx.conf \ -v ~/nginx/logs:/var/log/nginx \ -v ~/nginx/html:/usr/share/nginx/html \ nginxNow 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”.
$ docker search redis$ docker pull redis:5.0$ docker run -id \ --name=c_redis \ -p 6379:6379 \ redis:5.0A 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.
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))
$ java -jar /path/to/springboot-hello.jarThird, upload to CentOS 7 with SFTP command:
sftp> PUT /path/to/springboot-hello.jarAnd 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. Require Parent Docker Image: `java:8`FROM java:8
# 2. Add `springboot-hello.jar` into container as `app.jar`ADD springboot-hello.jar app.jar
# 3. command to execute Spring Boot appCMD java -jar app.jarFifth, build the Docker;
$ docker build \ --file ./springboot_dockerfile \ --tag springboot-hello-app \ ~/springboot-dockerNote:
--fileor-f: specifies the Dockerfile namedspringboot_dockerfile.--tagor-t: tags the image asspringboot-hello-app
Sixth, start the image springboot-hello-app
$ docker run -id -p 9090:8080 springboot-hello-appNow 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
In path ~/tailored_centos/, create Dockerfile called centos_tailored_dockerfile:
# 1. Specify the parent Docker Image: `centos:7`FROM centos:7
# 2. Specify the software to be installedRUN yum install -y tomcat
# 3. Change to directoryWORKDIR /usr/local/tomcat/webapps
# 4. Set command to be executedCMD /bin/bash
# 5. Expose portEXPOSE 8080/tcpEXPOSE 8080/udp## this also can be done with shell:## $ docker run \## -p 8080:8080/tcp \## -p 8080:8080/udp \## <the rest parameters...>Then we will build the docker:
$ docker build \ -f ./centos_tailored_dockerfile \ -t tailored_centos:1 ~/tailored_centosNext, we will run the container out of the docker image:
$ docker run -it \ --name=c_tailored_centos \ tailored_centos:1Syntax 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 |