docker是当下很热门的技术,是对以前的部署系统方式的完全改变。以前部署系统,须要安装数据库、初始化数据库,安装jdk,配置jdk,部署应用程序,修改配置文件等,很繁琐。通常现场运维人员很难搞定,现场也会出现不少公司开发环境没有的问题。使用docker技术,只须要运行镜像便可,省去了环境安装、变量配置等繁琐的事情,现场运维人员通过简单培训后能够独立部署系统。移植性好,公司开发环境直接能够部署到现场。css
使用docker技术,主要有两个个关键步骤:一、构建镜像 二、运行镜像。构建镜像,须要将基础支持软件、业务系统打成镜像包。运行镜像,须要将构建的镜像运行起来,外部能够访问。html
docker镜像能够理解为一个高度内聚的应用包,包含运行环境、配置等,能够移植到各个环境中运行。例如一个java应用镜像,运行这个镜像只须要准备一台Linux服务器,服务器上不须要装任何jdk,只须要安装docker,就能够运行该镜像。省去了常规的安装运行环境,配置环境变量,启动各类服务等各类繁琐步骤。前端
对于一个信息系统,镜像通常包括:java
1. mariadb镜像:包含数据库安装文件和业务数据库。数据库安装文件,是数据库基础支持软件。业务数据库是业务系统须要的数据库,业务系统须要提供初始化脚本。mysql
2. nginx镜像:包含nginx基础镜像和业务前端代码。nginx基础镜像是nginx运行软件。做为先后端分离的项目,nginx中存放前端静态页面。nginx
3. java镜像:包含jdk和业务应用程序。jdk是java应用运行基础环境。业务应用是后端系统,向前端提供展现数据。web
以上是信息系统一种部署方式,另外能够将基础镜像和初始化镜像分开,例如mariadb镜像能够分为mariadb安装镜像和业务系统初始化镜像。spring
先在本地环境安装docker,docker中配置仓库地址,指明了镜像存放路径,例如tim:5000,同时须要在hosts中配置tim的映射。sql
在系统的hosts文件中配置映射127.0.0.1 timdocker
一、 准备业务系统初始化脚本。
二、 修改数据库配置文件等
须要准备的文件以下:
utf8mb4.cnf 修改数据库编码字符集为utf8格式,解决中文汉字乱码问题。
run.txt 运行镜像命令。构建镜像非必需文件,这里只是记录运行命令。
blog.sql 初始化脚本。业务系统的初始化镜像,包含建库脚本、建表脚本、初始化数据脚本等。
Dockerfile 生成镜像说明文档。说明镜像如何生成,已经运行时执行的命令。
install_data.sh 数据库启动后执行的脚本。由于mariadb镜像须要在镜像运行后,初始化业务系统数据库,须要该脚本执行业务系统初始化脚本。
Makefile 执行make命令后,执行的镜像生成命令。通常是移除上次的镜像,再生成新的镜像。
重点是Dockerfile文件,内容以下:
#基础镜像使用daocloud.io/library/mysql:8,新构建的镜像以此镜像为基础 FROM daocloud.io/library/mysql:8 #定义工做目录变量 ENV WORK_PATH /usr/local/work #定义会被容器自动执行的目录 ENV AUTO_RUN_DIR /docker-entrypoint-initdb.d #定义sql文件名,这里指向业务系统初始化脚本 ENV FILE_0 blog.sql #定义shell文件名,指向待指向的shell脚本 ENV INSTALL_DATA_SHELL install_data.sh #执行shell命令,建立文件夹 RUN mkdir -p $WORK_PATH #把数据库初始化数据的文件复制到工做目录下 COPY ./$FILE_0 $WORK_PATH/ #把要执行的shell文件放到/docker-entrypoint-initdb.d/目录下,高版本mysql容器会自动执行这个shell(5.7.4不能执行) COPY ./$INSTALL_DATA_SHELL $AUTO_RUN_DIR/ #mysql默认字符集是latain,而它是不支持中文的,utf8mb4 是 utf8 的超集并彻底兼容utf8。修改字符集 COPY utf8mb4.cnf /etc/mysql/conf.d/ #给执行文件增长可执行权限 RUN chmod a+x $AUTO_RUN_DIR/$INSTALL_DATA_SHELL
install_data.sh文件主要是镜像在运行后,自动执行的命令,主要是登陆到已经启动的mysql镜像中,执行初始化脚本。内容以下:
#!/bin/bash mysql -uroot -p$MYSQL_ROOT_PASSWORD <<EOF source $WORK_PATH/$FILE_0;
utf8mb4.cnf内容以下:
# 设置服务器、客户端编码格式 [client] default-character-set = utf8mb4 [mysql] default-character-set = utf8mb4 [mysqld] character-set-client-handshake = FALSE # 忽略客户端的字符集,使用服务器的设置 character-set-server = utf8mb4 collation-server = utf8mb4_unicode_ci
Makefile包含两个命令,也能够拿出来单独执行,内容以下:
build-image: docker rmi tim:5000/blog-mariadb:dev-test docker build -t tim:5000/blog-mariadb:dev-test .
生成镜像:
经过命令进入到镜像生成命令中,执行make命令,或者拷贝Makefile文件中内容执行也能够。例:
docker run --name mysql-blog -p 3306:3306 -e MYSQL_ROOT_PASSWORD=root -d tim:5000/blog-mariadb:dev-test
--name mysql-blog 取名为mysql-blog
-p 3306:3306 将容器的3306端口暴露到宿主机中,外部能够经过3306访问容器,如同访问本机上的数据库同样
-e MYSQL_ROOT_PASSWORD=root 数据库密码为root
-d 之后台进程方式运行
tim:5000/blog-mariadb:dev-test 运行的镜像
须要准备的文件以下:
static是开发的业务系统前端静态页面,先后端分离的,因此这里是html、css、js之类的文件。
Dockerfile文件内容:
# 使用的基础镜像,这个是nginx运行软件 FROM hub.c.163.com/library/nginx # 将业务系统静态页面拷贝到nginx的页面目录中,static会自动建立 COPY static/ /usr/share/nginx/html/static/ # 将blog站点nginx配置文件拷贝到nginx站点配置文件中,能够拷贝多个,端口不一样便可 COPY blog.conf /etc/nginx/conf.d/
blog.conf是nginx配置,内容以下:
# nginx支持配置多个站点,配置文件拷贝到/etc/nginx/conf.d下便可 server { listen 9001; # 监听的端口 server_name localhost; # 服务器名称 location / { # 静态页面拷贝到这里来 root /usr/share/nginx/html/static; index index.html; # 跨域 if ($request_method ~* "(GET|POST|DELETE|PUT)") { add_header "Access-Control-Allow-Origin" *; } if ($request_method = OPTIONS ) { add_header "Access-Control-Allow-Origin" *; add_header "Access-Control-Allow-Methods" 'GET, POST, PUT, DELETE, OPTIONS'; add_header "Access-Control-Allow-Headers" 'Authorization,Content-Type'; return 200; } } }
一样,进入到该目录中,执行make命令。
运行命令:
docker run --name blog-web -d -p 8080:9001 tim:5000/blog-web:dev-test
blog站点nginx配置文件监听端口是9001,暴露出来,外部能够经过8080端口访问系统。
须要准备的文件以下:
Dockerfile:生成镜像的命令,指明了基础镜像来源,镜像中包含的文件,镜像运行的命令等。
下面两个文件是java应用须要的文件,application.properties将应用的参数拿出来,能够进行修改,运行时会覆盖应用中的配置文件,不须要修改应用内部的配置文件,再从新生成jar包。
重点看下Dockerfile文件
# java应用须要java支持,先使用hub.c.163.com/library/java:8做为基础镜像 FROM hub.c.163.com/library/java:8 # 运行的环境变量 ENV TZ Asia/Shanghai ENV LANG zh_CN.UTF-8 ENV LANGUAGE zh_CN:zh ENV LC_ALL zh_CN.UTF-8 # 工做目录 WORKDIR /opt/project # 将文件加到镜像中的目录中。application.properties是配置文件,再也不须要进入jar包中修改配置。blog-1.0-SNAPSHOT.jar是业务应用运行jar ADD application.properties /opt/project/config/application.properties ADD blog-1.0-SNAPSHOT.jar /opt/project/ # 镜像运行后执行的命令 CMD ["java", "-jar", "blog-1.0-SNAPSHOT.jar"]
生成镜像:
进入到镜像制做目录中,执行命令: docker build -t tim:5000/tim-blog:dev-test . 或者执行make命令。
查看镜像是否生成成功
docker images
运行镜像
docker run -p 9091:9091 --link mysql-blog:mysql-blog --name blog tim:5000/blog:dev-test
将端口映射到9091。同时连接到mysql-blog数据库,注意这里是数据库镜像运行时的名称,链接mysql:mysql(容器名:别名),应用名称为blog。
域名需使用链接的容器的别名(即上述所提的mysql-blog:mysql-blog中的第二个mysql-blog),例如应用中数据库链接字符串写法以下:
spring.datasource.url=jdbc:mysql://mysql-blog:3306/blog?useUnicode=true&characterEncoding=utf-8
查看容器运行状况:
docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 9f1a03cf3555 tim:5000/blog-web:dev-test "nginx -g 'daemon ..." 45 seconds ago Up 50 seconds 80/tcp, 0.0.0.0:8080->9001/tcp blog-web aec1c87b63ed tim:5000/blog:dev-test "java -jar blog-1...." 55 seconds ago Up About a minute 0.0.0.0:9091->9091/tcp blog 0c5dcc8543ca tim:5000/blog-mariadb:dev-test "docker-entrypoint..." About a minute ago Up About a minute 0.0.0.0:3306->3306/tcp, 33060/tcp mysql-blog
这样系统须要的3个镜像就运行起来了,在浏览器经过8080端口就能访问系统。
附docker经常使用命令:
docker images 查看全部镜像
docker ps -a 查看全部容器
docker stop containerID 中止容器
docker rm containerID 移除容器
docker rmi imagesID 移除镜像
docker exec -it containerId /bin/bash 进入到容器内部
看以上的运行过程,须要输入三次命令,依次启动数据库、后端、nginx,命令中指明了端口、容器间的依赖等,很繁琐。其实,这3个镜像是构成这个项目不可分割的部分,相互之间有依赖,并且有前后启动顺序。就是说应该当成一个总体来看待。
docker-compose就诞生了。
docker-compose是一组组合命令,融合了镜像生成和镜像运行等一些列命令,用于须要使用多个镜像才能使一个项目运行起来的状况,例如web应用,须要数据库、nginx、后端等服务,使用docker-compose组合这些镜像,快速启动项目。再也不须要依次输入docker run命令启动各个镜像。甚至不须要依次构建各个镜像。
下面以已经存在镜像为例,讲解如何使用docker-compose。
一、首先编写Dockfile,生成镜像。
这一步上面已经讲解过。须要手动依次调用docker build命令,获得须要的3个镜像,固然能够在docker-compose中生成,不须要依次调用。可是按照通常的思路,先是有镜像,而后才是镜像之间的组合,造成一个完整的项目。
二、编写docker-compose.yml文件
主要包括两部分:version、services。
services中就包括须要的3个镜像,能够看到services中各个服务其实就是docker run中的各个参数。
version: "3" services: mysql-blog: # 容器别名 image: tim:5000/blog-mariadb:dev-test # 使用的镜像 volumes: - /opt/mysql/data:/var/lib/mysql # 挂载目录,将容器内部的目录挂载到外部宿主机上 ports: - 3306:3306 # 端口映射 restart: always environment: # 数据库密码 MYSQL_ROOT_PASSWORD: root blog: depends_on: - mysql-blog # 依赖mysql-blog,这个服务要求先运行 image: tim:5000/blog:dev-test links: - mysql-blog # 连接到数据库,这里使用数据库容器的别名 ports: - 9091:9091 restart: always blog-web: depends_on: - blog image: tim:5000/blog-web:dev-test ports: - 8080:9001 restart: always
三、启动
进入到docker-compose.yml目录,运行:
docker-compose up -d
再使用docker ps -a 能够看到services中的3个容器都运行起来了。
- 中止docker-compose down