【分享】记一次项目迁移(docker java | docker python)

简介: 该项目是一个前端Vue3和后端Python+Java的应用,原本部署在CentOS7服务器上通过宝塔面板管理。由于服务器即将到期,计划迁移到另一台使用OpenCloudOS和1Plane的服务器。在尝试构建Docker镜像时,首先为Java应用创建Dockerfile,成功构建并运行。对于Python应用,也创建了Dockerfile,并处理了依赖包的安装。在迁移过程中遇到Java项目加载验证码失败的问题,原因是缺少字体配置。通过在宿主机安装fontconfig并将相关字体文件复制到镜像中解决了问题。最后,前端Vue应用作为静态文件运行,如果使用反代理,需要进行相应配置。

项目:前端Vue3,后端Python+Java,数据库Redis+MySQL

原先部署在centos7里面的,使用的宝塔面板部署的,还算方便。

但是服务器要到期了,要将项目迁移到另外一台服务器。

另外一台服务器是opencloudos+1plane

本来想构建一个jdk1.8+python3.12+Nodejs环境的镜像

奈何本人没学过docker,操作起来有点困难。

于是决定

先创建一个基于centos的容器

然后在容器里面部署宝塔。

成功了倒是成功了,java项目与也跑起来了,可是……

python项目的包使用有问题,需要使用终端,也就是去连接ssh

但是docker里又没有权限使用ssh

于是我决定,一个一个的来部署

java项目一个容器

python项目一个容器

docker java

先编译成jar包,在本地测试运行,能正常运行

本地是windows,运行代码是

@echo off
echo.
echo [信息] 使用Jar命令运行Web工程。
echo.
cd %~dp0
cd ../ruoyi-admin/target
set JAVA_OPTS=-Xms256m -Xmx1024m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=512m
java -jar %JAVA_OPTS% ruoyi-admin.jar
cd bin
pause

上传jar包到服务器,然后

根据上面的运行代码,编写Dockerfile文件

# 选择一个合适的基础镜像,这里使用OpenJDK 8的Alpine版本作为基础镜像来减小镜像大小  
FROM openjdk:8-jdk-alpine  
  
# 设置工作目录为/app  
WORKDIR /app  
  
# 将当前目录下的ruoyi-admin.jar复制到容器的/app目录下  
COPY ./ruoyi-admin.jar /app/ruoyi-admin.jar  
  
# 设置JVM参数  
ENV JAVA_OPTS="-Xms256m -Xmx1024m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=512m"  
  
# 定义容器启动时执行的命令  
ENTRYPOINT exec java $JAVA_OPTS -jar ruoyi-admin.jar  
  
# 对外暴露的端口,如果您的应用使用了特定端口,请确保此处声明(例如:EXPOSE 8080)  
# EXPOSE 端口号

然后创建镜像

docker build -t miao_sign_manage_server:v1 .

不要忘了后面有个点

然后 1plane上看到有镜像了,再根据这个镜像去创建容器

java这边就完成了。接下里就是python了,这玩意就有点麻烦,主要是包麻烦

python docker

导出依赖包

pip install pipreqs 
pipreqs ./

先上传项目,然后vim Dockerfile

# 使用官方提供的Python运行时作为父镜像
FROM python:3.12
# 设置在容器内的工作目录为/app
WORKDIR /app
# 将当前目录内容复制到容器的/app中
ADD . /app
# 设置pip使用阿里云镜像  
RUN pip config set global.index-url https://mirrors.aliyun.com/pypi/simple/ \  
    && pip config set install.trusted-host mirrors.aliyun.com  
# 安装任何需要的包
RUN pip install --no-cache-dir -r requirements.txt
# 对外暴露的端口号(如果您的Flask应用程序运行在不同的端口上,请相应更改)
EXPOSE 5000
# 设置环境变量
ENV NAME miao_run_server
# 容器启动时运行python app.py
CMD ["python", "app.py"]

换源这事很重要,不然容易超时错误

基本上能把包顺利装全,就没啥问题了

docker java 的一个巨坑

高高兴兴运行项目,开局就系统错误,加载不了验证码,原因是:

从你提供的日志中,可以看出你在请求 '/captchaImage' 地址时遇到了一个 NullPointerException 异常。这个异常通常表示你试图访问或操作一个为 null 的对象。从堆栈跟踪中,这个异常发生在 sun.awt.FontConfiguration.getVersion(FontConfiguration.java:1264),这似乎是Java的AWT库在尝试加载或读取字体配置时遇到的问题。

这个问题可能是由于以下几个原因造成的:

字体配置文件缺失或损坏:Java可能无法找到或正确读取系统的字体配置文件,这可能是由于文件缺失、损坏或权限问题导致的。你可以尝试检查系统的字体配置,或者重新安装Java以修复可能的文件损坏。

环境问题:如果你在一个无头(headless)环境中运行你的应用(例如,一个没有图形用户界面的服务器),那么Java可能无法正确初始化它的图形子系统。你可以尝试通过设置 java.awt.headless=true 系统属性来运行你的应用,以告诉Java你正在一个无头环境中运行。你可以在启动Java应用时添加 -Djava.awt.headless=true 到命令行参数中来实现这一点。

代码问题:虽然从堆栈跟踪中看不出具体的代码问题,但是如果你的代码在请求 '/captchaImage' 时尝试做了与字体或图形相关的操作,那么你可能需要检查这些代码以确保它们在没有图形环境的情况下也能正确运行。特别是,你应该避免在没有检查是否为 null 的情况下调用对象的方法或访问其属性。

请注意,由于堆栈跟踪并没有显示你的代码,所以我只能根据提供的信息做出一些猜测。如果以上的建议不能解决你的问题,或者你需要更具体的帮助,那么你可能需要提供更多的信息,例如你的代码片段或更详细的错误日志。

看AI回答,大概意思就是因为我的是无图形界面的,所有加载某些东西的时候出了问题

于是我修改了一下Dockerfile

# 选择一个合适的基础镜像,这里使用OpenJDK 8的Alpine版本作为基础镜像来减小镜像大小  
FROM openjdk:8-jdk-alpine  
# 设置容器时间与宿主时间一致
ENV TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
# 设置工作目录为/app
WORKDIR /app
# 安装fontconfig插件
RUN apk update && apk add fontconfig
RUN fc-cache --force
# 将当前目录下的ruoyi-admin.jar复制到容器的/app目录下
COPY ./ruoyi-admin.jar /app/ruoyi-admin.jar
# 设置JVM参数,并添加-Djava.awt.headless=true
ENV JAVA_OPTS="-Djava.awt.headless=true -Xms256m -Xmx1024m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=512m"
# 为了提高随机数生成速度,可以通过以下方式设置(可选)
# ENV JAVA_OPTS="$JAVA_OPTS -Djava.security.egd=file:/dev/./urandom"
# 定义容器启动时执行的命令
ENTRYPOINT exec java $JAVA_OPTS -jar ruoyi-admin.jar
# 对外暴露的端口,确保与应用实际使用的端口一致(例如:EXPOSE 8080)
# EXPOSE 端口号

可是并没有解决问题

我只能尝试在镜像做好后再去安装

docker ps
docker exec -it 939234e551c9 /bin/sh
apk update && apk add fontconfig 
apk add --update font-adobe-100dpi ttf-dejavu fontconfig

等等……这玩意下载那么久,要是每次都这么折腾我得死。

于是

宿主机 yum install fontconfig

再次修改Dockerfile

# 选择一个合适的基础镜像,这里使用OpenJDK 8的Alpine版本作为基础镜像来减小镜像大小  
FROM openjdk:8-jdk-alpine  
# 设置容器时间与宿主时间一致
ENV TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
# 设置工作目录为/app
WORKDIR /app
# 安装fontconfig插件
#RUN apk update && apk add fontconfig
#RUN fc-cache --force
RUN apk add --update font-adobe-100dpi ttf-dejavu fontconfig
# 将当前目录下的ruoyi-admin.jar复制到容器的/app目录下
COPY ./ruoyi-admin.jar /app/ruoyi-admin.jar
# 设置JVM参数,并添加-Djava.awt.headless=true
ENV JAVA_OPTS="-Djava.awt.headless=true -Xms256m -Xmx1024m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=512m"
# 为了提高随机数生成速度,可以通过以下方式设置(可选)
# ENV JAVA_OPTS="$JAVA_OPTS -Djava.security.egd=file:/dev/./urandom"
# 定义容器启动时执行的命令
ENTRYPOINT exec java $JAVA_OPTS -jar ruoyi-admin.jar
# 对外暴露的端口,确保与应用实际使用的端口一致(例如:EXPOSE 8080)
# EXPOSE 端口号

问题解决

# 选择一个合适的基础镜像,这里使用OpenJDK 8的Alpine版本作为基础镜像来减小镜像大小  
FROM openjdk:8-jdk-alpine  
# 设置容器时间与宿主时间一致
ENV TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
# 设置工作目录为/app
WORKDIR /app
# 安装fontconfig插件
#RUN apk update && apk add fontconfig
#RUN fc-cache --force
RUN apk add --update font-adobe-100dpi ttf-dejavu fontconfig
# 将当前目录下的ruoyi-admin.jar复制到容器的/app目录下
COPY ./ruoyi-admin.jar /app/ruoyi-admin.jar
# 设置JVM参数,并添加-Djava.awt.headless=true
ENV JAVA_OPTS="-Djava.awt.headless=true -Xms256m -Xmx1024m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=512m"
# 为了提高随机数生成速度,可以通过以下方式设置(可选)
# ENV JAVA_OPTS="$JAVA_OPTS -Djava.security.egd=file:/dev/./urandom"
# 定义容器启动时执行的命令
ENTRYPOINT exec java $JAVA_OPTS -jar ruoyi-admin.jar
# 对外暴露的端口,确保与应用实际使用的端口一致(例如:EXPOSE 8080)
# EXPOSE 端口号

至于前端的话,vue编译后,直接以静态文件的方式运行即可。

如果用了反代理,记得配置反代理

对了,如果你的项目涉及文件读写,本地保存数据的话,因为是在docker里面的,所有要考虑一下数据持久化的事情。

相关文章
|
10天前
|
jenkins 持续交付 Docker
docker之自定义制作镜像(python程序)
docker之自定义制作镜像(python程序)
|
8天前
|
Docker Python 容器
python检测docker compose文件是否正确
python检测docker compose文件是否正确
|
9天前
|
Java Linux Python
Linux环境下 代码java调用python出错
Linux环境下 代码java调用python出错
25 3
|
20天前
|
机器学习/深度学习 人工智能 安全
python和Java的区别以及特性
Python:适合快速开发、易于维护、学习成本低、灵活高效。如果你需要快速上手,写脚本、数据处理、做点机器学习,Python就是你的首选。 Java:适合大型项目、企业级应用,性能要求较高的场景。它类型安全、跨平台能力强,而且有丰富的生态,适合更复杂和规模化的开发。
22 3
|
23天前
|
SQL JavaScript 前端开发
用Java、Python来开发Hive应用
用Java、Python来开发Hive应用
22 6
|
23天前
|
NoSQL JavaScript Java
Java Python访问MongoDB
Java Python访问MongoDB
19 4
|
2月前
|
运维 数据安全/隐私保护 Docker
深入浅出Python装饰器《Docker容器化技术在运维中的应用与实践》
【8月更文挑战第29天】装饰器在Python中是一个强大而神秘的存在,它能够轻松地改变一个函数的行为而不修改其源代码。本文将通过浅显易懂的语言和生动的比喻,带你一步步揭开装饰器的神秘面纱,从基本概念到实际应用,让你轻松掌握这一魔法般的工具。
|
2月前
|
机器学习/深度学习 算法 Java
Java调用Python方法
【8月更文挑战第7天】
|
2月前
|
jenkins 持续交付 开发工具
"引爆效率革命!Docker+Jenkins+GIT+Tomcat:解锁持续集成魔法,一键部署Java Web应用的梦幻之旅!"
【8月更文挑战第9天】随着软件开发复杂度的增加,自动化变得至关重要。本文通过实例展示如何结合Docker、Jenkins、Git与Tomcat建立高效的持续集成(CI)流程。Docker确保应用环境一致性;Jenkins自动化处理构建、测试和部署;Git管理源代码版本;Tomcat部署Web应用。在Jenkins中配置Git插件并设置项目,集成Docker构建Tomcat应用镜像并运行容器。此外,通过自动化测试、代码质量检查、环境隔离和日志监控确保CI流程顺畅,从而显著提高开发效率和软件质量。
62 3
|
2月前
|
Docker Python 容器
[docker]封装python的docker镜像
[docker]封装python的docker镜像
下一篇
无影云桌面