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 ...
随机推荐
- 前端开发环境webstorm搭建
1. 下载node.js https://nodejs.org/en/ 2. 安装 webpack 用管理员开个命令行 (mac: open terminal) npm install webpack ...
- css元素溢出
当子元素的尺寸超过父元素的尺寸时,需要设置父元素显示溢出的子元素的方式,设置的方法是通过overflow属性来设置. overflow的设置项: 1.visible 默认值.内容不会被修剪,会呈现在元 ...
- 洛谷 P5020 【货币系统】
谁说这一定要排序的,这就是个装满背包嘛 \({f[i]}\) 表示 \(i\) 面值最多能被几张钱表示 则若其不能被表示 \(f[i]=-inf\) 能表示且只有它自己则 \(f[i]=1\) 初始化 ...
- redis 从入门到遗忘
Key操作 keys * *: 通配任意多个字符 ?: 通配单个字符 []: 通配括号内的某1个字符 exists key 存在返回1,不存在返回0 type key rename oldkey ne ...
- 2018蓝桥杯 省赛D题(测试次数)
x星球的居民脾气不太好,但好在他们生气的时候唯一的异常举动是:摔手机.各大厂商也就纷纷推出各种耐摔型手机.x星球的质监局规定了手机必须经过耐摔测试,并且评定出一个耐摔指数来,之后才允许上市流通.x星球 ...
- 群福利:Redis云服务器免费领取(附Redis安装和连接远程连接Redis案例)
Redis安装:在线体验:https://try.redis.io Ubuntu:sudo apt-get install redis CentOS:yum install redis (root权限 ...
- 洛谷P1080 国王游戏
两个难点. 怎么想到的贪心? 首先确定算法: 显然不是数据结构题.转成图论也不太可能. 考虑DP:f[i][j]表示前i个人取j状态的最小最大值......2^1000,直接放弃. 因为出现了“最大值 ...
- TensorFlow车牌识别实践(2)
http://www.cnblogs.com/jackkwok/p/7228021.html 1,运行准备 按照https://github.com/matthewearl/deep-anpr说明的用 ...
- Redis:默认配置文件redis.conf详解
转: Redis:默认配置文件redis.conf详解 # Redis配置文件样例 # Note on units: when memory size is needed, it is possibl ...
- Spring 学习笔记一
1.IOC,DI. 2.装配bean基于xml(实例化,声明周期,后处理bean,属性注入).3.装配bean基于注解 1 spring框架概述 1.1 什么是spring l Sp ...