【分享】记一次项目迁移(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月前
|
存储 监控 测试技术
如何将现有的应用程序迁移到Docker容器中?
如何将现有的应用程序迁移到Docker容器中?
728 57
|
8月前
|
机器学习/深度学习 JSON Java
Java调用Python的5种实用方案:从简单到进阶的全场景解析
在机器学习与大数据融合背景下,Java与Python协同开发成为企业常见需求。本文通过真实案例解析5种主流调用方案,涵盖脚本调用到微服务架构,助力开发者根据业务场景选择最优方案,提升开发效率与系统性能。
1913 0
|
JavaScript 前端开发 Java
通义灵码 Rules 库合集来了,覆盖Java、TypeScript、Python、Go、JavaScript 等
通义灵码新上的外挂 Project Rules 获得了开发者的一致好评:最小成本适配我的开发风格、相当把团队经验沉淀下来,是个很好功能……
1965 103
|
8月前
|
jenkins Shell 测试技术
|
10月前
|
存储 监控 Java
如何对迁移到Docker容器中的应用进行性能优化?
如何对迁移到Docker容器中的应用进行性能优化?
596 59
|
8月前
|
安全 jenkins Java
Java、Python、C++支持jenkins和SonarQube(一)
Jenkins 是一个开源的 持续集成(CI)和持续交付(CD) 工具,用于自动化构建、测试和部署软件项目。它基于 Java 开发,支持跨平台运行,并拥有丰富的插件生态系统,可以灵活地扩展功能
493 5
|
8月前
|
jenkins Java Shell
Java、Python、C++支持jenkins和SonarQube(全集)
Jenkins 是一个开源的持续集成(CI)和持续交付(CD)工具,用于自动化构建、测试和部署软件项目。它基于 Java 开发,支持跨平台运行,并拥有丰富的插件生态系统,可以灵活地扩展功能
722 1
|
8月前
|
jenkins Java 持续交付
Java、Python、C++支持Jenkins和SonarQube(三)
Python与Jenkins和SonarQube
403 1
|
8月前
|
jenkins Java 测试技术
|
12月前
|
数据采集 自然语言处理 Java
Playwright 多语言一体化——Python/Java/.NET 全栈采集实战
本文以反面教材形式,剖析了在使用 Playwright 爬取懂车帝车友圈问答数据时常见的配置错误(如未设置代理、Cookie 和 User-Agent),并提供了 Python、Java 和 .NET 三种语言的修复代码示例。通过错误示例 → 问题剖析 → 修复过程 → 总结教训的完整流程,帮助读者掌握如何正确配置爬虫代理及其它必要参数,避免 IP 封禁和反爬检测,实现高效数据采集与分析。
722 3
Playwright 多语言一体化——Python/Java/.NET 全栈采集实战