docker 系列 - Java程序制作Docker Image推荐方案(转载)
本文转自 https://segmentfault.com/a/1190000016449865 , 感谢作者!
本文的源代码在:https://github.com/chanjarste...
这里先给出一些Docker Image制作的要求,之后我们再看怎么做。
- 制作过程要融合在项目构建过程中
- 使用官方Image作为基础Image
- 设定正确的时区
- Container内的程序以非root用户启动
- 指定Web程序的接口
- 能够传递JVM参数、Java System Properties、程序自定义的参数
下面具体讲一下具体怎么做到以上几点:
制作过程要融合在项目构建过程中
这里推荐使用Spotify的dockerfile-maven-plugin,理由是这个plugin用起来最简单且容易掌握。
该plugin的本质上是你写一个Dockerfile(关于Dockerfile的具体写法请参照官方文档),这个plugin把一些参数传递进去来帮助你构建Docker Image。
因此只要你会写Dockerfile,就会使用这个plugin,它没有加入任何额外的概念。
使用官方Image作为基础Image
Java的基础镜像应该在openjdk repository里寻找,而不是在已经过时的java repository里找。
openjdk repository提供了各种各样的image tags看起来眼花缭乱,但是本质上来说就这么几个:
- openjdk:<version>
- openjdk:<version>-slim
- openjdk:<version>-alpine
关于<version>
一般来说指定大版本号就行了,比如你可以在Dockerfile这样写:
FROM openjdk:8-alpine
从尺寸上来讲,alpine最小、slim稍大、默认的最大。所以应该尽可能的使用alpine版本的,如果发现程序的运行环境缺少某些东西,那么尝试用slim版本或者默认版本。就目前的经验来讲:
- 如果需要操作系统字体库,那么就得使用slim版本或者默认版本。需要操作系统字体库的程序例如:图片验证码、PDF导出。
- 如果需要某些Linux标准的动态/静态连接库,那么在alpine版本不行的情况下,尝试slim版本或默认版本。因为alpine版本是一个及其精简的Linux,它删除了很多东西。
设定正确的时区
几乎所有的Docker Image的时区都是UTC,我们需要给我们自己制作的Docker Image设定时区(参考的是SO的这个回答):
ENV TZ=Asia/Shanghai
RUN set -eux; \
ln -snf /usr/share/zoneinfo/$TZ /etc/localtime; \
echo $TZ > /etc/timezone
关于数据库时区的相关内容可以见:
Container内的程序以非root用户启动
在Docker Image内部,我们应该使用非root用户启动程序,这需要使用到gosu。
gosu的Dockerfile指南在这里。
记得要根据不同的基础Image选择适合的安装方式。
如果你用的是openjdk:<version>-alpine
,那么直接用本项目提供的Dockerfile就行了。
如果你用的是openjdk:<version>-slim
或者openjdk:<version>
,那么在Image里安装gosu的方式是这样:
RUN set -ex; \
apt update; \
apt install -y gosu; \
rm -rf /var/lib/apt/lists/*; \
# verify that the binary works
gosu nobody true;
指定Web程序的接口
对于联网应用而言,必须在Dockerfile中指定暴露的端口,否则该端口无法映射。
EXPOSE 8080
能够传递JVM参数、Java System Properties、程序自定义的参数
我们需要能够在启动Docker Image的时候将一些参数传递进去:
- JVM参数
- Java System Properties
- 程序启动参数
这里就需要参考Dockerfile best practice和Docker ENTRYPOINT了。
样例项目
样例项目源代码在这里:https://github.com/chanjarster/dockerfile-examples/
目录结构
所有与程序相关的东西都存放在/home/java-app/
下:
/home/java-app
├── docker-entrypoint.sh
├── lib
│ └── java-app.jar
├── etc
├── logs
└── tmp
docker-entrypoint.sh
,启动脚本lib
,存放JAR包lib/java-app.jar
,程序JAR包etc
,存放配置文件logs
,存放日志文件tmp
,存放临时文件
构建Image的方法
mvn clean package dockerfile:build
运行
普通启动,然后访问http://localhost:8080
:
docker run -p 8080:8080 chanjarster/dockerfile-java-examples-1:1.0-SNAPSHOT
设定JVM参数,使用JVM_OPTS
环境变量:
docker run -p 8080:8080 -e JVM_OPTS='-Xmx128M -Xms128M' chanjarster/dockerfile-java-examples-1:1.0-SNAPSHOT
设定System Properties,使用JAVA_ARGS
环境变量:
docker run -p 8080:8080 -e JAVA_ARGS='-Dabc=xyz -Ddef=uvw' chanjarster/dockerfile-java-examples-1:1.0-SNAPSHOT
提供程序运行参数,在后面直接添加即可:
docker run -p 8080:8080 chanjarster/dockerfile-java-examples-1:1.0-SNAPSHOT --debug
参考文档
- Dockerfile best practice
- Docker ENTRYPOINT
- Postgres Dockerfile & script
- MySQL Dockerfile & script
- gosu Intall
- Bash set命令教程
docker 系列 - Java程序制作Docker Image推荐方案(转载)的更多相关文章
- Docker系列-(2) 镜像制作与发布
上篇文章引入了Docker的基本原理和操作,本节文章主要介绍如何制作Docker镜像和发布. 镜像文件结构 Docker镜像的本质是一系列文件的集合,这些文件依次叠加,形成了最后的镜像文件,类似于下图 ...
- Docker极简入门:使用Docker运行Java程序
运行简单的Java程序 先在当前目录创建App.java文件 public class App{ public static void main(String[] args){ String os = ...
- docker 运行java程序时区问题
如果 docker 上面 java 的当前时间比,真实时间慢了8 小时,那估计就是时区问题了, 需要在 打包docker镜像的时候 带上 localtime 和 timezone.(这2 个文件 ...
- Docker系列-第七篇Docker构建SpringBoot应用
1.基于Dockerfile构建SpringBoot镜像 1.1准备工作 将SpringBoot项目通过maven打成jar包 mvn clean package #使用maven打包项目 1.2使用 ...
- Docker系列(一)Docker概述,核心概念讲解,安装部署
部分内容参考链接: Docker实战总结(非常全面,建议收藏) 一. Docker概述 Docker是一个开源的应用容器引擎(基于Go语言开发),让开发者可以打包他们的应用以及依赖包到一个可移植的容器 ...
- Docker系列教程01-使用Docker镜像
docker系列导读 一文带你读懂什么是docker Docker安装部署 10张图带你深入理解Docker容器和镜像 前言 学习Docker,我们需要掌握它的三大核心概念:镜像.容器和仓库. 今天先 ...
- docker系列之一:初见docker
什么是docker? docker是目前linux最流行的容器技术,Docker 将应用程序与该程序的依赖,打包在一个文件里面.运行这个文件,就会生成一个虚拟容器.程序在这个虚拟容器里运行,就好像在真 ...
- Docker系列06:Linux修改docker镜像和容器数据存储位置
指定镜像和容器存放路径的参数是--graph=/var/lib/docker,其默认存储位置为/var/lib/docker, Docker 的配置文件可以设置大部分的后台进程参数,在各个操作系统中的 ...
- Java程序员进击书籍推荐
计算机基础 计算机科学导论 计算机操作系统 操作系统原理及应用(Linux) Java 基础和进阶 疯狂Java讲义 Java 核心基础卷1/2 Java编程思想 Java 8实战 jls11 Eff ...
随机推荐
- IIS最小配置
目的 : IIS按需要配置练习 测试环境 IIS 10 WIN10 1.安装IIS与建立网站 安装IIS略,服务器版用添加角色,用户版添加删除WINDOWS组件. 装好IIS之后,建一个网 ...
- BZOJ3133[Baltic2013]ballmachine
题目描述 https://www.lydsy.com/JudgeOnline/problem.php?id=3133 题解 还是分两个操作来说吧. 先看第一个操作,放球,可以发现,对于祖先节点和后代节 ...
- A.01.09—模块的输出—PWM低端输出
PWM输出在汽车上的应用也比较多,它有三种不同的实现方式. 第一种由软件实现,即软件设定对一个输出口拉高和拉低的时间,形成时高时低的PWM控制:但这种方式目前用得不多,这是由使用需求和软件本身的特性决 ...
- 微服务下 Spring Boot Maven 工程依赖关系管理
单体 Spring Boot Maven 工程 最基本的 pom.xml 包含工程信息.Spring Boot 父工程.属性配置.依赖包.构建插件 <?xml version="1.0 ...
- LINQ的基础使用方法
//新建一个项目 //项目下新建一个App_Code文件夹 //在文件夹内添加一个LINQ TO SQL,这个操作就相当于创建了一个实体类 //连接数据库后把表拖入到服务器资源管理器中 //创建数据访 ...
- bzoj2007 NOI2010 海拔(对偶图)
80分(最小割)思路 先考虑如果没有题目中东南角为\(1\)那个限制的话会怎样. 那么只要让每个点的海拔都是\(0\)就行了.这样不论怎样走,最后的答案都是0. 然后再考虑那个东南角为\(1\)的限制 ...
- ImageMagick - 智能的灰度空间(GRAYColorspace)让人窒息
今天在处理一张 gray.jpg 图片时,发现生成的图片色彩空间是: GRAYColorspace 可我在代码中明明设置了: MagickWand * mw = NewMagickWand (); M ...
- java 打印水仙花数
package cn.lijun.demo6; public class Test2 { public static void main(String[] args) { for(int i=100; ...
- Python网络编程之socket编程
什么是Socket? Socket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口.在设计模式中,Socket其实就是一个门面模式,它把复杂的TCP/IP协议族隐藏在Socket接口后面 ...
- xlrd(excel导入mysql数据库)
一.xlrd模块: python 对 excel 文件进行读操作 1.下载xlrd 并安装 http://pypi.python.org/pypi/xlrd wget https://pypi.pyt ...