前言
在上節的內容中,我們已經通過一個簡單的實例,將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
自定義鏡像?請參照:
這里我就不重復寫了,差不多都一樣的。
Dockerfile
還是放置到 src/docker/
下,不管放置到哪兒,只要你YML里面配置了一樣的位置即可。
## 依賴基礎鏡像 maven 3.5 這個鏡像里面已經包含有java
FROM maven:3.5-jdk-8
這是可能會有疑惑?為什么看不到 RUN
CMD
命令了,因為我們在后面將這些命令都指定到 docker-compose.yml
文件里面了。
配置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
簡單說下一下:
version
這個就簡單了,指明 docker-compose
文件的語法信息。當然,這個版本信息也不能忽視,從官網的一張表里面說明你的docker 版本與之對應的yml 文件的版本。需要查詢自己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.yml 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