这里的SSM项目中所需要构建的镜像比较简单,只用到了 一般开发中用的一些组件:
1.Redis
2.Mysql
3.tomcat
docker这里不做简介,直接说docker-compose
1.Compose是Docker的服务编排工具,主要用来构建基于Docker的复杂应用, Compose 通过一个配置文件来管理多个Docker容器,非常适合组合使用多个容器进行开发的场景。
2.通过Docker-Compose用户可以很容易地用一个配置文件定义一个多容器的应用,然后使用一条指令安装这个应用的所有依赖,完成构建。Docker-Compose解决了容器与容器之间如何管理编排的问题。
准备工作:
1.虚拟机一台(这里用的是linux,CentOS),虚拟机可以自己装,也可以租阿里云的ecs云服务器,学生套餐。(这里用的阿里云esc)。
2.服务器中已经安装好了docker和docker-compose,关于安装教程网上一堆,这里不做重复说明。
3.开发工具用的IDEA,项目骨架用的是Maven来管理
4.因为ssm项目中的Spring没有自带tomcat,所以这里的项目是直接打成War包通过dockerfile中的copy命令自动上传到容器中的tomcat的webapps目录下,然后tomcat在启动的时候就会自动运行你的项目啦。
5.一个完整的SSM项目(这里就不介绍怎么去整合SSM项目了,网上都有),最下面提供本次教程的所有源代码,包括一个简单的ssm项目用来做测试。
废话不多说,直接上重点!
整个项目的骨架,我把所有的docker文件都放在了IDEA的项目中便于大家的理解。
***流程:***
编写docker-compose.yml文件来编排我们整个项目中需要用到的所有依赖的镜像,通过构造这些镜像来生成一个个的实际容器为最后的一键部署做准备
这里说明一点,一个docker的镜像可以是直接从远程的docker提供的镜像仓库拉取(因为现在的docker仓库拥有非常多的可以直接用的常用开发所需要的组件的镜像),但是在实际的业务开发过程中,有些镜像是需要自己根据实际情况来自定义的,所以,这里docker给我们提供了 一个可以自己重构镜像的方式来DIY生成我们想要的镜像,即通过一个Dockerfile文件来实现重构。
1.tomcat镜像的制作:
1.1 tomcat文件夹下的Dockerfile文件
# 直接从docker提供的远程镜像仓库中拉取最新的tomcat组件
FROM tomcat
# 本镜像的制作者的信息
MAINTAINER "leo-bin" <1114011786@qq.com>
# 把该容器的时区设置为北京时区
ENV TZ=Asia/Shanghai
# 把当前文件目录下的docker-ssm.war移动到容器中tomcat自动启动的目录下
COPY ./docker-ssm.war /usr/local/tomcat/webapps/
2.mysql镜像的制作:
2.1 Dockerfile文件
这里遇到了一个坑,至今没想到是为什么,之前我这里是直接拉的mysql5.7.28版本的 ,但是弄了好久,服务确实能够启动,MySQL也能访问,但是就是没有我的要求去自动创建数据库和表,查了一下,发现,原因就是那个docker-entrypoint.sh文件一直没有被执行,百度了好久,看到一篇stackflow的文章:
链接
里面说到是有些镜像是不支持docker-entrypoint-initdb.d这个文件去自动执行sh或者sql脚本的功能的,最后换成了最新版mysql镜像,问题成功解决。
FROM mysql:latest
MAINTAINER "leo-bin" <1114011786@qq.com>
# mysql的工作位置
ENV WORK_PATH /usr/local/
# 定义会被容器自动执行的目录
ENV AUTO_RUN_DIR /docker-entrypoint-initdb.d
# 初始化数据库的SQL文件
ENV FILE_0 docker_ssm_schema.sql
# 执行SQL
ENV INSTALL_DATA_SHELL docker-entrypoint.sh
# 把要执行的sql文件放到MySQL的工作目录下
COPY ./$FILE_0 $WORK_PATH/
# 把要执行的shell文件放到/docker-entrypoint-initdb.d/目录下,容器会自动执行这个shell
COPY ./$INSTALL_DATA_SHELL $AUTO_RUN_DIR/
# 给执行文件增加可执行权限
RUN chmod a+x $AUTO_RUN_DIR/$INSTALL_DATA_SHELL
2.2 docker_ssm_schema.sql文件:
在mysql容器初始化之后需要执行的sql文件,以此来节省初始化我们的容器之后还要连接数据库进行建库建表的一系列工作了
CREATE DATABASE `docker_ssm` CHARACTER SET 'utf8mb4';
use docker_ssm;
create table docker_ssm_test
(
id int auto_increment
primary key,
name varchar(10) null
) DEFAULT CHARSET = utf8mb4;
2.3 docker-entrypoint.sh文件:
本文件实现了在本容器第一次启动的时候自动执行SQL脚本文件。这一过程存在于第一次使用镜像构建容器时,下一次restart容器时则不会存在等待其再次自动执行SQL的过程。根据其他博主的文章来看,这里的sql启动脚本sh文件必须叫这个名字:docker-entrypoint.sh
#!/bin/bash
#-u后面为数据库用户名 -p后面跟的是密码,如果数据库密码不是root记得修改这里,
#而且,-p后面一定要紧跟你的密码,不要有空格!!
mysql -u root -proot </usr/local/docker_ssm_schema.sql;
EOF
**2.4 my.cnf文件:
这里还引入了一个MySQL的配置文件,为了防止出现中文乱码,这里我们不用容器中安装MySQL时自带的配置文件,而是将这里的文件在容器启动的时候自动替换掉原来的配置文件:
# For advice on how to change settings please see
# http://dev.mysql.com/doc/refman/5.6/en/server-configuration-defaults.html
[client]
default-character-set=utf8mb4
#explicit_defaults_for_timestamp=true
#default-time-zone='Asia/Shanghai'
[mysqld]
#
# Remove leading # and set to the amount of RAM for the most important data
# cache in MySQL. Start at 70% of total RAM for dedicated server, else 10%.
# innodb_buffer_pool_size = 128M
#
# Remove leading # to turn on a very important data integrity option: logging
# changes to the binary log between backups.
# log_bin
#
# Remove leading # to set options mainly useful for reporting servers.
# The server defaults are faster for transactions and fast SELECTs.
# Adjust sizes as needed, experiment to find the optimal values.
# join_buffer_size = 128M
# sort_buffer_size = 2M
# read_rnd_buffer_size = 2M
#character-set-client-handshake=FALSE
character-set-server = utf8mb4
#character_set_server=utf8mb4
collation-server = utf8mb4_unicode_ci
#collation_server=utf8mb4_unicode_ci
init_connect='SET NAMES utf8mb4'
lower_case_table_names=1
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
log-bin=/var/lib/mysql/mysql-bin
server-id=123456
# Disabling symbolic-links is recommended to prevent assorted security risks
symbolic-links=0
# Recommended in standard MySQL setup
sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES
[mysqld_safe]
log-error=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid
#[mysql]
#default_character_set=utf8mb4
3 编写docker-compose.yml文件:
目的:使用一个docker-compose文件来进行容器服务的编排,将项目中所有需要用到的镜像进行一个统一的配置,以此来达到一键部署的最终效果
version: "2"
services: #控制image的运行方式
tomcat: #编排文件中容器的别名
build: ./tomcat #从当前文件目录下的tomcat文件夹下寻找Dockerfile文件开始构建tomcat镜像
image: tomcat-ssm #构建之后镜像的名字
container_name: tomcat-ssm #容器的名字
restart: always #容器重启之后总是会重新构建本镜像
depends_on: #依赖于mysql和redis,目的是为了在mysql和redis启动之后再启动本容器
- mysql
- redis
ports:
- "8888:8080" #冒号左边的8888代表宿主机中的端口,右边的8080代表容器中的端口
mysql:
build: ./mysql
image: mysql-ssm:mysql
container_name: mysql-ssm
restart: always
ports:
- "3301:3306"
volumes: #这里多挂载了一个conf文件,目的就是为了防止mysql原始配置文件不生效,产生乱码的情况
- "/temp/test/docker-ssm/conf:/etc/mysql/conf.d"
- "/temp/test/docker-ssm/logs:/logs"
- "/temp/test/docker-ssm/data:/var/lib/mysql"
command: [
'--character-set-server=utf8mb4',
'--collation-server=utf8mb4_unicode_ci'
]
environment: #在mysql初始化的时候设置登陆密码
MYSQL_ROOT_PASSWORD: "root"
redis:
image: redis:latest #如果本地有该名称的镜像,那么就拉取本地的镜像,如果本地没有,则从数据仓库中拉取最新版的镜像
container_name: redis-ssm
restart: always
ports:
- "6380:6379"
volumes:
- "/temp/test/docker-ssm/redis_data:/data"
#将宿主机上的redis_data文件挂载到本容器上的/data上,达到数据持久化
#需要注意的是,如果volume是空的而container中的目录有内容,那么docker会将container目录中的内容拷贝到volume中
#但是如果volume中已经有内容,则会将container中的目录覆盖
所有的配置文件和项目都已经完成,现在开始将项目部署在阿里云服务器上
部署流程:
1.把我们的SSM项目打成war包,放在docker-ssm/tomcat文件夹下:
如何利用IDEA中的maven把项目打成war包?参考这篇博客:链接
2.把docker-ssm文件上传到阿里云服务器的/tmp/test下(路径无所谓,我这里是放在了这里):
控制台下,进入这个路径目录下/tmp/test/docker-ssm,并开始执行docker的命令:
先查看本宿主机上的docker容器的运行情况:
正在运行的容器:
docker ps
可以看到现在还没有正在运行中的容器,(我都给关了)
所有存在的容器的情况(包括运行中的和已经停止的)
docker ps -a
***重头戏来啦!!!使用docker-compose的命令一键启动并部署项目:***
docker-compose up -d
note:-d表示后台运行
先是构建了mysql的镜像,创建了一个叫做mysql-ssm的容器
马上就开始构建tomcat镜像:
三个容器成功启动!
使用命令查看下现在docker中的情况:
容器已经成功启动了!我们来验证下我们的项目是否成功部署上去了!
***mapper中的sql语句:***
根据端口的映射规则,我们的实际访问地址是:
主机号+端口号+项目名+接口地址
这里是:
47.100.170.169:8888/docker-ssm/docker/test
最后我把我整个项目的都上传在了GitHub上,有兴趣可以直接拉。
GitHub地址