1. 程式人生 > >DOCKER 學習筆記5 Springboot+nginx+mysql 容器編排

DOCKER 學習筆記5 Springboot+nginx+mysql 容器編排

前言

在上節的內容中,我們已經通過一個簡單的例項,將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/ 下,不管放置到哪兒,只要你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

https://hub.docker.com/_/nginx?tab=tags

簡單說下一下:

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-comp