CentOS 8 で Docker を使用して Spring Boot + Vue アプリケーションをデプロイします。使用するコンテナは Spring Boot、MySQL、Redis、Nginx です。Spring Boot イメージの Dockerfile の構築、ブリッジコンテナの相互接続、ディレクトリマッピングなどの内容が含まれています。
基本環境#
- CentOS のファイアウォールでポート転送を有効にする
firewall-cmd --add-masquerade --permanent
- ファイアウォールを再起動する
firewall-cmd --reload
-
ディレクトリを作成する
ルートディレクトリに /data フォルダを作成し、コンテナ内にマウントされるファイルを統一して保存します。
- /data/redis/data:[ディレクトリ] Redis の永続データを保存
-
/data/redis/redis.conf:[ファイル] Redis の設定ファイル
- /data/nginx/html:[ディレクトリ] Nginx の HTML ファイルディレクトリ
-
/data/nginx/log:[ディレクトリ] ログ
- /data/nginx/nginx/nginx.conf:[ファイル] Nginx の設定ファイル
ネットワーク#
- Docker サブネットを作成する
docker network create --subnet 192.168.0.0/16 --gateway 192.168.0.1 docker-net
192.168.0.0/16:サブネット範囲
192.168.0.1:ゲートウェイアドレス
docker-net:サブネット名
- 作成後に確認する
docker network inspect docker-net
[
{
"Name": "docker-net",
"Id": "1fc4884e63c593800fbbf263d10c09a8dadb52307096d57a5b2e80f84574ab90",
"Created": "2023-01-11T19:18:32.691672677+08:00",
"Scope": "local",
"Driver": "bridge",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": {},
"Config": [
{
"Subnet": "192.168.0.0/16",
"Gateway": "192.168.0.1"
}
]
},
"Internal": false,
"Attachable": false,
"Ingress": false,
"ConfigFrom": {
"Network": ""
},
"ConfigOnly": false,
"Containers": {},
"Options": {},
"Labels": {}
}
]
-
ネットワークに参加する
-
Docker の起動パラメータに
--net docker-net
を追加する -
コンテナ起動後、コマンド
docker network connect docker-net <コンテナID/NAME>
を使用する
-
Redis#
- Redis Docker イメージをダウンロードする
docker pull redis
- Redis 設定ファイルを作成する
vi redis.conf
- redis.conf ファイルに書き込む
requirepass <あなたのredisパスワード>
- Redis を起動する
docker run -d -p 6379:6379 --name docker-redis --restart always -v /data/redis:/etc/redis -v /data/redis/data:/data --net docker-net redis redis-server /etc/redis/redis.conf
-d:バックグラウンドで実行
-p:ポートマッピング、ホストの 6379 ポートをコンテナの 6379 ポートにマッピング
--name:コンテナ起動後の名前
--restart always:コンテナを自動的に再起動
-v:ファイルマウント、コンテナ内のディレクトリをホストにマウント、左側がホストのアドレス、右側がコンテナ内のアドレス
--net docker-net:Docker サブネットに参加
- 起動後、
docker ps -a
を使用してコンテナが正常に起動しているか確認する
MySQL#
- イメージを取得する
docker pull mysql:8.0.25
":" は MySQL のバージョンを指定するために使用されます
- MySQL コンテナを起動する
docker run -d -p 3306:3306 --name d-mysql --net docker-net --restart always -e MYSQL_ROOT_PASSWORD=mysqlpwd -e MYSQL_USER=violet -e MYSQL_PASSWORD=Dd112211 mysql:8.0.25
-e MYSQL_ROOT_PASSWORD=mysqlpwd:-e はカスタムパラメータを示し、root ユーザーのパスワード
-e MYSQL_USER=violet:コンテナ起動時にユーザーを作成
-e MYSQL_PASSWORD=Dd112211:そのユーザーのパスワード
その他のパラメータはdocker hub mysqlで確認できます
- ユーザー権限を設定する
コンテナ起動時に作成されたユーザーに権限を付与するか、root ユーザーがリモートログインできるようにします。
コンテナ内に入る
docker exec -it d-mysql /bin/bash
MySQL クライアントに入る
mysql -uroot -p
root がリモートログインできるように設定する
grant all privileges on *.* to 'root'@'%';
権限をリフレッシュする
FLUSH PRIVILEGES;
- MySQL クライアントを終了し、Docker コンテナから退出する
exit
- MySQL データベースデータを Docker MySQL にインポートする
MySQL クライアントで実行する
mysqldump -uroot -p --databases arrogant javawebsql my_blog springcloud vote_sys >/data/mysql/data-backup.sql
mysqldump を使用してデータをダウンロードし、実行可能な SQL ファイルに保存します。
/data/mysql/data-backup.sql:ディレクトリと最後に生成される SQL ファイル名
--databases とディレクトリの間は、ダンプするデータベース名です
SQL ファイルを MySQL コンテナ内にコピーする
docker cp /data/mysql/data-backup.sql d-mysql:/home/
MySQL コンテナに入り、MySQL クライアントに入って、コマンドを実行し、データを書き込む。必ず SQL ファイルのディレクトリに入る必要があります。
source data-backup.sql
Spring Boot イメージの構築#
- application.yml の設定
データベースアドレスを d-mysql に設定します。つまり、MySQL Docker コンテナの名前です。
url: jdbc:mysql://d-mysql:3306/my_blog?useUnicode=true&useSSL=false&characterEncoding=utf8&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true
Redis アドレスを d-redis に設定します。
host: d-redis
- src ディレクトリに Dockerfile というファイルを作成する
FROM openjdk:8
LABEL maintainer=lnbiuc
COPY ./*.jar /app.jar
ENTRYPOINT ["java","-jar","/app.jar"]
- ファイルをアップロードする
Dockerfile と jar パッケージを同じディレクトリに置く
- イメージを構築する
docker build -t api:8.8 .
-t:ここでのタグを示し、ここではイメージのバージョンを指します。api はイメージの名前です。
.:ドットは非常に重要で、現在のディレクトリで構築することを示します。
- 構築が完了したら、イメージを確認する
docker images
- コンテナを起動する
docker run -d -p 8888:8888 -v /data/api:/log --name api --net docker-net --restart always api:8.8.3
ここでは log フォルダをマウントして確認しやすくしています。jar パッケージのルートディレクトリなので、log フォルダも同じ階層のルートディレクトリにあります。
Nginx#
- イメージをプルする
docker pull nginx
- Spring Boot のアクセスアドレスを取得する
docker network inspect docker-net
出力
[
{
"Name": "docker-net",
"Id": "1fc4884e63c593800fbbf263d10c09a8dadb52307096d57a5b2e80f84574ab90",
"Created": "2023-01-11T19:18:32.691672677+08:00",
"Scope": "local",
"Driver": "bridge",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": {},
"Config": [
{
"Subnet": "192.168.0.0/16",
"Gateway": "192.168.0.1"
}
]
},
"Internal": false,
"Attachable": false,
"Ingress": false,
"ConfigFrom": {
"Network": ""
},
"ConfigOnly": false,
"Containers": {
"00729e5b41d6ddcec195722869e57d1baf7bd754793cac7f986d452032b6810d": {
"Name": "d-redis",
"EndpointID": "2ea0446903341146ccc741aac0431ae3f3e0e6acc8972763f024136a3499a0ae",
"MacAddress": "02:42:c0:a8:00:02",
"IPv4Address": "192.168.0.2/16",
"IPv6Address": ""
},
"0682772aaec9f7d6bb435cf0d38e478c5298fa577783a226d086867d71bcf4b3": {
"Name": "d-nginx",
"EndpointID": "97dde4d3e0b8fff81722518b3b62094af5f0c1b1b484ef112c7db3490fb89ee7",
"MacAddress": "02:42:c0:a8:00:03",
"IPv4Address": "192.168.0.3/16",
"IPv6Address": ""
},
"27325e2b869eb28534e5a3e65de5eb8a650fa8488ded994de46cbb271af40a17": {
"Name": "d-gitea",
"EndpointID": "1a9ab8e968041b4df12ebaacecb74a166f23438cbba9b5345878c6fa672d982d",
"MacAddress": "02:42:c0:a8:00:04",
"IPv4Address": "192.168.0.4/16",
"IPv6Address": ""
},
"bf2d1cf717fbc3a39c06068bba9638ad6ce49d407b3a6e28c196803188597038": {
"Name": "api",
"EndpointID": "34a832756b3c9c051d67e096f27448a80165407579de0a25877fe4d4e9f6e5d3",
"MacAddress": "02:42:c0:a8:00:05",
"IPv4Address": "192.168.0.5/16",
"IPv6Address": ""
},
"ebb72c81a769e9e8385cdbf910a5845ae3f53d8cd8e4d3d317046dd726b74947": {
"Name": "d-mysql",
"EndpointID": "c86a7becc085a4f47a35a8488b81bef771e0ae9f6eadd7e41d0db2beae3a8862",
"MacAddress": "02:42:c0:a8:00:06",
"IPv4Address": "192.168.0.6/16",
"IPv6Address": ""
}
},
"Options": {},
"Labels": {}
}
]
ここで name が api の IPv4Address が Nginx がリバースプロキシする必要があるアドレスです。
- SSL 証明書と nginx.conf ファイルを準備し、/data/nginx/nginx ディレクトリに置きます。
私の nginx.conf
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;
include /usr/share/nginx/modules/*.conf;
# include enable-cors.conf
events {
worker_connections 1024;
}
http {
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
include /etc/nginx/mime.types;
default_type application/octet-stream;
include /etc/nginx/conf.d/*.conf;
gzip on;
gzip_static on;
gzip_min_length 1k;
gzip_comp_level 7;
gzip_buffers 4 16k;
gzip_http_version 1.1;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
gzip_vary on;
server {
listen *:80;
listen [::]:80;
server_name beyondhorizon.top;
rewrite ^(.*)$ https://${server_name}$1 permanent;
}
server {
listen *:80;
listen [::]:80;
server_name www.beyondhorizon.top;
rewrite ^(.*)$ https://${server_name}$1 permanent;
}
server {
listen *:443 ssl http2;
listen [::]:443 ssl http2;
server_name beyondhorizon.top www.beyondhorizon.top;
ssl on;
ssl_certificate beyondhorizon.top_bundle.crt;
ssl_certificate_key beyondhorizon.top.key;
ssl_session_timeout 5m;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:ECDHE-RSA-DES-CBC3-SHA:ECDHE-ECDSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:DES-CBC3-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA';
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;
ssl_session_tickets on;
ssl_stapling on;
ssl_stapling_verify on;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
client_max_body_size 10m;
keepalive_timeout 70;
include /etc/nginx/default.d/*.conf;
location / {
root /usr/share/nginx/html;
index index.html;
try_files $uri $uri/ /index.html;
}
location ~ /api/ {
add_header Cache-Control max-age=3600;
proxy_pass http://192.168.0.5:8888;
}
error_page 404 /404.html;
location = /40x.html {
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
}
}
}
- HTML ファイルを /data/nginx/html にアップロードする
- Nginx を起動する
docker run -d -p 80:80 -p 443:443 -v /data/nginx/html:/usr/share/nginx/html -v /data/nginx/nginx:/etc/nginx -v /data/nginx/log:/var/log/nginx --name d-nginx --restart always --net docker-net nginx
- その後、Nginx 設定ファイルを変更した場合は、コマンドでコンテナを再起動すればよいです。
docker restart d-nginx
この時点で、すべてのコンテナが起動しており、ウェブサイトも正常にアクセスできるはずです。