实际工作中,可能但是使用docker部署项目的没有那么多。使用docker的大多搭配k8s,或者公有云的容器服务等。但是不可否认的是,docker还是基石。特别是小公司,或者自己做demo项目时,还是使用docker搭建环境更为方便,不过需要注意做好备份。
docker安装MySQL
创建网络
用于容器间通信,一般数据库等中间件不会暴漏出去,我们只需要使用docker的网络进行荣期间通信即可。
docker network create lingtai-net
宿主机创建目录
用于将容器内文件挂载出来,主要挂在数据,配置,日志。
mkdir -p /home/mysql/data
mkdir -p /home/mysql/conf
mkdir -p /home/mysql/logs
创建容器
指定网络,密码,挂载,端口,以及镜像,数据库的密码与默认库可以搭建完成后设置与创建。
docker run --name lingtai-mysql \
--network lingtai-net \
-e MYSQL_ROOT_PASSWORD=LingTai_06csxz96 \
-e MYSQL_DATABASE=lingtai \
-v /home/mysql/data:/var/lib/mysql \
-v /home/mysql/conf:/etc/mysql/conf.d \
-v /home/mysql/logs:/var/log/mysql \
-p 3306:3306 \
-d mysql:8.0.39
- --name mysql-container:容器名称。
- -e MYSQL_ROOT_PASSWORD=root_password:设置 MySQL 根用户密码。
- -e MYSQL_DATABASE=my_database:初始化一个数据库(可选)。
- -v /path/to/mysql/data:/var/lib/mysql:数据目录映射。
- -v /path/to/mysql/conf:/etc/mysql/conf.d:配置文件目录映射。
- -v /path/to/mysql/logs:/var/log/mysql:日志目录映射。
docker安装redis
网络
使用mysql所在网络
宿主机创建目录
mkdir -p /home/redis/data
mkdir -p /home/redis/logs
mkdir -p /home/redis/conf
mkdir -p /home/redis/pid
redis配置文件
仅供参考,这是拷贝实际项目的配置。后续实际使用过程可以进行优化。
bind 0.0.0.0
protected-mode no
port 6379
tcp-backlog 511
timeout 0
tcp-keepalive 300
daemonize no
supervised no
pidfile /var/run/redis_6379.pid
loglevel notice
logfile "/var/log/redis/redis.log"
databases 16
always-show-logo yes
save 900 1
save 300 10
save 60 10000
stop-writes-on-bgsave-error yes
rdbcompression yes
rdbchecksum yes
dbfilename dump.rdb
dir /data
replica-serve-stale-data yes
replica-read-only yes
repl-diskless-sync no
repl-diskless-sync-delay 5
repl-disable-tcp-nodelay no
replica-priority 100
requirepass LingTai_feew2uis
lazyfree-lazy-eviction no
lazyfree-lazy-expire no
lazyfree-lazy-server-del no
replica-lazy-flush no
appendonly no
appendfilename "appendonly.aof"
appendfsync everysec
no-appendfsync-on-rewrite no
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
aof-load-truncated yes
aof-use-rdb-preamble yes
lua-time-limit 5000
slowlog-log-slower-than 10000
slowlog-max-len 128
latency-monitor-threshold 0
notify-keyspace-events "Ex"
hash-max-ziplist-entries 512
hash-max-ziplist-value 64
list-max-ziplist-size -2
list-compress-depth 0
set-max-intset-entries 512
zset-max-ziplist-entries 128
zset-max-ziplist-value 64
hll-sparse-max-bytes 3000
stream-node-max-bytes 4096
stream-node-max-entries 100
activerehashing yes
client-output-buffer-limit normal 0 0 0
client-output-buffer-limit replica 256mb 64mb 60
client-output-buffer-limit pubsub 32mb 8mb 60
hz 10
dynamic-hz yes
aof-rewrite-incremental-fsync yes
rdb-save-incremental-fsync yes
创建容器
docker run \
--name lingtai-redis \
--network lingtai-net \
-p 6379:6379 \
-d redis:5.0.14 redis-server /usr/local/etc/redis/redis.conf \
--requirepass LingTai_feew2uis
复制出配置文件
docker run \
--name lingtai-redis \
--network lingtai-net \
-p 6379:6379 \
-v /home/redis/data:/data \
-v /home/redis/logs:/var/log/redis \
-v /home/redis/conf/redis.conf:/usr/local/etc/redis/redis.conf \
-v /home/redis/pid:/var/run \
redis:5.0.14 redis-server /usr/local/etc/redis/redis.conf \
--requirepass LingTai_feew2uis
问题
- 日志文件映射,一直报错
Can’t open the log file: Permission denied
- 网上找资料,一般都是说需要给映射在的宿主机文件设置权限:试了,文件夹或文件,都不行
- 不设置log:会影响以后问题排查
- 不设置日志文件,则一直在启动中
- 按照网上说的,取消设置为守护进程 可以访问了
docker安装minio
MinIO 是一个高性能的分布式对象存储系统,兼容 Amazon S3 API,广泛用于存储大量非结构化数据,如图片、视频、日志和备份等。它支持高可用、跨区域的数据复制和灾难恢复,能够在私有云或公有云环境中进行灵活部署。MinIO 提供极低的延迟和高吞吐量,适合需要快速数据访问和大规模存储的应用场景。
网络
使用MySQL所在网络
宿主机创建目录
mkdir -p /home/minio/data
mkdir -p /home/minio/logs
mkdir -p /home/minio/conf
创建容器
docker run \
--name lingtai-minio \
--network=lingtai-net \
-p 9000:9000 \
-p 9001:9001 \
-d \
--restart=always \
-v /home/minio/data:/data \
-v /home/minio/conf:/root/.minio \
-v /home/minio/logs:/var/log/minio \
-e "MINIO_ACCESS_KEY=lingtai_minio" \
-e "MINIO_SECRET_KEY=LingTai_5j7gy5iw" \
minio/minio server /data \
--console-address ":9001" \
--address ":9000"
bucket
当前创建一个:lingtai-test , 用于产品的测试环境
docker安装nacos
下载nacos:
https://github.com/alibaba/nacos/releases
创建目录
mkdir -p home/nacos/{data,logs,conf}
创建语句
docker run -d --name lingtai-nacos\
--network lingtai-net \
-e MODE=standalone \
-e SPRING_DATASOURCE_PLATFORM=mysql \
-e MYSQL_SERVICE_HOST=lingtai-mysql \
-e MYSQL_SERVICE_PORT=3306 \
-e MYSQL_DATABASE=nacos-config \
-e MYSQL_USER=root \
-e MYSQL_PASSWORD=LingTai_06csxz96 \
-v /home/nacos/conf:/home/nacos/conf \
-v /home/nacos/logs:/home/nacos/logs \
-v /home/nacos/data:/home/nacos/data \
-p 8848:8848 \
-p 9848:9848 \
nacos/nacos-server:v2.3.2
参数说明
- docker run: 运行一个新的容器。
- -d: 以分离模式运行容器(在后台运行)。
- --name lingtai-nacos: 为容器指定一个名称。
- --network lingtai-net: 将容器连接到指定的 Docker 网络。
- -e: 设置环境变量。
- MODE=standalone: 启动 Nacos 在独立模式下运行。
- SPRING_DATASOURCE_PLATFORM=mysql: 指定使用 MySQL 作为数据源。
- MYSQL_SERVICE_HOST=lingtai-mysql: MySQL 服务的主机名。
- MYSQL_SERVICE_PORT=3306: MySQL 服务的端口。
- MYSQL_DATABASE=nacos-config: Nacos 使用的数据库名称。
- MYSQL_USER=root: MySQL 的用户名。
- MYSQL_PASSWORD=LingTai_06csxz96: MySQL 用户的密码。
- -v: 挂载卷(将主机目录挂载到容器中)。
- /home/nacos/conf: 用于配置文件的本地路径。
- /home/nacos/logs: 用于日志文件的本地路径。
- /home/nacos/data: 用于持久数据存储的本地路径。
- -p: 映射端口。
- 8848:8848: 将容器的 8848 端口映射到主机的 8848 端口(Nacos 默认管理端口)。
- 9848:9848: 将容器的 9848 端口映射到主机的 9848 端口(Nacos 集群端口)。
- nacos/nacos-server:v2.3.2: 使用的 Docker 镜像及其标签。
docker安装nginx
网络
使用MySQL所在网络
宿主机创建目录
mkdir -p /home/nginx/website
mkdir -p /home/nginx/logs
mkdir -p /home/nginx/conf
无挂载创建容器
docker run \
--name lingtai-nginx \
--network=lingtai-net \
-p 80:80 \
-p 443:443 \
nginx:1.23.1
备份容器配置数据
包含主配置表,以及子配置列表,实际操作可以先备份到其他地方,再拷贝过来
docker cp useed-nginx:/etc/nginx /home/nginx/conf
更新配置
参考实际项目的配置
- nginx.conf
# For more information on configuration, see:
# * Official English Documentation: http://nginx.org/en/docs/
# * Official Russian Documentation: http://nginx.org/ru/docs/
user root;
worker_processes 8;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
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;
#keepalive_timeout 0;
keepalive_timeout 65;
gzip on;
fastcgi_intercept_errors on;
proxy_intercept_errors on;
# Load config files from the /etc/nginx/conf.d directory
# The default server is in conf.d/default.conf
include /etc/nginx/conf.d/*.conf;
# levels指定该缓存空间有两层hash目录,第一层目录是1个字母,第二层为2个字母;
# keys_zone为这个空间起个名字,50m指空间大小为50MB;
# inactive的5m指缓存默认时长5分钟;
# max_size的2m是指单个文件超过2m的就不缓存;
# clean_time指定一分钟清理一次缓存。
proxy_cache_path /var/ng_cache levels=1:2 keys_zone=cache_one:50m inactive=20m max_size=30g;
client_max_body_size 8M;
}
- conf.d下的配置:usdemo.conf
注意: 所有的20021端口host为useed-sale, 20020端口对应的host为useed-prod
host取决于对应的容器启动参数
server {
listen 30456;
server_name localhost;
root /opt/data/project;
error_page 404 /404.html;
location = /404.html {
root /etc/nginx/page;
}
### test
location /lingtai{
add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS';
add_header Access-Control-Allow-Headers 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization';
alias /opt/data/project/useed/front/dist;
}
location ^~ /lingtai/api{
proxy_pass http://useed-sale:20021/lingtai;
#proxy_set_header Host $http_host;
proxy_connect_timeout 15s;
proxy_send_timeout 15s;
proxy_read_timeout 15s;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
client_max_body_size 20m;
}
location ^~ /lingtai/prod-api{
proxy_pass http://useed-prod:20020/lingtai;
#proxy_set_header Host $http_host;
proxy_connect_timeout 15s;
proxy_send_timeout 15s;
proxy_read_timeout 15s;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
client_max_body_size 20m;
}
location ^~ /yuanliang/sale-api{
proxy_pass http://useed-sale:20021/lingtai;
#proxy_set_header Host $http_host;
proxy_connect_timeout 15s;
proxy_send_timeout 15s;
proxy_read_timeout 15s;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
client_max_body_size 20m;
}
location ^~ /lingtai/ureport/{
proxy_pass http://useed-sale:20021/yuanliang/ureport/;
#proxy_set_header Host $http_host;
proxy_connect_timeout 15s;
proxy_send_timeout 15s;
proxy_read_timeout 15s;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
client_max_body_size 20m;
}
location = /lingtai/ureport/designer/{
allow 60.173.195.243;
deny all;
proxy_pass http://useed-sale:20021/yuanliang/ureport/designer/;
#proxy_set_header Host $http_host;
proxy_connect_timeout 30s;
proxy_send_timeout 30s;
proxy_read_timeout 30s;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
client_max_body_size 20m;
}
}
重新创建容器
docker run \
--name useed-nginx \
--network=useed-net \
-p 30456:30456 \
-p 443:443 \
-d \
-v /home/nginx/website:/opt/data/project/useed/front/dist \
-v /home/nginx/logs:/var/log/nginx \
-v /home/nginx/conf:/etc/nginx/ \
nginx:1.23.1
主服务docker部署
创建Dockerfile
注:文件名不能修改
启动 Java 应用程序这行,$@
是一个特殊变量,表示所有传递给脚本或命令的参数。在 Dockerfile 的 ENTRYPOINT
指令中,$@
将被替换为 CMD
指令提供的所有参数。因此,$@
可以用来将传递给容器的额外参数(如 --server.port=10111
)传递给 Java 应用程序
# 使用 OpenJDK 1.8 基础镜像
FROM openjdk:8-jdk
# 设置工作目录
WORKDIR /app
# 定义构建参数
ARG JAR_FILE="useed.jar"
# 将本地的 JAR 文件复制到 Docker 容器中
COPY $JAR_FILE /app/useed.jar
# 设置 JVM 参数
ENV JAVA_OPTS="-server -Xms1024m -Xmx2048m"
# 运行日志文件名
ENV LOG_FILE="useed.log"
# 暴漏的端口
ENV EXPOSE_PORT=10010
# 启动环境
ENV USEED_ENV="demo"
# 启动 Java 应用程序
ENTRYPOINT ["sh", "-c", "java $JAVA_OPTS -jar /app/useed.jar --server.port=$EXPOSE_PORT --spring.profiles.active=$USEED_ENV > /app/log/$LOG_FILE 2>&1"]
构建docker镜像
注:useed_prod.jar为目标jar包名,可以同目录下安装构建不同项目的镜像
docker build --build-arg JAR_FILE="useed_prod.jar" -t useed-prod:6.0.0 .
docker build --build-arg JAR_FILE="useed_sale.jar" -t useed-sale:6.0.0 .
网络
使用MySQL所在网络
配置
将对应环境的配置文件的MySQL,minio,redis host设置为容器名,对应用户名密码设置为对应的
datasource:
url: jdbc:mysql://useed-mysql:3306/useed?useSSL=false&useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&transformedBitIsBoolean=true&serverTimezone=GMT%2B8&nullCatalogMeansCurrent=true&allowPublicKeyRetrieval=true
username: root
password: Uic_06csxz96
#oss默认配置
oss:
enabled: false
name: minio
tenant-mode: false
endpoint: http://useed-minio:9000
access-key: useed_minio
secret-key: Uic_5j7gy5iw
bucket-name: useed-test
#测试
spring:
redis:
host: useed-redis
port: 6379
password: Uic_feew2uis
database: 10
ssl: false
宿主机创建目录
mkdir -p /home/useed/demo/jarAndLog_prod
mkdir -p /home/useed/demo/jarAndLog_sale
启动容器
因为要适配不同的jar包,所以启动端口可以指定,如果仅仅为一个服务构建,可以将启动端口写死
同时可以通过-e指定环境变量,如果不指定则按照Dockerfile默认值执行
docker run \
--name useed-prod \
--network=useed-net \
-p 20020:20020 \
-e EXPOSE_PORT=20020 \
-e USEED_ENV="demo" \
-d \
-v /home/useed/demo/jarAndLog_prod \
useed-prod:6.0.0
docker run \
--name useed-sale \
--network=useed-net \
-p 20021:20021 \
-e EXPOSE_PORT=20021 \
-e USEED_ENV="demo" \
-v /home/useed/demo/jarAndLog_sale \
-d \
useed-sale:6.0.0
指定环境变量启动(正常不需要,适用于jdk优化时进行调试,或者指定文件名)
docker run \
--name useed-prod \
--network=useed-net \
-p 20020:20020 \
-e JAVA_OPTS="-server -Xms1024m -Xmx2048m" \
-e LOG_FILE="useed.log" \
-e EXPOSE_PORT=20020 \
-e USEED_ENV="demo" \
-d \
-v /home/useed/demo/jarAndLog_prod \
useed-prod:6.0.0
docker run \
--name useed-sale \
--network=useed-net \
-e JAVA_OPTS="-server -Xms1024m -Xmx2048m" \
-e LOG_FILE="useed.log" \
-p 20021:20021 \
-e EXPOSE_PORT=20021 \
-e USEED_ENV="demo" \
-v /home/useed/demo/jarAndLog_sale \
-d \
useed-sale:6.0.0
以上 就是通过docker搭建的一套服务,包含常见中间件。当然如果使用k8s,直接创建对应POD可以的。写这篇文章主要是熟悉docker命令,理念,同时体验容器的魅力。后面还会继续研究云服务相关用法。