liunx docker 部署spring boot 项目
新建 /opt/docker-build/yshop-admin 目录
新建Dockerfile 和 application-prod.yml 文件,作为线上项目的配置文件和docker构建镜像需要的Dockerfile文件
Dockerfile
#FROM ibm-semeru-runtimes:open-17-jre
#FROM ibm-semeru-runtimes:open-8-jre
FROM openjdk:8-jdkVOLUME /tmp
WORKDIR /opt/appARG JAR_FILE=*.jar
COPY ${JAR_FILE} app.jar
COPY application-prod.yml application-prod.yml#RUN mkdir /opt/arthas
#COPY /opt/arthas/arthas-boot.jar /opt/arthas/arthas-boot.jarENV JAVA_OPTS=""
EXPOSE 8080
#ENTRYPOINT java ${JAVA_OPTS} --add-opens=java.base/java.lang=ALL-UNNAMED -Djava.security.egd=file:/dev/./urandom -jar /opt/app/app.jar
ENTRYPOINT java ${JAVA_OPTS} -Djava.security.egd=file:/dev/./urandom -jar /opt/app/app.jar
application-prod.yml
server.port: 8080
#配置数据源
spring:application:name: yshop-systemdatasource:druid:type: com.alibaba.druid.pool.DruidDataSourcedriverClassName: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://mysql:3306/yshopb2c?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf8&useSSL=false&zeroDateTimeBehavior=convertToNullusername: rootpassword: 123456connection-init-sqls:- SET NAMES utf8mb4- SET sql_mode = 'STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION'# 初始化配置initial-size: 4# 最小连接数min-idle: 4# 最大连接数max-active: 8# 获取连接超时时间max-wait: 5000# 连接有效性检测时间time-between-eviction-runs-millis: 90000# 最大空闲时间#min-evictable-idle-time-millis: 1800000# 配置一个连接在池中最小生存的时间,单位是毫秒min-evictable-idle-time-millis: 300000# 配置一个连接在池中最大生存的时间,单位是毫秒max-evictableIdle-time-millis: 900000test-while-idle: truetest-on-borrow: falsetest-on-return: falsevalidation-query: select 1# 配置监控统计拦截的filtersfilters: statstat-view-servlet:url-pattern: /druid/*reset-enable: falselogin-username: adminlogin-password: 123456web-stat-filter:url-pattern: /*exclusions: "*.js,*.gif,*.jpg,*.bmp,*.png,*.css,*.ico,/druid/*"redis:#数据库索引database: 2host: redisport: 6379password: JZoxuxAKkH24qLCFH9AG#连接超时时间timeout: 3000# 是否限制单用户登录
single:login: false#jwt
jwt:header: Authorization# 令牌前缀token-start-with: Bearersecret: k09BQnaF# 必须使用最少88位的Base64对该令牌进行编码base64-secret: ZmQ0ZGI5NjQ0MDQwY2I4MjMxY2Y3ZmI3MjdhN2ZmMjNhODViOTg1ZGE0NTBjMGM4NDA5NzYxMjdjOWMwYWRmZTBlZjlhNGY3ZTg4Y2U3YTE1ODVkZDU5Y2Y3OGYwZWE1NzUzNWQ2YjFjZDc0NGMxZWU2MmQ3MjY1NzJmNTE0MzI=# 令牌过期时间 此处单位/毫秒 ,默认2小时,可在此网站生成 https://www.convertworld.com/zh-hans/time/milliseconds.htmltoken-validity-in-seconds: 7200000# 在线用户keyonline-key: online-token# 验证码code-key: code-key#是否允许生成代码,生产环境设置为false
generator:enabled: false#如果生产环境要开启swagger,需要配置请求地址
#springfox:
# documentation:
# swagger:
# v2:
# host: # 接口域名或外网ip#是否开启 swagger-ui,生产环境默认不开启
swagger:enabled: truetitle: yshop商城管理后台APIserverUrl: http://127.0.0.1:8000version: 3.0file:path: /app/file/avatar: /app/avatar/# 文件大小 /MmaxSize: 100avatarMaxSize: 5
新建 /opt/docker-build/yshop-app 中的Dockerfile 和 application-prod.yml
Dockerfile
#FROM ibm-semeru-runtimes:open-17-jre
FROM openjdk:8-jdkVOLUME /tmp
WORKDIR /opt/appARG JAR_FILE=*.jar
COPY ${JAR_FILE} app.jar
COPY application-prod.yml application-prod.ymlENV JAVA_OPTS=""
EXPOSE 8080
#ENTRYPOINT java ${JAVA_OPTS} --add-opens=java.base/java.lang=ALL-UNNAMED -Djava.security.egd=file:/dev/./urandom -jar /opt/app/app.jar
ENTRYPOINT java ${JAVA_OPTS} -Djava.security.egd=file:/dev/./urandom -jar /opt/app/app.jar
application-prod.yml
server.port: 8080
server.ssl.enabled: false
server.servlet.context-path: /
spring:datasource:type: com.alibaba.druid.pool.DruidDataSourcedriverClassName: com.mysql.cj.jdbc.Driverdruid:connection-init-sqls:- SET NAMES utf8mb4- SET sql_mode = 'STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION'# 主库数据源master:url: jdbc:mysql://mysql:3306/yshopb2c?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=GMT%2B8username: rootpassword: 123456connection-init-sqls:- SET NAMES utf8mb4- SET sql_mode = 'STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION'# 从库数据源slave:# 从数据源开关/默认关闭enabled: falseurl:username:password:# 初始连接数initialSize: 4# 最小连接池数量minIdle: 4# 最大连接池数量maxActive: 8# 配置获取连接等待超时的时间maxWait: 60000# 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒timeBetweenEvictionRunsMillis: 60000# 配置一个连接在池中最小生存的时间,单位是毫秒minEvictableIdleTimeMillis: 300000# 配置一个连接在池中最大生存的时间,单位是毫秒maxEvictableIdleTimeMillis: 900000# 配置检测连接是否有效validationQuery: SELECT 1 FROM DUALtestWhileIdle: truetestOnBorrow: falsetestOnReturn: falsestatViewServlet:enabled: trueurl-pattern: /monitor/druid/*filter:stat:# 慢SQL记录log-slow-sql: trueslow-sql-millis: 1000merge-sql: truewall:config:multi-statement-allow: trueredis:host: redis # Redis服务器地址database: 2 # Redis数据库索引(默认为0)port: 6379 # Redis服务器连接端口password: JZoxuxAKkH24qLCFH9AG # Redis服务器连接密码(默认为空)jedis:pool:max-active: 8 # 连接池最大连接数(使用负值表示没有限制)max-wait: -1ms # 连接池最大阻塞等待时间(使用负值表示没有限制)max-idle: 8 # 连接池中的最大空闲连接min-idle: 0 # 连接池中的最小空闲连接timeout: 3000 # 连接超时时间(毫秒)cache:# spring cache 缓存类型为redis 也可以是其他的实现type: redis# 是否限制单用户登录
single:login: trueyshop:security:jwt-key: yshopmini#token-expired-in: 72000token-expired-in: 1296000#如果生产环境要开启swagger,需要配置请求地址
#springfox:
# documentation:
# swagger:
# v2:
# host: # 接口域名或外网ip#是否开启 swagger-ui,生产环境默认不开启
swagger:enabled: truetitle: yshop商城移动端APIserverUrl: http://localhost:8009version: 3.0# 文件存储路径
file:path: /app/file/avatar: /app/avatar/# 文件大小 /MmaxSize: 100avatarMaxSize: 5
新建liunx用户 新建用户 dockerapp 编号1001 并加入root组
useradd dockerapp -u 1001 -g root
修改用户密码
passwd dockerapp
# 查看系统中的用户组
cat /etc/group
# 查看系统中的用户
cat /etc/passwd
安装mysql
新建目录 /opt/docker-data/mysql
赋权
chown -R dockerapp:root /opt/docker-data/mysql
启动mysql容器
docker run -it -p 11203:3306 \\--name mysql --network app -hmysql \\--user 1001:root \\-v /opt/docker-data/mysql/data:/bitnami/mysql/data \\-e MYSQL_ROOT_PASSWORD=TnF4mLZfW4B46fejDCt6QVC0XRP6of0H \\-e TZ=Asia/Shanghai \\-d bitnami/mysql:5.7docker logs -f -t --tail 50 mysql
安装redis
新建目录 /opt/docker-data/redis
赋权
chown -R dockerapp:root /opt/docker-data/redis
启动redis容器
docker run --name redis \\-p 6608:6379 --restart=unless-stopped \\--network app -hredis \\--user 1001:root \\-e REDIS_PASSWORD=JZoxuxAKkH24qLCFH9AG \\-v /opt/docker-data/redis/data:/bitnami/redis/data \\-d bitnami/redis:7.0 /opt/bitnami/scripts/redis/run.sh --notify-keyspace-events Exdocker logs -f -t --tail 50 redis
安装nginx
新建目录 /opt/docker-data/nginx
新建 conf,https-cert,log,static 目录,分别是配置文件目录,ssl证书目录,日志目录,静态资源目录
conf下新建 nginx.conf文件,和conf.d文件夹
nginx.conf
#user nobody;
# worker 数和服务器的 cpu 数相等是最为适宜的。
# 设少了会浪费 cpu,设多了会造成 cpu 频繁切换上下文带来的损耗。
worker_processes 2;# work 绑定 cpu(4 work 绑定 4cpu)。
# worker_cpu_affinity 0001 0010 0100 1000
# work 绑定 cpu (4 work 绑定 8cpu 中的 4 个) 。
# worker_cpu_affinity 0000001 00000010 00000100 00001000#error_log logs/error.log;
#error_log logs/error.log notice;
error_log logs/error.log warn;pid logs/nginx.pid;events {# 普通的静态访问最大并发数建议:worker_connections * worker_processes / 2# 作为反向代理来说,最大并发数量建议 worker_connections * worker_processes / 4# 因为作为反向代理服务器,每个并发会建立与客户端的连接和与后端服务的连接,会占用两个连接。worker_connections 1024;
}http {server_tokens off;include 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 logs/access.log main;sendfile on;#tcp_nopush on;#keepalive_timeout 0;keepalive_timeout 65;gzip on;# 关闭etag,比较消耗性能,仅使用Last-Modifiedetag off;# 设置允许压缩的页面最小字节数; 这里表示如果文件小于这个大小,就不用压缩,因为没有意义,本来就很小.gzip_min_length 2k;# 设置压缩比率,最小为1,处理速度快,传输速度慢;9为最大压缩比,处理速度慢,传输速度快; # 这里表示压缩级别,可以是0到9中的任一个,级别越高,压缩就越小,节省了带宽资源,但同时也消耗CPU资源,所以一般折中为6gzip_comp_level 6;# 指定压缩的文件类型gzip_types text/plain application/x-javascript text/css application/xml text/javascript application/x-httpd-php application/javascript application/json;limit_conn_log_level error;limit_conn_status 429;limit_req_status 429;# 设置了名为 ip_conn_pool 的存储区,大小为20兆字节,根据IP地址limit_conn_zone $binary_remote_addr zone=ip_conn_pool:32m;# 设置了名为 per_server_pool 的存储区,大小为20兆字节,根据serverlimit_conn_zone $server_name zone=per_server_pool:32m;limit_req_zone $binary_remote_addr zone=api_limit:256m rate=20r/s;# 其中$binary_remote_addr有时需要根据自己已有的log_format变量配置进行替换#server {# listen 80 default_server;# listen 443 default_server;# server_name _;# ssl_reject_handshake on;# return 444;#}client_max_body_size 50m;include /etc/nginx/conf.d/*.conf;
}
conf.d 下 ttx-admin.conf
server {listen 80;listen 8001;listen 443 ssl http2;ssl_protocols TLSv1.3 TLSv1.2;ssl_certificate /etc/nginx/https-cert/.pem;ssl_certificate_key /etc/nginx/https-cert/.key;server_name .com default_server;# 限制每个客户端IP的最大并发连接数limit_conn ip_conn_pool 60;# 该服务提供的最大总连接数, 超过请求的会被拒绝limit_conn per_server_pool 2000;limit_req zone=api_limit burst=30 delay=15; #也可设置为nodelay;ssl_prefer_server_ciphers on;#ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4:!DH:!DHE;# 挑选更新更快的 Cipher,有助于减少延迟 https://syslink.pl/cipherlist/ssl_ciphers 'EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH';# OCSP Stapling 开启。OCSP是用于在线查询证书吊销情况的服务# 使用OCSP Stapling能将证书有效状态的信息缓存到服务器,提高 TLS 握手速度ssl_stapling on;#ssl_trusted_certificate /etc/nginx/https-cert/example.com/full_chain.cer;#ssl_stapling_verify on;# 为了缓存的更新时间更可加控,你也可以人工负责更新文件内容# 利用 NginX 的 ssl_stapling_file 指令直接将 OCSP 响应存成文件# NginX 从文件获取OCSP响应而无需从服务商拉取,将其随证书下发而不实时查询。# ssl_stapling_file /xxx/xxx/stapling_file.ocsp; # 用于查询 OCSP 服务器的DNS# resolver 223.5.5.5 223.6.6.6 valid=600s;# 查询域名超时时间# resolver_timeout 5s;#这里 ssl_session_cache 设置为使用 16M 内存,以及 4 小时的连接超时关闭时间 ssl_session_timeout# Enable SSL cache to speed up for return visitors# speed up first time. 1m ~= 4000 connectionsssl_session_cache shared:SSL:2m;ssl_session_timeout 2h;# 开启浏览器的 Session Ticket 缓存ssl_session_tickets on;# 控制在发送数据时的 buffer 大小,默认设置是 16k。这个值越小,则延迟越小。而添加的报头之类会使 overhead 会变大,反之则延迟越大,overhead 越小。ssl_buffer_size 16k;# 防止 MIME 类型混淆攻击add_header X-Content-Type-Options nosniff;root html/vue-admin;proxy_set_header X-Real-IP $remote_addr;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;proxy_set_header Host $host;proxy_redirect off;location /admin/ {if ($request_method = OPTIONS) {add_header Access-Control-Allow-Origin $http_origin;add_header "Access-Control-Allow-Headers" "Authorization, Origin, X-Requested-With, Content-Type, Accept";add_header Access-Control-Allow-Methods GET,POST,OPTIONS,HEAD,PUT,DELETE;add_header Access-Control-Allow-Credentials true;return 200;}proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;proxy_set_header Host $host;proxy_set_header X-Real-IP $remote_addr;proxy_pass http://yshop-admin:8080/;#proxy_pass http://www.baidu.com/;}location /api/ {proxy_hide_header Access-Control-Allow-Origin;add_header Access-Control-Allow-Origin *;add_header "Access-Control-Allow-Headers" "Authorization, Origin, X-Requested-With, Content-Type, Accept";add_header Access-Control-Allow-Methods GET,POST,OPTIONS,HEAD,PUT,DELETE;add_header Access-Control-Allow-Credentials false; if ($request_method = OPTIONS) {return 200;}proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;proxy_set_header Host $host;proxy_set_header X-Real-IP $remote_addr;proxy_pass http://yshop-app:8080/;#proxy_pass http://www.baidu.com/;}location / {root html/vue-admin;# VUE History 模式下刷新网页404问题try_files $uri $uri/ /index.html;index index.html;#expires 12h;add_header Cache-Control "no-cache,must-revalidate";error_log off;access_log off;}error_page 429 /429;location = /429 {default_type application/json;return 429 '{"code":429,"message":"当前访问人数过多, 请稍后再试"}';}error_page 502 /server_shutdown;error_page 503 /server_shutdown;location = /server_shutdown {default_type application/json;return 502 '{"code":502,"message":"服务器升级维护中, 请稍后再试"}';}
}
静态文件上传至/opt/docker-data/nginx/static 下,启动nginx容器即可
后台jar包分为yshop-admin-3.3.jar 和 yshop-app-3.3.jar 分别上传至/opt/docker-build/yshop-admin 和 /opt/docker-build/yshop-app
新建 /opt/docker-data/yshop/files/avatar 和 /opt/docker-data/yshop/files/upload 文件夹,用来存储用户上传的图片
并执行
chown -R dockerapp:root /opt/docker-data/yshopchmod -R 777 /opt/docker-data/yshop
启动admin
cd /opt/docker-build/yshop-admin
docker build -t yshop:admin1.0.0 .docker run -d -p 8770:8080 \\--user 1001:root \\--network app -hyshop-admin \\-v /opt/docker-data/yshop/files/upload:/app/file \\-v /opt/docker-data/yshop/files/avatar:/app/avatar \\-v /opt/docker-data/yshop/logs:/opt/app/logs \\-e "SPRING_PROFILES_ACTIVE=prod" \\-e TZ="Asia/Shanghai" \\--name yshop-admin1.0.0 yshop:admin1.0.0 docker logs -f --tail 200 yshop-admin1.0.0
启动api
cd /opt/docker-build/yshop-app
docker build -t yshop:app1.0.0 .docker run -d -p 8771:8080 \\--user 1001:root \\--network app -hyshop-app \\-v /opt/docker-data/yshop/files/upload:/app/file \\-v /opt/docker-data/yshop/files/avatar:/app/avatar \\-v /opt/docker-data/yshop/logs:/opt/app/logs \\-e "SPRING_PROFILES_ACTIVE=prod" \\-e TZ="Asia/Shanghai" \\--name yshop-app1.0.0 yshop:app1.0.0docker logs -f --tail 200 yshop-app1.0.0