前言
在上节的内容中, 我们已经通过一个简单的实例, 将 Docker-compose 进行了实际的应用. 这一小节中. 我们将通过学习和了解, 着重认识容器的编排, 上一节只算是一个小小的测试. 在这一节中. 我们将用最常见的技术.
Springboot 作为后端应用
Nginx 作为反向代理
MySQL 持久化数据
Springboot 后端应用
引入 JPA 支持, 以及 MySQL 的驱动
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-data-jpa</artifactId>
- </dependency>
- <dependency>
- <groupId>MySQL</groupId>
- <artifactId>MySQL-connector-java</artifactId>
- </dependency>
配置 JPA 的基本属性
- spring.jpa.properties.hibernate.hbm2ddl.auto=update
- spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect
- spring.jpa.show-sql=true
定义控制器
通过定义这样一个简单的控制器, 访问 / index 后就往数据库插入一条访问记录.
- @RestController
- @RequestMapping
- public class UserController {
- @Autowired
- private UserRep userRep;
- @GetMapping("/index")
- public String index(HttpServletRequest request) {
- UserEntity userEntity = new UserEntity();
- userEntity.setName("guest");
- userEntity.setCreateTime(new Date());
- userEntity.setIp(request.getRemoteAddr());
- userEntity.setStatus(1);
- userRep.save(userEntity);
- return "hello-docker-nginx";
- }
- }
实例代码:
自定义镜像
是否记得上次我们在使用 Dockerfile 自定义镜像? 请参照:
https://www.cnblogs.com/ChromeT/p/12283482.html#_label1_0
这里我就不重复写了, 差不多都一样的.
Dockerfile 还是放置到 src/docker/ 下, 不管放置到哪儿, 只要你 YAML 里面配置了一样的位置即可.
- ## 依赖基础镜像 maven 3.5 这个镜像里面已经包含有 java
- FROM maven:3.5-jdk-8
这是可能会有疑惑? 为什么看不到 RUN CMD 命令了, 因为我们在后面将这些命令都指定到 docker-compose.YAML 文件里面了.
配置 NGINX
- version: "3.0"
- services:
- nginx:
- container_name: my-nginx
- image: nginx:1.13
- restart: always
- ports:
- - 8080:80
- - 8443:443
- volumes:
- - ./nginx/conf.d:/etc/nginx/conf.d
- https://hub.docker.com/_/nginx?tab=tags
简单说下一下:
version
这个就简单了, 指明 docker-compose 文件的语法信息. 当然, 这个版本信息也不能忽视, 从官网的一张表里面说明你的 docker 版本与之对应的 YAML 文件的版本. 需要查询自己 docker 的版本后填写.
我这里是 1.13.1
- [root@mrclinux ~]# docker -v
- Docker version 1.13.1, build 4ef4b30/1.13.1
- container_name
这个就字面意思了, 容器的名称
image
指定容器的构建镜像
- restart
- restart: "no"
- restart: always
- restart: on-failure
- restart: unless-stopped
No 是默认的重新启动策略, 在任何情况下都不会重新启动容器.
always, 若没有启动成功, 则容器始终重新启动. (常用)
如果退出代码指示出现 on-failure 错误, 则启动失败策略重新启动容器.
ports
将宿主主机上的端口与容器服务端口进行绑定, 比如 8080:80 就是将宿主主机的 8080 端口绑定到这个服务的 80 端口
volumes
挂载主机路径或命名卷, 指定为服务的子选项.
就意思说: 把指定的路径挂载到服务当中. 在这个例子里,
./nginx/conf.d:/etc/nginx/conf.d
就是将本文件夹./nginx/conf.d 映射到 (挂载) 到容器的 / etc/nginx/conf.d
就是把 NGINX 的配置文件夹给映射出来了. 方便我们修改.
配置转发
- server {
- listen 80;
- charset utf-8;
- access_log off;
- location / {
- 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;
- proxy_pass http://App:8080;
- }
- }
这个就简单了. 没啥可说的, proxy_pass http://App:8080; 主要一下, 因为 App 这个服务和 nginx 不在一个服务内, 所以需要通过服务名的方式进行转发.
配置 MySQL
- MySQL:
- container_name: my-MySQL
- image: MySQL:8.0
- environment:
- MYSQL_DATABASE: demo
- MYSQL_ROOT_PASSWORD: root
- MYSQL_ROOT_HOST: '%'
- ports:
- - "3306:3306"
- volumes:
- - /root/database/MySQL:/var/lib/MySQL
- restart: always
- environment
环境变量, 这个主要用于设置一些比如数据库的名称, 以及用户密码等信息.
详见 MySQL 环境变量 https://hub.docker.com/_/mysql?tab=description
MYSQL_ROOT_PASSWORD
这个变量是强制性的, 它指定将为 MySQL root 超级用户帐户设置的密码.
MYSQL_DATABASE
此变量是可选的, 并允许您指定要在映像启动时创建的数据库的名称.
注意点
因为容器停止后, 其里面的数据也会消失, 这是我们所不能接受的, 所以, 将 MySQL 里面用来存储数据库的路径映射出来, 映射到本机上我们所熟知的位置, 这样就好了.
mkdir -p /root/database/MySQL/
创建本地路径
/root/database/MySQL:/var/lib/MySQL
组成映射关系.
配置后台 Springboot
- App:
- container_name: my-App
- build: .
- working_dir: /App
- volumes:
- - ./:/App
- - ~/.m2:/root/.m2
- expose:
- - "8080"
- depends_on:
- - nginx
- - MySQL
- command: mvn clean spring-boot:run -Dspring-boot.run.profiles=docker
- build
指定自定义镜像文件 Dockerfile 的目录, 用于构建镜像
working_dir
指定功能目录
expose
在不将端口发布到主机的情况下公开端口 -- 它们只能被链接的服务访问. 只能指定内部端口.
depends_on
启动顺序, 意思是需要先启动 nginx MySQL 而后启动本应用.
command
容器启动执行命令进行重写, 其实就是将这个 JAR 包运行起来.
注意
~/.m2:/root/.m2 其实就是把宿主主机的 Maven 仓库映射到镜像内.
./:/App 其实就是将当前目录挂载到容器内 /App 下
运行测试
- ## 克隆仓库到服务器
- Git clone https://gitee.com/mrc1999/springboot-nginx-mysql-docker-compose.git
- cd springboot-nginx-MySQL-docker-compose
- ## 运行 docker-compose 进行编排
- docker-compose up
通过运行 UP 命令进行容器的编排与部署, 观察打印的内容是否正确, 若没有错误, 则出现以下部分内容.
- my-App | Downloaded from central: https://repo.maven.apache.org/maven2/org/apache/maven/maven-model/3.3.9/maven-model-3.3.9.jar (164 kB at 155 kB/s)
- my-App |
- my-App | . ____ _ __ _ _
- my-App | /\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
- my-App | ( ( )\___ | '_ |'_| | '_ \/ _` | \ \ \ \
- my-App | \\/ ___)| |_)| | | | | || (_| | ) ) ) )
- my-App | ' |____| .__|_| |_|_| |_\__, | // //
- my-App | =========|_|==============|___/=/_/_/_/
- my-App | :: Spring Boot :: (v2.1.6.RELEASE)
- my-App |
- my-App | 2020-02-10 03:39:14.574 INFO 1 --- [ main] com.example.demo.DemoApplication : Starting DemoApplication on f27ac469d127 with PID 1 (/App/target/classes started by root in /App)
- my-App | 2020-02-10 03:39:14.588 INFO 1 --- [ main] com.example.demo.DemoApplication : The following profiles are active: docker
Springboot 启动正常, 因为这个时候是直接运行容器服务的, 我们可以尝试使用 CTRL+C 进行关闭, 而后通过后台的方式运行
后台运行
- docker-compose up -d
- [root@mrclinux springboot-nginx-MySQL-docker-compose]# docker-compose up -d
- my-nginx is up-to-date
- Starting my-MySQL ... done
- Starting my-App ... done
检查容器运行情况
docker-compose ps 查看当前编排容器的运行情况
- [root@mrclinux springboot-nginx-MySQL-docker-compose]# docker-compose ps
- Name Command State Ports
- -----------------------------------------------------------------------------------------------
- my-App /usr/local/bin/mvn-entrypo ... Up 8080/tcp
- my-MySQL docker-entrypoint.sh mysqld Up 0.0.0.0:3306->3306/tcp, 33060/tcp
- my-nginx nginx -g daemon off; Up 0.0.0.0:8443->443/tcp, 0.0.0.0:8080->80/tcp
- docker ps
通过运行 docker-ps 后发现, 所有的镜像也已经存在.
- [root@mrclinux springboot-nginx-MySQL-docker-compose]# docker ps
- CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
- f27ac469d127 springboot-nginx-MySQL-docker-compose_app "/usr/local/bin/mv..." 6 minutes ago Up 31 seconds 8080/tcp my-App
- 5c0e28096c35 MySQL:8.0 "docker-entrypoint..." 6 minutes ago Up 32 seconds 0.0.0.0:3306->3306/tcp, 33060/tcp my-MySQL
- 2565244279b4 nginx:1.13 "nginx -g'daemon ..." 6 minutes ago Up 30 seconds 0.0.0.0:8080->80/tcp, 0.0.0.0:8443->443/tcp my-nginx
- docker-compose down
停止容器并且移除容器
- [root@mrclinux springboot-nginx-MySQL-docker-compose]# docker-compose down
- Stopping my-App ... done
- Stopping my-MySQL ... done
- Stopping my-nginx ... done
- Removing my-App ... done
- Removing my-MySQL ... done
- Removing my-nginx ... done
- Removing network springboot-nginx-MySQL-docker-compose_default
尝试发现
MySQL 数据库持久化 ?
我们通过使用 volumes 将宿主主机的一个文件夹挂载到 my-MySQL 容器下的 /var/lib/MySQL 目录, 那我们产生的数据呢? 是否正常保存了么?
- [root@mrclinux springboot-nginx-MySQL-docker-compose]# ls /root/database/MySQL/
- auto.cnf binlog.000003 ca.pem demo ib_logfile0 #innodb_temp performance_schema server-cert.pem undo_001
- binlog.000001 binlog.index client-cert.pem ib_buffer_pool ib_logfile1 MySQL private_key.pem server-key.pem undo_002
- binlog.000002 ca-key.pem client-key.pem ibdata1 ibtmp1 MySQL.ibd public_key.pem sys
通过发现后得知, 宿主主机的目录下已经产生了 demo 的一个数据库. 我们的挂载没有问题, 下次还是从这里面读取即可. 所以持久化数据没有问题.
working_dir 有啥用?
在容器运行的时候, 我们尝试使用 docker exec -it my-App bash 使用命令行连接容器后, 我们会发现
- [root@mrclinux springboot-nginx-MySQL-docker-compose]# docker exec -it my-App bash
- root@f27ac469d127:/App#
- root@f27ac469d127:/App#
- root@f27ac469d127:/App# ls
- Dockerfile docker-compose.YAML maven mvnw mvnw.cmd nginx pom.xml src target
原来通过 working_dir 其实就是将当前目录的所有文件挂载到容器 /App 下. 里面存在的文件, 均是我通过映射拿进去的文件.
参考以及小结
通过这一节学习, 基本上容器部署这些主流的 MySQL 以及 NGINX 等已经全部没有任何问题了. 学习到了卷的挂载. 以及 MySQL 持久化数据的方式
要是遇到一些新的命令或者语法, 再来记录吧~
参考
DOCKER 官网 https://docs.docker.com/compose/compose-file/
DOCKER 官网 https://docs.docker.com/storage/volumes/
DOCKER 官网 https://docs.docker.com/compose/gettingstarted/
纯洁的微笑 https://www.cnblogs.com/ityouknow/p/8661644.html
码云示例
https://gitee.com/mrc1999/springboot-nginx-mysql-docker-compose
来源: https://www.cnblogs.com/ChromeT/p/12289177.html