一、准备工作
①:环境准备
Ubuntu系统:我这里是22.04(一台安装好docker环境的Ubuntu)
查看docker版本
二、项目部署
①:准备工作
好了,环境准备好之后,接下来可以尝试部署项目了。
- 项目说明:
invoice:发票系统管理的后端代码
invoice-web:发票系统管理的前端代码
DockerFile:用于构建镜像
部署的容器及端口说明:
DockerFile
# 基础镜像
FROM java:8
# 设定时区
ENV TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
VOLUME /logs
# 拷贝jar包
COPY *.jar /app.jar
# 入口
ENTRYPOINT ["java", "-jar", "/app.jar"]
②:准备MySQL、nginx、redis容器
- 因为项目中分别用到了MySQL、nginx和redis,所以提前准备好这些容器(并准备好数据库中的数据)
- MySQL、nginx、redis容器 将容器放到同一个网络中,之后直接使用容器名字访问即可
01:创建网络 - 创建网络(名为invoice)
sudo docker network create invoice
- 查看所有网络
sudo docker network ls
02:创建nginx容器
1.创建容器
- 指定版本运行,会自动拉取镜像
sudo docker run --name nginx -p 80:80 -d nginx:1.25.3
- 查看运行的镜像
docker ps
- 创建本地文件夹
sudo mkdir -p /usr/local/nginx
- 从容器nginx里复制配置文件到本地
sudo docker cp nginx:/etc/nginx/ /usr/local/nginx
sudo docker cp nginx:/usr/share/nginx/html /usr/local/nginx
- 删除容器
sudo docker rm -f nginx
- 重新启动nginx 并挂载到本地 由于需要让nginx同时代理invoice-web前端资源,因此我们需要暴露两个端口:
- 80:默认nginx首页端口(也可以不代理)
- 8899:对应invoice-web
sudo docker run \
-p 80:80 \
-p 8899:8899 \
--name nginx \
--restart=always \
-v /usr/local/nginx/nginx/nginx.conf:/etc/nginx/nginx.conf \
-v /usr/local/nginx/html:/usr/share/nginx/html \
-v /usr/local/nginx/logs:/var/log/nginx \
-d nginx:1.25.3
2.nginx容器创建之后我们需要将nginx容器加入到invoice网络中
- 查看所有网络
sudo docker network ls
- 将容器加入到网络中
sudo docker network connect invoice nginx
3.查看网络详细信息
docker network inspect invoice
03:创建redis容器
1.创建容器
- 拉取最新镜像
sudo docker pull redis
- 创建redis配置目录
sudo mkdir -p /usr/local/redis/conf
- 进入到该目录
cd /usr/local/redis/conf
- 下载redis的配置文件,并上传到虚拟机中
- 修改默认配置信息
vim /usr/local/redis/redis.conf
# 配置信息 分析
bind 127.0.0.1 # 这行要注释掉,解除本地连接限制
protected-mode no # 默认yes,如果设置为yes,则只允许在本机的回环连接,其他机器无法连接。
daemonize no # 默认no 为不守护进程模式
requirepass 123456 # 设置密码
appendonly yes # 持久化
- 创建并启动redis容器
docker run --name redis \
-p 6379:6379 \
--restart=always \
-v /usr/local/redis/conf/redis.conf:/etc/redis/redis.conf \
-v /usr/local/redis:/data \
-d redis redis-server /etc/redis/redis.conf --appendonly yes
2.redis容器创建之后我们需要将redis容器加入到invoice网络中
- 查看所有网络
sudo docker network ls
- 将容器加入到网络中
sudo docker network connect invoice redis
3.查看网络详细信息
sudo docker network inspect invoice
04:创建MySQL容器
1.创建容器
- 拉取指定版本镜像
sudo docker pull mysql:8.0
- 创建挂载目录
sudo mkdir -p /usr/local/mysql/data
sudo mkdir -p /usr/local/mysql/init
sudo mkdir -p /usr/local/mysql/conf
- 创建并运行mysql容器
sudo docker run -d \
--name mysql \
-p 3306:3306 \
--restart=always \
-e TZ=Asia/Shanghai \
-e MYSQL_ROOT_PASSWORD=123456 \
-v /usr/local/mysql/data:/var/lib/mysql \
-v /usr/local/mysql/conf:/etc/mysql/conf.d \
-v /usr/local/mysql/init:/docker-entrypoint-initdb.d \
mysql:8.0
- 挂载的目录下有很多数据
2.MySQL容器创建之后我们需要将MySQL容器加入到invoice网络中
- 查看所有网络
sudo docker network ls
- 将容器加入到网络中
sudo docker network connect invoice mysql
3.查看网络详细信息
docker network inspect invoice
05:准备数据
1.运行sql文件
③:部署Java项目
01:准备Dokerfile文件
1.可以使用以下两种方式来命名 Dockerfile 文件:
Dockerfile:这是最常见和推荐的方式,使用没有后缀的文件名。
Dockerfile.dockerfile:这种方式在某些情况下可能更具描述性,特别是当你有多个类型的 Dockerfile 文件时。
2.Dokerfile内容
# 基础镜像
FROM openjdk:8-jre-buster
# 设定时区
ENV TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
# 拷贝jar包
COPY invoice-0.1.2-SNAPSHOT.jar /app.jar
# 入口
ENTRYPOINT ["java", "-jar", "/app.jar"]
02:部署后端
1.将Dockerfile和jar包一起上传到虚拟机
2.构建镜像,构建项目镜像,不指定tag,则默认为latest,这里的invoice 为自定义的一个镜像标签而已,未具体指定,则在查看镜像中展示为:latest
docker build -t invoice .
注意:这里可能执行错误:执行docker build 报错文件找不到解决方案
**排查思路:**
1、查看当前dockerfile文件名称是默认名称:
在没有指定参数的情况下必须是dockerfile或者是Dockerfile,不允许有后缀
2、确保您从 Dockerfile 的保存位置运行命令:
必须要在当前dockerfile文件目录下执行docker build 命令,如:
当前路径为/user/local/project/invoice,在该路径下执行命令
**解决方案:**
1、将dockerfile文件名称改成默认名:dockerfile或者Dockerfile
2、如果是要用自定义的dockerfile文件名称,需要使用 -f 选项指定自定义文件名
如:docker build -t nginx:v1 -f nginx_dockerfile .
3、必须要在当前dockerfile文件目录下执行docker build 命令,包括需要用到的文件指定正确目录
2,查看镜像
docker images
3.创建并运行容器,创建并运行一个tomcat容器
docker run -d --name tomcat --restart=always --network invoice -p 8080:8080 tomcat
备注:此命令中创建了一个tomcat容器,指定容器名称为tomcat,该容器在后台运行且会自启动,容器将会连接到创建的invoice 网络中,且将主机端口8080映射到容器端口8080
# 命令分析
-d: #这是一个简写形式,全称为 --detach。它表示在后台运行容器。
--name tomcat: #指定容器的名称为 tomcat。
--restart=always: #设置容器始终自动重启,即使容器异常退出也会自动重新启动。
--network invoice: #将容器连接到名为 invoice 的网络中。这要求在运行此命令之前已经创建了该网络。
-p 8080:8080: #将主机的端口 8080 映射到容器的端口 8080。这使得可以通过主机的 8080 端口访问容器中运行的 Tomcat 服务。
tomcat: #指定要使用的镜像名称为 tomcat。
4.创建并运行容器,并通过–network将其加入hmall网络,这样才能通过容器名访问mysql
docker run -d --name invoice --restart=always --network invoice -p 19009:19009 invoice
备注:该指令创建了一个名为invoice的容器,容器会自启动并且加入到invoice 网络中,指定该容器和主机映射端口号为:19009
4.查看启动日志
docker logs invoice
5.请求api测试 http://192.168.200.128:19009/web/workFile/getAll
- 后端部署成功!
以上内容为单个jar包服务部署,若存在多个jar包进行部署的情况,则 以启动jar包打包镜像,部署容器(单个和多个jar包均可),参考如下:
1.创建并制作Dockerfile文件
创建mytest.dockerfile文件:
# 基础镜像
FROM openjdk:8-jre-buster
# 设定时区
ENV TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
# 拷贝jar包 后面test-app.jar可自行定义
COPY xiaomi-calendar-1.jar /test-app.jar
# 入口
ENTRYPOINT ["java", "-jar", "/test-app.jar"]
将Dockerfile文件及服务jar包放到对应路径下:
2.制作镜像
根据Dockerfile制作镜像命令如下:
docker build -f 【dockerfile文件的路径】 -t 【自定义镜像名】:latest .
本案例中我自定义的镜像名为mytest,制作镜像的具体命令如下:
docker build -f mytest.dockerfile -t mytest:latest .
可以通过docker images命令查看已有镜像:
3部署容器
根据刚刚生成的镜像部署容器:
docker run -d --name 【自定义容器名】 -p 【需要暴露的端口号】 【所基于的镜像名】
本案例中我自定义容器名也为mytest,1个jar包的暴露端口有8800
docker run -d --name mytest -p 8800:8800 mytest
可以通过docker ps 命令查看已有容器:
该容器则可像如上服务一样进行访问了:
注意:这里有个坑,刚接触docker不太清楚,踩过!!!!!
如果项目有更新,新打的jar包丢进路径内替换原有的jar包,使用命令重启容器、关闭容器、启动容器均不能更新新jar包运行。
目前使用的方案如下(使用Idea创建一键部署项目到Docker):
附:简单容器命令
1、启动容器
docker start 容器名/容器ID
2、重启容器
docker restart 容器名/容器ID
3、杀死 kill 容器
docker kill 容器名/容器ID
扩展: docker build 命令选项介绍
1、-t,–tag: 为构建的镜像指定一个标签。标签可以是名称、版本号或者带有仓库信息的完整标识。
docker build -t nginx:v1 .
2、-f, --file: 指定 Dockerfile 的自定义路径和文件名。默认情况下,docker build 假定 Dockerfile 位于当前工作目录中。通过 -f 选项可以指定其他路径或文件名。
docker build -f /path/to/nginx_dockerfile .
3、–build-arg: 设置构建时的参数,可以在 Dockerfile 中使用。
bashCopy code
docker build --build-arg HTTP_PROXY=http://proxy.example.com:80 .
4、–no-cache: 不使用缓存。默认情况下,Docker 将尝试使用缓存的中间镜像层来加速构建过程。使用 --no-cache 将强制重新生成所有层
bashCopy code
docker build --no-cache .
5、–rm: 构建完成后删除中间容器。默认情况下,Docker 会保留构建过程中生成的中间容器,使用 --rm 可以在构建完成后删除这些容器。
bashCopy code
docker build --rm .
6、–network: 设置构建时的网络模式。默认情况下,使用主机的网络模式。例如:
bashCopy code
docker build --network=host .
7、–pull: 在构建之前尝试拉取最新的基础镜像。例如:
bashCopy code
docker build --pull .
8、–target: 指定构建的目标阶段。Dockerfile 可能包含多个阶段,通过 --target 可以选择性地构建其中的一个阶段。例如:
bashCopy code
docker build --target=mytarget .
03:部署前端
1.创建目录用于存放前端代码
mkdir -p /usr/local/nginx/html/invoice-web
2.将打包好的前端代表拷贝到目录/usr/local/nginx/html/invoice-web下
3.配置nginx
vim /usr/local/nginx/nginx/nginx.conf
- 添加以下信息
worker_processes 1;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/json;
sendfile on;
keepalive_timeout 65;
client_max_body_size 1000M; #(设置客户端请求体最大值)
client_body_buffer_size 1000M; #(配置请求体缓存区大小)
fastcgi_intercept_errors on;
server {
listen 8899;
server_name _;
location /api/ {
# 这里配置代理到后端服务的地址
proxy_pass http://invoice:19009/;
}
location / {
# 这里配置前端资源的路径(容器内部路径)
root /usr/share/nginx/html/invoice-web;
index index.html index.htm;
try_files $uri $uri/ /index.html;
}
}
}
4.重启nginx容器(使配置文件生效)
docker restart nginx
5.访问测试 http://192.168.200.128:8899/web