在将java应用部署到docker环境的过程中,一个支持运行java程序的镜像是必不可少的。由于oracle授权方面的问题,docker hub 上一般只有基于openjdk的镜像,而且open jdk的镜像不支持字体管理,在使用一些验证码功能时会报错,比如生成验证码功能等。
而且openjdk 的镜像过于庞大,openjdk:17-slim的镜像大小就有407M。基于这些原因,我们可以选择定制一个java运行环境镜像。
由于jdk的体积比较大,我们选择jre来作为运行环境,jdk1.8及以前的版本,都是有jre的,但是jdk9以后的版本不在提供jre需要自己制作。
jlink是通过按模块打包的,但是由于目前很多库还不是按模块打包的,所以我们无法知道项目里面都用了那些模块。只好将所有的模块进行打包。这样避免以后出现缺失模块导致应用报错的问题。
下面是windows平台的打包命令
bin\jlink.exe --module-path jmods --add-modules ALL-MODULE-PATH --compress=2 --strip-debug --output jre
linux下,需要将要打包的java配置到系统环境变量中,不然生成不了,会报jlink not find错误
bin/jlink --module-path jmods --add-modules ALL-MODULE-PATH --compress=2 --strip-debug --output jre17
–strip-debug 不打包调式信息 --compress=2 开启2级别压缩,这两项减小生成的文件体积
–add-modules ALL-MODULE-PATH表示所有模块
docker pull alpine
alpine镜像非常小,只有5.59MB,可以通过docker run -it {iamgeId} sh 运行容器,运行一些简单的命令试试
D:\repo\docker\java>docker run -it c059bfaa849c sh
/ # ls
bin dev etc home lib media mnt opt proc root run sbin srv sys tmp usr var
FROM alpine:latest
MAINTAINER lin
#更换aline源
RUN echo "http://mirrors.aliyun.com/alpine/latest-stable/community" > /etc/apk/repositories
RUN echo "http://mirrors.aliyun.com/alpine/latest-stable/main" >> /etc/apk/repositories
#update apk
RUN apk update && apk upgrade
RUN apk --no-cache add ca-certificates
# bash vim wget curl net-tools
RUN apk add bash bash-doc bash-completion
RUN apk add vim wget curl net-tools
RUN rm -rf /var/cache/apk/*
RUN /bin/bash
#setup glibc
RUN wget https://github.com/sgerrand/alpine-pkg-glibc/releases/download/2.32-r0/glibc-2.32-r0.apk
RUN wget https://github.com/sgerrand/alpine-pkg-glibc/releases/download/2.32-r0/glibc-bin-2.32-r0.apk
RUN wget https://github.com/sgerrand/alpine-pkg-glibc/releases/download/2.32-r0/glibc-i18n-2.32-r0.apk
RUN wget https://github.com/sgerrand/alpine-pkg-glibc/releases/download/2.32-r0/glibc-dev-2.32-r0.apk
RUN wget -q -O /etc/apk/keys/sgerrand.rsa.pub https://alpine-pkgs.sgerrand.com/sgerrand.rsa.pub
RUN apk add glibc-2.32-r0.apk
RUN apk add glibc-bin-2.32-r0.apk
RUN apk add glibc-dev-2.32-r0.apk
RUN apk add glibc-i18n-2.32-r0.apk
RUN rm -rf *.apk
#setup date
RUN apk add tzdata
cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
#setup language 解决中文乱码
RUN /usr/glibc-compat/bin/localedef -i en_US -f UTF-8 en_US.UTF-8
ENV LANG=en_US.UTF-8
#copy jdk-8u251-linux-x64.tar.gz
ADD jdk-8u251-linux-x64.tar.gz /usr/local
#setup java env
ENV JAVA_HOME=/usr/local/jdk1.8.0_251
ENV PATH=$PATH:.:$JAVA_HOME/bin
ENV CALSSPATH=$JAVA_HOME/jre/lib/rt.jar:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
docker build -t jdk17-orcle-alpine .
总结:由于alpine缺少很多东西,比如glibc,需要安装后才能运行jvm,所以暂时放弃这条路
自己安装glibc比较麻烦,可以使用已经安装好glibc的镜像
#FROM alpine:latest
FROM frolvlad/alpine-glibc
MAINTAINER lin
COPY ./jre17 /usr/local/jre17
#setup java env
ENV JAVA_HOME=/usr/local/jre17
ENV PATH=$PATH:$JAVA_HOME/bin
ENV CALSSPATH=$JAVA_HOME/jre/lib/rt.jar:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
该方法构建的镜像体积是比较小,但是启动java应用(基于spring boot)的时候jvm会崩溃,原因不明
ubuntu镜像相对来说也不是很大,才70多M
FROM ubuntu:latest
MAINTAINER lin
#更新软件源
RUN apt-get update
#安装字体支持
RUN apt-get install fontconfig -y
#清理缓存
RUN apt-get clean
#在windows环境下构建,将/usr/share/zoneinfo/Asia/Shanghai拷贝到本地目录
COPY ./Shanghai /etc/localtime
#setup language 解决中文乱码
#设置中文支持
ENV LANG C.UTF-8
#解压jdk并删除lib目录下的源码
COPY ./jre17 /usr/local/jre17
#授执行权限
RUN chmod -R 750 /usr/local/jre17/bin
#setup java env
ENV JAVA_HOME=/usr/local/jre17
ENV PATH=$PATH:$JAVA_HOME/bin
ENV CALSSPATH=$JAVA_HOME/jre/lib/rt.jar:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
构建
docker build -t mydockerhub:5000/jdk17-orcle-ubuntu:jre-17 .
总结:除了需要处理语言问题外,其他都比较顺利,而且结果镜像211MB,比官方提供的小了很多,暂时就这样吧,以后有时间再折腾
总的来说,我对ruby还比较陌生,我正在为我正在创建的对象编写一些rspec测试用例。许多测试用例都非常基础,我只是想确保正确填充和返回值。我想知道是否有办法使用循环结构来执行此操作。不必为我要测试的每个方法都设置一个assertEquals。例如:describeitem,"TestingtheItem"doit"willhaveanullvaluetostart"doitem=Item.new#HereIcoulddotheitem.name.shouldbe_nil#thenIcoulddoitem.category.shouldbe_nilendend但我想要一些方法来使用
在选择我想要运行操作的频率时,唯一的选项是“每天”、“每小时”和“每10分钟”。谢谢!我想为我的Rails3.1应用程序运行调度程序。 最佳答案 这不是一个优雅的解决方案,但您可以安排它每天运行,并在实际开始工作之前检查日期是否为当月的第一天。 关于ruby-如何每月在Heroku运行一次Scheduler插件?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/8692687/
exe应该在我打开页面时运行。异步进程需要运行。有什么方法可以在ruby中使用两个参数异步运行exe吗?我已经尝试过ruby命令-system()、exec()但它正在等待过程完成。我需要用参数启动exe,无需等待进程完成是否有任何rubygems会支持我的问题? 最佳答案 您可以使用Process.spawn和Process.wait2:pid=Process.spawn'your.exe','--option'#Later...pid,status=Process.wait2pid您的程序将作为解释器的子进程执行。除
我尝试运行2.x应用程序。我使用rvm并为此应用程序设置其他版本的ruby:$rvmuseree-1.8.7-head我尝试运行服务器,然后出现很多错误:$script/serverNOTE:Gem.source_indexisdeprecated,useSpecification.Itwillberemovedonorafter2011-11-01.Gem.source_indexcalledfrom/Users/serg/rails_projects_terminal/work_proj/spohelp/config/../vendor/rails/railties/lib/r
Sinatra新手;我正在运行一些rspec测试,但在日志中收到了一堆不需要的噪音。如何消除日志中过多的噪音?我仔细检查了环境是否设置为:test,这意味着记录器级别应设置为WARN而不是DEBUG。spec_helper:require"./app"require"sinatra"require"rspec"require"rack/test"require"database_cleaner"require"factory_girl"set:environment,:testFactoryGirl.definition_file_paths=%w{./factories./test/
GivenIamadumbprogrammerandIamusingrspecandIamusingsporkandIwanttodebug...mmm...let'ssaaay,aspecforPhone.那么,我应该把“require'ruby-debug'”行放在哪里,以便在phone_spec.rb的特定点停止处理?(我所要求的只是一个大而粗的箭头,即使是一个有挑战性的程序员也能看到:-3)我已经尝试了很多位置,除非我没有正确测试它们,否则会发生一些奇怪的事情:在spec_helper.rb中的以下位置:require'rubygems'require'spork'
我正在玩HTML5视频并且在ERB中有以下片段:mp4视频从在我的开发环境中运行的服务器很好地流式传输到chrome。然而firefox显示带有海报图像的视频播放器,但带有一个大X。问题似乎是mongrel不确定ogv扩展的mime类型,并且只返回text/plain,如curl所示:$curl-Ihttp://0.0.0.0:3000/pr6.ogvHTTP/1.1200OKConnection:closeDate:Mon,19Apr201012:33:50GMTLast-Modified:Sun,18Apr201012:46:07GMTContent-Type:text/plain
是否有可能:before_filter:authenticate_user!||:authenticate_admin! 最佳答案 before_filter:do_authenticationdefdo_authenticationauthenticate_user!||authenticate_admin!end 关于ruby-on-rails-before_filter运行多个方法,我们在StackOverflow上找到一个类似的问题: https://
之前在培训新生的时候,windows环境下配置opencv环境一直教的都是网上主流的vsstudio配置属性表,但是这个似乎对新生来说难度略高(虽然个人觉得完全是他们自己的问题),加之暑假之后对cmake实在是爱不释手,且这样配置确实十分简单(其实都不需要配置),故斗胆妄言vscode下配置CV之法。其实极为简单,图比较多所以很长。如果你看此文还配不好,你应该思考一下是不是自己的问题。闲话少说,直接开始。0.CMkae简介有的人到大二了都不知道cmake是什么,我不说是谁。CMake是一个开源免费并且跨平台的构建工具,可以用简单的语句来描述所有平台的编译过程。它能够根据当前所在平台输出对应的m
Unity自动旋转动画1.开门需要门把手先动,门再动2.关门需要门先动,门把手再动3.中途播放过程中不可以再次进行操作觉得太复杂?查看我的文章开关门简易进阶版效果:如果这个门可以直接打开的话,就不需要放置"门把手"如果门把手还有钥匙需要旋转,那就可以把钥匙放在门把手的"门把手",理论上是可以无限套娃的可调整参数有:角度,反向,轴向,速度运行时点击Test进行测试自己写的代码比较垃圾,命名与结构比较拉,高手轻点喷,新手有类似的需求可以拿去做参考上代码usingSystem.Collections;usingSystem.Collections.Generic;usingUnityEngine;u