DockerFile实战

背景

在上一篇文章中,我们对DockerFile有了一个较为深刻的认识,那么这篇文章,我将会向你展示如何自定义一个镜像并且在docker上运行。

一、基础指令

指令 技术说明 生产环境最佳实践 典型错误示例
FROM - 必须作为Dockerfile第一条指令 - 推荐使用官方镜像的LTS版本 FROM eclipse-temurin:17-jre-jammy FROM ubuntu:latest
ENV - 支持多变量定义:ENV A=1 B=2 - 会被后续RUN/CMD等指令继承 ENV JAVA_OPTS="-Xms512m -Xmx1024m" ENV PATH=$PATH:/tmp
COPY - 支持通配符:COPY *.jar /app/ - 会保留文件元数据 COPY --chown=1000:1000 . /app COPY /opt/xxx /app
RUN - 多个命令用&&连接 - 用\换行提高可读性 RUN apt update && apt install -y \ curl && rm -rf /var/lib/apt/lists/* RUN cd /app && tar xf pkg.tar
EXPOSE - 只是声明而非实际开放端口 - 需与docker run -p配合 EXPOSE 8080/tcp 8443/udp EXPOSE 8080-8090
ENTRYPOINT - 容器的主进程 - 建议用JSON数组格式 ENTRYPOINT ["java", "-jar", "app.jar"] ENTRYPOINT java -jar app.jar
java 复制代码
#1、准备Linux运行环境(推荐使用轻量级基础镜像)
FROM eclipse-temurin:17-jre-alpine

#2、安装JRE并配置环境变量(基础镜像已包含,此处为扩展配置)
ENV JAVA_OPTS="-Xms512m -Xmx1024m"
ENV TZ=Asia/Shanghai

#3、拷贝Jar包(使用分层构建优化)
COPY target/*.jar /app/application.jar

#4、编写运行脚本(使用ENTRYPOINT+CMD组合)
ENTRYPOINT ["sh", "-c", "java ${JAVA_OPTS} -jar /app/application.jar"]
EXPOSE 8888

二、分步骤技术解析

① 基础镜像选择

  • ​推荐方案​:

    java 复制代码
    FROM eclipse-temurin:17-jre-alpine
    • 比openjdk镜像更小(Alpine版约85MB)
    • 已包含完整的JRE环境
  • ​替代方案​:

    java 复制代码
    FROM amazoncorretto:17  # 亚马逊优化版

② 环境配置增强

java 复制代码
# 内存配置(根据应用需求调整)
ENV JAVA_OPTS="-Xms512m -Xmx1024m -XX:+UseG1GC"

# 时区设置
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone

③ 应用部署优化

  • 分层构建技巧 :

    java 复制代码
    COPY --chown=1000:1000 target/*.jar /app/  # 指定非root用户
  • 版本控制 :

    java 复制代码
    ARG JAR_FILE=target/*.jar
    COPY ${JAR_FILE} /app/application.jar

④ 启动脚本进阶

java 复制代码
# 健康检查(K8s就绪探针)
HEALTHCHECK --interval=30s --timeout=3s \
  CMD curl -f http://localhost:8888/actuator/health || exit 1

# 允许传递启动参数
CMD ["--spring.profiles.active=prod"]

三、构建与运行命令

  1. ​构建镜像​:

    java 复制代码
    docker build -t java-app:v1 .
  2. ​运行容器​:

    java 复制代码
    docker run -d -p 8860:8888 \
      -e JAVA_OPTS="-Xmx2048m" \
      java-app:v1

容器创建成功:

四、生产环境建议

  1. ​安全加固​:

    java 复制代码
    USER 1000  # 使用非root用户
    RUN addgroup -S appgroup && adduser -S appuser -G appgroup
  2. ​多阶段构建​(如需包含JDK编译):

    java 复制代码
    FROM eclipse-temurin:17-jdk as builder
    WORKDIR /build
    COPY . .
    RUN ./gradlew bootJar
    
    FROM eclipse-temurin:17-jre-alpine
    COPY --from=builder /build/build/libs/*.jar /app.jar
  3. ​镜像扫描​:

    java 复制代码
    docker scan java-app:v1

五、常见问题排查

问题现象 解决方案
容器启动立即退出 docker logs <container> 查看JVM错误
内存溢出(OOM) 调整-Xmx参数并检查内存泄漏
时区不正确 确认TZ环境变量已正确设置
应用性能低下 考虑使用-XX:+UseContainerSupport
相关推荐
是枚小菜鸡儿吖3 小时前
Home Assistant跨品牌智能家居教程:Docker部署、米家接入、vivo桥接与远程访问
docker·容器·智能家居
螺蛳粉 螺蛳粉6 小时前
第 02 篇:镜像分层与 containerd 2.x 实战:SystemdCgroup 与 pause 镜像配置踩坑(底座认知 02)
docker·云原生·容器·kubernetes·etcd·containerd·kube-apiserver
wefg16 小时前
【Docker】镜像相关指令
运维·docker·容器
java_logo7 小时前
Docker 部署 DPanel:轻松搭建轻量容器管理平台
运维·docker·容器·podman·容器管理·dpanel·轩辕镜像
死磕音视频8 小时前
Open WebUI 入门:用 Docker 装上本地对话界面并连接 Ollama
docker·ollama·本地大模型·open webui
分布式存储与RustFS8 小时前
CI 老被 Docker Hub 的 429 卡住,自建 Registry 把镜像搬进内网
运维·docker·开源·镜像仓库·对象存储·ci·rustfs
n112129 小时前
Docker 容器时区错 8 小时:3 个坑
运维·docker·容器·故障排查·服务器运维·容器时区
慈云数据9 小时前
用 DSH 辅助部署一个网站监控平台:Uptime Kuma + Docker 实战
运维·docker·容器
螺蛳粉 螺蛳粉10 小时前
第 03 篇:为什么 K8s 的最小调度单元是 Pod 而不是容器:pause 容器与边车模式(底座认知 03)
docker·云原生·容器·kubernetes·etcd·运维排障·kube-apiserver
杨浦老苏1 天前
把项目管理搬回自己服务器:Windshift部署与避坑
docker·项目管理·群晖