将jar包部署到docker
0,先打包好项目,再启动docker
1,在Java项目根目录下创建一个名为Dockerfile的文件(没有扩展名),并添加以下内容。
# 使用OpenJDK的基础镜像
FROM openjdk:8-jdk-alpine
# 设置工作目录
WORKDIR /app
# 将项目中的jar包复制到镜像中,并且在镜像中的/app工作目录下重命名为app.jar
COPY target/打好的应用包.jar app.jar
# 暴露应用端口
EXPOSE 8080
# 启动应用
ENTRYPOINT ["java", "-jar", "/app/app.jar"]
2,打开PowerShell,导航到你的项目根目录(包含Dockerfile的目录),然后运行以下命令来构建Docker镜像,注意命令最后的 . ,代表在当前目录下的Dockerfile文件
docker build -t 镜像名称 .
3,构建完镜像后,使用以下命令来运行容器:-d表示在后台运行容器,-p 8080:8080将容器的8080端口映射到主机的8080端口,如果有多个端口要给外面访问的话,直接 -p 8080:8080 -p 2672:2672 就好了。
docker run -d -p 8080:8080 --name 对外显示的容器名称 镜像名称
4,打开浏览器,访问http://localhost:8080看是否正常运行,以下命令可以查看日志
docker logs 对外显示的容器名称
以上部分还不能访问数据库,有几种解决方案,我试过之后再更新上来
1将数据库服务也容器化
2修改Docker容器的网络配置
3使用Docker Compose来管理多容器应用
解决方案一:
在上方第3步的指令中添加一个–net=host设置网络为共享主机模式,这样能访问宿主机的数据库,如下:
docker run -d -p 8080:8080 --name 对外显示的容器名称 --net=host 镜像名称
但意义不大,因为数据库要么在其它服务器,要么在其它容器中。
解决方案二:
为了安全起见,容器创建时默认是桥接模式,不管容器是否设置了共享主机模式,先在PowerShell中从容器ping一下数据库所在ip,看是否能通,或者用telnet看一下是否能连上3306端口。
docker exec -it 项目所在容器名称 ping 数据库所在容器名称或者IP地址
docker exec -it 项目所在容器名称 telnet 数据库所在容器名称或者IP地址 3306
能ping通的话,直接在项目的yml文件中设置数据库配置就好
如果数据库比pom文件配置的高,比如pom文件中配置的数据库是MySQL5,但实际数据库是MySQL8,就需要把allowMultiQueries=true替换成useSSL=false&allowPublicKeyRetrieval=true,否则项目连接不上数据库。
first: #数据源1
url: jdbc:mysql://192.168.0.225:3306/数据库名?useUnicode=true&characterEncoding=UTF-8&useSSL=false&allowPublicKeyRetrieval=true
username: root
password: root
second: #数据源2
url: jdbc:mysql://192.168.0.225:3306/数据库名?allowMultiQueries=true&useUnicode=true&characterEncoding=UTF-8
username: root
password: root
用Navicat连接上数据库,添加数据库所在IP地址的用户,并给与全部权限
停止容器,删除容器,重新执行第2和第3步构建镜像和运行容器即可访问数据库了。
将数据库部署到docker
我还是将mysql数据库也部署到docker上了,执行下方指令即可(我同时也部署了5.7版本的,在Windows上跑不起来,将镜像打包到Linux上可以跑起来)
1,创建挂载目录
mkdir D:\development_sources\docker\mysql\log,D:\development_sources\docker\mysql\data,D:\development_sources\docker\mysql\conf,D:\development_sources\docker\mysql\mysql-files
2,构建镜像和配置容器
docker run -p 3307:3306 --restart=always --name mysqldoc -v D:\development_sources\docker\mysql\log:/var/log/mysql -v D:\development_sources\docker\mysql\data:/var/lib/mysql -v D:\development_sources\docker\mysql\conf:/etc/mysql -v D:\development_sources\docker\mysql\mysql-files:/var/lib/mysql-files -e MYSQL_ROOT_PASSWORD=root -d mysql:8.0.24
指令解释如下
数据库部署指令解释:
-p 3307:3306
MySQL默认使用3306端口,我已经在宿主机上运行了其他MySQL实例占用了3306端口,所以把容器中mysql的3306端口映射到3307上。
--restart=always
设置容器的重启策略为“always”,当Docker守护进程启动时,或者容器异常退出时,Docker会自动重新启动这个容器。
--name mysqldoc
容器名称“mysqldoc”,可以使用docker stop mysqldoc来停止容器。
-v D:\development_sources\docker\mysql\log:/var/log/mysql
创建了一个卷映射,将宿主机的D:\development_sources\docker\mysql\log目录映射到容器内的/var/log/mysql目录。
MySQL容器会将日志文件写入到/var/log/mysql目录中,通过这个映射,可以在宿主机上访问这些日志文件。
-v D:\development_sources\docker\mysql\data:/var/lib/mysql
将宿主机的D:\development_sources\docker\mysql\data目录映射到容器内的/var/lib/mysql目录。
/var/lib/mysql是MySQL存储数据文件的默认目录,通过这个映射,可以将MySQL的数据文件保存在宿主机上,便于数据备份和迁移。
-v D:\development_sources\docker\mysql\conf:/etc/mysql
将宿主机的D:\development_sources\docker\mysql\conf目录映射到容器内的/etc/mysql目录。
可以在这个目录中放置MySQL的配置文件(如my.cnf),然后容器会使用这些配置文件来启动MySQL服务。
-v D:\development_sources\docker\mysql\mysql-files:/var/lib/mysql-files
将宿主机的D:\development_sources\docker\mysql\mysql-files目录映射到容器内的/var/lib/mysql-files目录。
/var/lib/mysql-files是MySQL用于存储导入和导出的文件的目录,通过这个映射,可以方便地在宿主机和容器之间传输文件。
-e MYSQL_ROOT_PASSWORD=root
设置环境变量MYSQL_ROOT_PASSWORD的值为root。
MySQL容器在启动时,会使用这个环境变量来设置root用户的密码。
-d mysql:8.0.24
指定使用mysql镜像的8.0.24版本,并以“detached mode”(后台模式)运行容器。
创建网络
创建名为dev_net的网络,将数据库,redis和应用加入到网络中,应用的yml文件就可以用容器名替换IP地址进行访问了
docker network create dev_net
将mysql连接上配置好的网络dev_net
docker network connect dev_net mysqldoc
这样就可以连接docker上的数据库了:
从其他电脑连接docker上的数据库:
IP地址进行访问:
其它的相关docker指令:
列出所有容器
docker ps
查看容器日志
docker logs mysqldoc
查看镜像网络
docker network ls
查看镜像网络的IP地址
docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' mysqldoc
进入容器指定目录
docker exec -it mysqldoc /bin/bash 或者docker exec -it mysqldoc mysql -uroot -p
登录mysql
mysql -u root -p
设置用户表格显示
use mysql
查看用户
select host,user from user;
创建用户CREATE USER '数据库登录账号'@'单个IP地址或者%' IDENTIFIED BY '数据库密码';
CREATE USER 'root'@'192.168.0.27' IDENTIFIED BY 'root';
保存修改
FLUSH PRIVILEGES;
退出
EXIT;
指令执行情况如下:
因为我镜像安装的是MySQL8.0.24,所以项目的pom文件要同步修改成这个版本,不然数据库连接不上。
将Redis部署到docker
创建挂载点
mkdir D:\development_sources\docker\redis\data
构建镜像和配置容器
docker run -p 6380:6379 --restart=always --name redis -v D:\development_sources\docker\redis\data:/data -d redis redis-server --appendonly yes --requirepass redis
指令解释如下:
-p 6380:6379
将容器内Redis默认的6379端口映射到宿主机的6380端口上,因为宿主机的6379端口占用了,所以用6380端口,这样可以从宿主机或其他容器访问Redis服务。
--restart=always
设置容器的重启策略为“always”,当Docker守护进程启动时,或者容器异常退出时,Docker会自动重新启动这个容器。
--name redis
为容器指定了一个名称“redis”。
通过这个名称,可以方便地引用或管理容器,例如使用docker stop redis来停止容器。
-v D:\development_sources\docker\redis\data:/data
创建一个卷映射,将宿主机的D:\development_sources\docker\redis\data目录映射到容器内的/data目录。
Redis容器会将数据存储在/data目录中,通过这个映射,可以在宿主机上访问和备份这些数据。
-d
指定了容器将以“detached mode”(后台模式)运行,表示容器将在后台运行,这样可以继续在同一个终端会话中执行其他命令。
redis redis-server --appendonly yes --requirepass redis
指定要运行的Docker镜像(redis)和容器启动时要执行的命令(redis-server --appendonly yes --requirepass redis)。
redis-server是Redis服务器的启动命令。
--appendonly yes参数启用了Redis的AOF(Append Only File)持久化机制。这意味着Redis会将每个写命令追加到文件的末尾,以便在服务器重启时能够重新构建数据集。
--requirepass redis参数设置了Redis服务器的密码为redis。用这个密码可以连接到Redis服务器时
将Redis连接上配置好的网络dev_net,方便容器之间使用容器名互相访问
docker network connect dev_net redis
使用Another Redis Desktop Manager连接Redis
将Windows中的docker容器搬到Linux中
先准备一个Linux环境,我的是centos7
[root@MiWiFi-R3G-srv ~]# uname -r
3.10.0-1062.56.1.el7.x86_64
BigCloud Enterprise Linux 7 (GNU/Linux 3.10.0-1062.56.1.el7.x86_64 x86_64)
Windows系统中,在docker打开的情况下,执行如下命令将Windows上docker中的镜像打包
docker save -o 包名.tar 镜像名
docker save -o myimage.tar renren-generator-1.0.0
docker save -o mysqlimage.tar mysql:8.0.24
docker save -o myredisimage.tar redis
下载远程连接工具FinalShell用来连接Linux
安装好后点击SSH连接:
输入Linux系统IP地址和端口和账号密码进行远程连接:
连接上之后的界面如图所示:上方是命令行,下方是Linux文件管理:
安装docker
关闭防火墙(因为有很多端口需要开放出去,为了开发方便,直接关闭防火墙,生成环境禁止操作)
systemctl stop firewalld
禁用防火墙
systemctl disable firewalld
远程连接上后,就使用 root 权限更新 yum 包,(生产环境禁止操作)
yum -y update:升级所有包同时也升级软件和系统内核;
yum -y upgrade:只升级所有包,不升级软件和系统内核
docker的卸载指令:
yum remove docker docker-common docker-selinux docker-engine
docker的安装指令:
//yum-util 提供yum-config-manager功能,另两个是devicemapper驱动依赖
yum install -y yum-utils device-mapper-persistent-data lvm2
//设置一个yum源
yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
//查看可安装版本
yum list docker-ce --showduplicates | sort -r
//我选了18.03.1.ce这个版本
yum -y install docker-ce-18.03.1.ce
//启动docker
systemctl start docker
//设置开机自启
systemctl enable docker
//查看docker版本
docker version
搬镜像
将镜像上传Linux的自定义目录loadimages下,
cd到镜像所在目录后,执行镜像加载指令:
docker load -i myimage.tar
docker load -i mysqlimage.tar
docker load -i myredisimage.tar
查看镜像列表
docker image list
接着启动容器,启动指令和Windows中的指令一致,启动完就可以访问应用了:
docker run -d -p 8080:8080 --name renren --net=host renren-generator-1.0.0:latest
其它一些相关指令:
强制删除镜像(每次更新镜像,都要先停止容器、删除容器、删除镜像、编译镜像、运行容器,应该有更简洁的方法,欢迎留言)
docker image rm -f 镜像名称:版本号
停止容器
docker stop 容器名称
强制删除容器
docker rm -f 容器名称
防火墙命令
为了后面操作方便,我们可以关闭防火墙。但是在实际应用中不推荐,在实际应用中需要开放指定端口。
查看防火墙状态
systemctl status firewalld
启用防火墙
systemctl start firewalld
查看防火墙状态
firewall-cmd --state
开放指定端口
firewall-cmd --zone=public --add-port=8080/tcp --permanent
关闭指定端口
firewall-cmd --zone=public --remove-port=8080/tcp --permanent
重新加载防火墙配置
firewall-cmd --reload
查看开放的端口
firewall-cmd --zone=public --list-ports
启动MySQL
docker run -p 3306:3306 --restart=always --name mysqldoc -e MYSQL_ROOT_PASSWORD=root -d mysql:8.0.24
错误号码2058 Plugin caching sha2 password could not be loaded:
可视化工具远程连接docker 下的MySQL无法加载插件缓存sha2密码,在MySQL 8.0中,caching_sha2_password是默认的身份验证插件,而不是mysql_native_password,但服务器可以正常连接。有两种解决办法,一种就是升级sqlyog,一种是修改mysql默认身份验证插件。明天来补充。
docker exec -it mysqldoc /bin/bash
mysql -h localhost -u root -p
ALTER USER 'root'@'%' IDENTIFIED BY 'root' PASSWORD EXPIRE NEVER;
ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY 'root';
FLUSH PRIVILEGES;
ALTER USER 'root'@'%' IDENTIFIED BY 'root' PASSWORD EXPIRE NEVER;
ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY 'root';
启动docker时报错
[root@MiWiFi-R3G-srv packimages]# Job for docker.service failed because the control process exited with error
我的解决方式:
1、进入docker目录:cd /etc/docker/
2、修改daemon的类型:mv daemon.json daemon.conf
3、重启docker:systemctl restart docker
在centos中构建镜像报错
[root@MiWiFi-R3G-srv packimages]# docker build -t vivrimage .
Sending build context to Docker daemon 51.72MB
Step 1/5 : FROM openjdk:8-jdk-alpine
Get https://registry-1.docker.io/v2/: net/http: request canceled while waiting for connection (Client.Timeout exceeded while awaiting headers)
我的解决方式,添加docker镜像(操作完之后,我之前的容器和镜像全没了,应该是换了个工作目录导致的,建议大家谨慎操作):
[root@MiWiFi-R3G-srv packimages]# vim /etc/docker/daemon.json
{
"data-root": "/data/app/dockerWork",
"insecure-registries": [
"ss.suwell.com"
],
"registry-mirrors": [
"https://docker.registry.cyou",
"https://docker-cf.registry.cyou",
"https://dockercf.jsdelivr.fyi",
"https://docker.jsdelivr.fyi",
"https://dockertest.jsdelivr.fyi",
"https://mirror.aliyuncs.com",
"https://dockerproxy.com",
"https://mirror.baidubce.com",
"https://docker.m.daocloud.io",
"https://docker.nju.edu.cn",
"https://docker.mirrors.sjtug.sjtu.edu.cn",
"https://docker.mirrors.ustc.edu.cn",
"https://mirror.iscas.ac.cn",
"https://docker.rainbond.cc"
]
}
系统登录验证码无法显示
直接在centos中运行jar文件,是可以显示的,只是部署到docker上就无法显示,怀疑是镜像中缺少依赖导致的,换了个镜像就好了,这个镜像需要科学上网才能下载。
FROM openjdk:8
代码有变更,不需要重新构建镜像,只要更新一下宿主机的jar包就好
启动容器时,将Dockerfile文件中设置的工作目录映射到宿主机 -v /home/lijie/Speedda/Project/DialNgTWInspector/app:/app,
每次有代码更新时,将新的jar包上传到宿主机就可以了
docker run -d -p 8005:8005 -v /home/lijie/Speedda/Project/DialNgTWInspector/app:/app -v /home/lijie/Speedda/Project/DialNgTWInspector/logs:/logs -v /home/lijie/Speedda/Project/DialNgTWInspector/media:/home/lijie/Speedda/Project/DialNgTWInspector/media --name vivr vivrimg
redis中安装ping,其它镜像的ping要查找安装指令
//通过dockere exec -it 容器名 bash或者/bin/sh 进入redis后执行指令
apt-get update && apt-get install -y iputils-ping
参考:
https://blog.youkuaiyun.com/heima005/article/details/127053152
https://blog.youkuaiyun.com/qq_41583556/article/details/141690461
https://zhuanlan.zhihu.com/p/705200341