错误做法:
ADD http://example.com/big.tar.xz /usr/src/things/RUN tar -xJf /usr/src/things/big.tar.xz -C /usr/src/thingsRUN make -C /usr/src/things all复制代码
正确的做法:
RUN mkdir -p /usr/src/things && curl -SL http://example.com/big.tar.xz | tar -xJC /usr/src/things && make -C /usr/src/things all复制代码
RUN指令在使用较长的RUN指令时可以使用反斜杠分隔多行 。大部分使用RUN指令的常见是运行apt-wget命令,在该场景下请注意以下几点 。
- 不要在一行中单独使用指令RUN apt-get update 。当软件源更新后,这样做会引起缓存问题,导致RUN apt-get install指令运行失败 。所以,RUN apt-get update和RUN apt-get install应该写在同一行 。比如 RUN apt-get update && apt-get install -y package-1 package-2 package-3
- 避免使用指令RUN apt-get upgrade 和 RUN apt-get dist-upgrade 。因为在一个无特权的容器中,一些必要的包会更新失败 。如果需要更新一个包(如package-1),直接使用命令RUN apt-get install -y package-1 。
比如下面这个例子:
FROM busyboxWORKDIR /AppCOPY run.sh /appRUN chmod +x run.shENTRYPOINT ["/app/run.sh"]CMD ["param1"]复制代码
run.sh内容如下:#!/bin/shecho "$@"复制代码
运行后输出结果为param1, Dockerfile中CMD和ENTRYPOINT的顺序不重要(CMD写在ENTRYPOINT前后都可以) 。当在windows系统下build dockerfile你可能会遇到这个问题
standard_init_linux.go:207: exec user process caused "no such file or directory"复制代码
这是因为sh文件的fileformat是dos,这里需要修改为unix,不需要下载额外的工具,一般我们机器上安装了git会自带git bash,进入git bash,使用vi 编辑,在命令行模式下修改(:set ff=unix) 。不要再Dockerfile中做端口映射使用Dockerfile的EXPOSE指令,虽然可以将容器端口映射在主机端口上,但会破坏Docker的可移植性,且这样的镜像在一台主机上只能启动一个容器 。所以端口映射应在docker run命令中用-p 参数指定 。
# 不要再Dockerfile中做如下映射EXPOSE 80:8080# 仅暴露80端口,需要另做映射EXPOSE 80复制代码
实践Dockerfile的写法JAVA 服务的DockerFileFROM openjdk:8-jre-alpineENV spring_profiles_active=devENV env_java_debug_enabled=falseEXPOSE 8080WORKDIR /appADD target/smcp-web.jar /app/target/smcp-web.jarADD run.sh /appENTRYPOINT ./run.sh复制代码
可以看到基础镜像是openjdk,然后设置了两个环境变量,服务访问端口是9090(意味着springboot应用中指定了server.port=8080),设置了工作目录是/app 。通过ENTRYPOINT设定了启动镜像时要启动的命令(./run.sh) 。这个脚本中的内容如下:#!/bin/sh# Set debug options if requiredif [ x"${env_java_debug_enabled}" != x ] && [ "${env_java_debug_enabled}" != "false" ]; then java_debug_args="-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005"fi# ex: env_jvm_flags="-Xmx1200m -XX:MaxRAM=1500m" for productionjava $java_debug_args $env_jvm_flags -XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap -jar target/smcp-web.jar复制代码
如果我们要指定jvm的一些参数,可以通过在环境变量中设置env_jvm_flags来指定 。Maven Dockerfilemaven的Dockerfile也写的很好,这里我发上来也给大家参考下
FROM openjdk:8-jdkARG MAVEN_VERSION=3.6.3ARG USER_HOME_DIR="/root"ARG SHA=c35a1803a6e70a126e80b2b3ae33eed961f83ed74d18fcd16909b2d44d7dada3203f1ffe726c17ef8dcca2dcaa9fca676987befeadc9b9f759967a8cb77181c0ARG BASE_URL=https://Apache.osuosl.org/maven/maven-3/${MAVEN_VERSION}/binariesRUN mkdir -p /usr/share/maven /usr/share/maven/ref && curl -fsSL -o /tmp/apache-maven.tar.gz ${BASE_URL}/apache-maven-${MAVEN_VERSION}-bin.tar.gz && echo "${SHA} /tmp/apache-maven.tar.gz" | sha512sum -c - && tar -xzf /tmp/apache-maven.tar.gz -C /usr/share/maven --strip-components=1 && rm -f /tmp/apache-maven.tar.gz && ln -s /usr/share/maven/bin/mvn /usr/bin/mvnENV MAVEN_HOME /usr/share/mavenENV MAVEN_CONFIG "$USER_HOME_DIR/.m2"COPY mvn-entrypoint.sh /usr/local/bin/mvn-entrypoint.shCOPY settings-docker.xml /usr/share/maven/ref/ENTRYPOINT ["/usr/local/bin/mvn-entrypoint.sh"]CMD ["mvn"]复制代码
推荐阅读
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 个人交社保、单位交社保,差别到底在哪里?一文读懂
- 看完这篇,再也不用焦虑如何写dockerfile了
- 一文搞懂交换基础知识
- 一文读懂常用开源许可证
- 抽水马桶是如何工作的?一文看懂虹吸原理
- 一文讲弄懂什么是vlan、三层交换机、网关、子网掩码
- 如何玩转 HTTP 3?
- 一文教您如何实现持续集成服务器环境搭建
- 一文搞定MySQL性能调优
- 一文了解神经网络工作原理