之前讲解过Docker安装单个服务的系列教程,没看过的可以点击下面的链接回顾一下:
Docker的用途我在这里就不做赘述了,不懂的自己戳上面的链接学习,假如现在我们有个Springboot应用,里面用到了mysql、Redis、Nginx等服务,那现在我们要用Docker部署我们的服务,通常需要下面几步:
安装docker
使用docker安装Redis
使用docker安装Mysql
使用docker安装、配置Nginx
springboot应用打成Jar包和编写dockerfile
安装好以上服务之后,我们还要一一启动,然后再运行项目才能访问,虽然说docker有一次打包到处运行、节省存储空间和资源,应用隔离和服务器整合等优点,但是仔细看上面的部署步骤,即便我们用了docker,也还是要在docker里手动安装其他服务,现在只有redis、mysql、nginx几个服务,如果我们以后还要加ES、Mongo等等越来越多的服务,好像并没有提高很多效率,那作为“万能”的程序员,有解决方法吗?那必须有啊,下面就进入本文的重点:docker-compose。
docker-compose简介
Compose是用于定义和运行多容器Docker应用程序的工具,是docker的服务编排工具,主要应用于构建基于Docker的复杂应用,compose通过一个配置文件来管理多个docker容器,适合组合使用多个容器进行开发的场景。使用compose,可以使用yml或者yaml文件配置应用程序的服务。然后,通过一个命令,可以从配置中创建和启动所有服务。更多资料可以参考官网:https://docs.docker.com/compose/overview/docker-compose安装
安装docker相关依赖环境:
# 安装依赖
sudo yum install -y yum-utils device-mapper-persistent-data lvm2
# 添加docker下载仓库
sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
# 安装docker-ce
sudo yum install docker-ce
# 启动docker-ce
sudo systemctl start docker
# 验证
sudo docker --version
compose官网安装文档:https://docs.docker.com/compose/install/#install-compose
1、安装Run this command to download the latest version of Docker Compose
sudo curl -L https://github.com/docker/compose/releases/download/1.21.2/docker-compose-$(uname -s)-$(uname -m) -o /usr/local/bin/docker-compose
2、赋权Apply executable permissions to the binary:
sudo chmod +x /usr/local/bin/docker-compose
3、Optionally, install command completion for the bash and zsh shell.
4、测试(查看版本)Test the installation
docker-compose --version
docker-compose部署服务详解使用compose部署应用一般需要下面几个步骤:
用dockerfile,或者镜像定义应用程序所依赖的环境,以便在任何地方都可以直接复制。
在docker-compose.yaml中定义应用程序需要的服务,以便这些服务可以在单独的环境中一起运行。
运行docker-compose build 安装应用程序所需要的服务镜像。
运行docker-compose up -d 启动并在后台运行整个应用程序。
运行docker compose down 停止整个应用程序。
下面我们来详细讲解上面的四个步骤。
docker-compose部署Spring Boot+Nginx+Redis+Mysql实战
历经了一个月,终于将个人的博客发布上线了,原来准备用传统的方式先草草上线,可是对于一个对前沿技术有强迫症的开发者来说,哪怕不精通不擅长,至少要懂点皮毛,要在别人聊起的时候至少能听懂,于是果断换了docker方式部署,可部署过程中发现既然都已经开始了,索性就再为难自己一下,干脆一次性到位好了,直接用compose方式。其实人很多时候都是在“为难自己”的过程中成长,只要你勇敢的迈出第一步。
好了,废话少说,在大概的看了官方文档,又谷哥度娘了几篇相关文章,在失败了7次,解决了4个问题之后,最终如愿使用compose方式上线成功,下面就将整个过程记录下来和大家分享,所有步骤都经过本人亲测,希望对码之初的乡亲们也有帮助。
一、看一下完整的目录结构
下面的common、dao、service、web模块不用多做介绍了,是个人博客项目,上面的docker-build文件夹就是使用compose方式部署的文件夹,主要包括:
Spring Boot web项目打成的jar包
jar对应的Dockerfile
compose方式的核心配置文件docker-compose.yaml
config文件夹,是将宿主机本地配置挂载到docker容器中的配置文件
data文件夹:存放的一些初始化数据或者配置
log日志文件夹
二、Dockerfile文件详解
FROM java:8
#FROM maven:3.5-jdk-8
VOLUME /tmp
ADD mazhichu.jar mazhichu.jar
EXPOSE 8082
#RUN bash -c 'touch /mazhichu.jar'
ENTRYPOINT ["java","-Djava.security.egd=file:/prod/./urandom","-Dspring.profiles.active=prod", "-jar","/mazhichu.jar"
命令解释:
FROM java:8:基础镜像环境 JDK1.8
VOLUME /tmp:指定了挂载目录
ADD mazhichu.jar mazhichu.jar:把指定的 jar 包拷贝到 Docker 容器中并命名为 mazhichu.jar
EXPOSE 8082:运行监听端口
RUN bash -c 'touch /mazhichu.jar':等同于上面的拷贝jar文件到容器
ENTRYPOINT...:启动jar的命令并指定运行环境等参数
三、docker-compose.yaml文件详解
version: '3'
services:
nginx:
container_name: nginx
image: nginx:1.14
environment:
- TZ=Asia/Shanghai
ports:
- "80:80"
volumes:
- ./config/nginx/conf.d:/etc/nginx/conf.d
# - ./data/nginx/:/usr/share/nginx/html/
- ./log/nginx/:/var/log/nginx/
restart: always
redis:
container_name: redis
image: redis:5.0.7
environment:
- TZ=Asia/Shanghai
ports:
- "6379:6379"
volumes:
- ./config/redis/redis.conf:/usr/local/etc/redis/redis.conf
- ./data/redis/:/data/
- ./log/redis/:/var/log/redis/
command: redis-server /usr/local/etc/redis/redis.conf
restart: always
mysql:
container_name: mysql
image: mysql:8.0.18
environment:
TZ: Asia/Shanghai
MYSQL_DATABASE: mazhichu
MYSQL_ROOT_PASSWORD: Moore@2019
MYSQL_ROOT_HOST: '%'
ports:
- "3306:3306"
volumes:
- ./config/mysql/my.cnf:/etc/mysql/conf.d/my.cnf
- ./data/mysql/:/var/lib/mysql/
- ./data/init/:/docker-entrypoint-initdb.d/
- ./log/mysql/:/var/log/mysql/
command: [
'--character-set-server=utf8mb4',
'--collation-server=utf8mb4_unicode_ci',
#这行代码解决无法访问的问题
'--default-authentication-plugin=mysql_native_password'
]
security_opt:
- seccomp:unconfined
restart: always
mazhichu:
container_name: mazhichu
build:
context: .
dockerfile: Dockerfile
environment:
TZ: Asia/Shanghai
spring.datasource.host: mysql
spring.redis.host: redis
expose:
- "8082"
depends_on:
- nginx
- redis
- mysql
links:
- "mysql:mysql"
restart: always
# networks:
# - my-network
# command: mvn clean spring-boot:run -Dspring-boot.run.profiles=prod
配置解释:
version: '3': 表示使用第三代语法来构建 docker-compose.yaml 文件。
services: 用来表示 compose 需要启动的服务,上面的配置文件中有四个服务分别为:nginx、redis、mysql还有我的博客项目mazhichu(码之初)。
Image:指定下载镜像版本
container_name: 指定容器名称
environment: 此节点下的信息会当作环境变量传入容器,例如mysql 服务配置了数据库、密码和权限信息。
ports: 表示对外开放的端口
volumes: 加载本地目录下的配置文件到容器目标地址下
restart: always 表示如果服务启动不成功会一直尝试。
depends_on:配置依赖服务,表示需要先启动 depends_on 下面的服务后,再启动本服务。
links:与depends_on相对应,depends_on控制启动顺序,links控制容器连接问题。值为"服务名:别名"或者直接使用服务名
command: mvn clean spring-boot:run -Dspring-boot.run.profiles=docker: 表示以这个命令来启动项目,-Dspring-boot.run.profiles=prodr表示使用 application-prod.yml文件配置信息进行启动。
networks:加入指定网络,我这儿没用到。
四、config文件夹详解
config文件夹下是将宿主机本地配置挂载到docker容器中的配置,在docker-compose.yaml文件中使用volumes指定。因为单个安装这些服务时我们也会这样做,可以见文章开头的相关文章,这儿我就把我的贴一下,大家参考一下就好。
my.cnf:mysql的配置,注意改变加密方式那个位置
[client]
default-character-set=utf8mb4
[mysqld]
character-set-client-handshake = FALSE
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci
# 数据库唯一 ID,主从的标识号绝对不能重复。
server-id = 1
# 开启 bin-log,并指定文件目录和文件名前缀
log-bin=/var/log/mysql/binlog
# bin-log 日志文件格式,设置为 MIXED 可以防止主键重复。
binlog_format = mixed
# 改变加密方式,远程连接(这个很重要)
default_authentication_plugin=mysql_native_password
# 解决远程访问慢问题
skip-name-resolve
[mysql]
default-character-set=utf8mb4
mzc.conf:主要配置ip域名映射,注意proxy_pass那儿的码之初是docker-compose.yaml文件中指定的服务名。
upstream mazhichu {
server mazhichu:8082;
}
server {
listen 80;
server_name www.mazhichu.cn;
charset utf-8;
location / {
proxy_pass http://mazhichu;
proxy_set_header Host $host:$server_port;
proxy_set_header X-Forwarded-Host $server_name;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
redis.conf:我这儿其实就是redis.conf的文件,只是改变了里面的连接redis的密码。
五、详细步骤
1、将docker-build文件夹上传到centos指定目录中,使用命令:
scp -r docker-build mzc:/usr/local/server
友情提示:
直接使用scp拷贝文件提示无权限的时候,需要加上一个-r就可以了。
mzc:/usr/local/server:这儿我直接使用的远程服务器别名,是不是很方便,感兴趣的可以看我这篇公众号:ssh使用别名免密登录远程服务器
2、给log文件夹加上所有权限,然后重启一下docker服务
3、使用docker-compose build构建服务
4、使用docker-compose up -d 启动并在后台运行yaml中定义的所有服务
至此,使用compose方式部署Spring Boot+Nginx+Redis+Mysql服务全部完成,访问博客主页http://www.mazhichu.cn,看到可以成功访问。
docker-compose常用命令介绍
docker-compose --verbose:输出更多的调试信息
docker-compose --version:查看compose的版本
docker-compose -f --file FILE:使用特定的compose模板文件,默认为docker-compose.yaml。
docker-compose -p --project-name NAME 指定项目名称,默认使用目录名称。
docker-compose build:构建或重建服务
docker-compose ps:查看已经启动的服务状态
docker-compose kill:停止某个服务、杀掉容器
docker-compose logs:可以查看某个服务的log、显示容器的输出内容
docker-compose port:打印绑定的public port(开放端口)
docker-compose pull:拉取服务镜像
docker-compose up:启动yml定义的所有服务
docker-compose stop:停止yml中定义的所有服务
docker-compose start:启动被停止的yml中的所有服务
docker-compose kill:强行停止yml中定义的所有服务
docker-compose rm:删除yml中定义的所有服务
docker-compose restart:重启yml中定义的所有服务
docker-compose scale:设置服务的容器数目
docker-compose run:运行一个一次性命令
总结在写这篇文章之前,我从来没有接触过compose,以前只关注过docker一些基础知识,整个部署过程花了我整整一天的时间,从看文档到查资料再到不断试错,最终又花了半天时间总结写这篇文章。说了这么多,只是想表达如果你想学习一门语言或者技术,那你就必须走近它,必须动手尝试才能有真正的成长和体验,就跟你看到一个漂亮的高冷小姐姐一样,你只有走近她才有接触的机会,只有敢于追求才有成功脱单的机会,道理是一样一样的。最后,原创不易,如果乡亲们觉得本文不错,麻烦帮忙右下角点个在看或者分享给其他有需要的人,这就是给我最大的鼓励和坚持原创的动力了,谢谢!