docker - 多阶段 Docker 映像
问题描述
我创建了一个多阶段 dockerfile。
FROM dot-portal.de.pri.o2.com:8079/centos:centos7 as base
# Install a basic SSH server GIT, UNZIP, LSOF and JDK 8
ADD myrepo.repo /etc/yum.repos.d/myrepo.repo
RUN rm -rf /etc/yum.repos.d/CentOS*
COPY docker /opt/docker
RUN yum repolist refresh && yum clean all && yum repolist && yum install -y openssh-server git unzip lsof epel-release bzip2 fontconfig && yum clean all && rm -rf /var/cache/yum && cd /opt/docker && rpm -ivh *.rpm && rm -rf /opt/docker
ADD docker-compose-Linux-x86_64 /usr/local/bin/docker-compose
RUN ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose
# update sshd settings, create jenkins user, set jenkins user pw, generate ssh keys
RUN sed -i 's|session required pam_loginuid.so|session optional pam_loginuid.so|g' /etc/pam.d/sshd \
&& mkdir -p /var/run/sshd \
&& useradd -u 1000 -m -s /bin/bash jenkins \
&& echo "jenkins:jenkins" | chpasswd \
&& usermod -aG wheel jenkins \
&& /usr/bin/ssh-keygen -A \
&& sed -i "s/#UsePrivilegeSeparation.*/UsePrivilegeSeparation no/g" /etc/ssh/sshd_config \
&& sed -i 's/PermitRootLogin without-password/PermitRootLogin yes/' /etc/ssh/sshd_config \
&& echo export JAVA_HOME="/`alternatives --display java | grep best | cut -d "/" -f 2-6`" >> /etc/environment \
&& usermod -a -G docker jenkins \
&& sed 's@session\s*required\s*pam_loginuid.so@session optional pam_loginuid.so@g' -i /etc/pam.d/sshd
RUN git config --global http.sslVerify false && mkdir -p /opt/app/jenkins
COPY --chown=jenkins:jenkins jenkins_tools /opt/app/jenkins/jenkins_tools/
ADD node-v10.13.0-linux-x64.tar.gz /opt/app/jenkins/jenkins_tools
ENV CI_TOOLS_HOME /opt/app/jenkins/jenkins_tools
ENV ARCH Linux-x86_64
ENV CI_TOOLS_HOME /opt/app/jenkins/jenkins_tools
ENV JAVA_HOME /usr/java/jdk1.8.0_241-amd64/
COPY dot-portal.de.pri.o2.com.crt $CI_TOOLS_HOME/dot-portal.de.pri.o2.com.crt
RUN cd $CI_TOOLS_HOME && echo yes | keytool -importcert -file dot-portal.de.pri.o2.com.crt -alias "dot-portal.de.pri.o2.com" -keystore "$JAVA_HOME/jre/lib/security/cacerts" -storepass changeit
COPY --chown=jenkins:jenkins authorized_keys /home/jenkins/.ssh/
RUN mkdir /root/.ssh && mkdir -p /opt/app/home/jenkins && chown -R jenkins:jenkins /opt/app/home/jenkins
COPY dockerslave /etc/default/docker
RUN ln -s $CI_TOOLS_HOME/phantomjs-2.1.1-linux-x86_64/bin/phantomjs /usr/bin/ && chown -R jenkins:jenkins /opt/app/jenkins/jenkins_tools
FROM base
COPY --from=base /opt/app/jenkins/jenkins_tools /opt/app/jenkins/jenkins_tools
COPY --from=base /etc/default/docker /etc/default/docker
COPY --from=base /usr/bin/phantomjs /usr/bin/phantomjs
ENV CI_TOOLS_HOME /opt/app/jenkins/jenkins_tools
ENV ARCH Linux-x86_64
ENV CI_TOOLS_HOME /opt/app/jenkins/jenkins_tools
ENV JAVA_HOME /usr/java/jdk1.8.0_241-amd64/
ENV MAVEN_HOME /opt/app/jenkins/jenkins_tools/nonarch/maven-3.3.9
RUN echo "export PATH=$CI_TOOLS_HOME/node-v10.13.0-linux-x64/bin/:$CI_TOOLS_HOME/phantomjs-2.1.1-linux-x86_64/bin/:$JAVA_HOME/bin:$MAVEN_HOME/bin:$PATH" >> ~/.bashrc
# Standard SSH port
EXPOSE 22
CMD ["/usr/sbin/sshd", "-D", "-e"]
我的问题是,我在基本图像中安装/创建的包和用户不会反映在最终图像中。仅从 Base 我正在创建最终映像,但是当我连接到容器时,我无法看到在基本映像中创建的用户“jenkins”并且包也丢失了。
解决方案
您想在这里使用多级 docker 构建来实现什么?如果您的第二阶段从具有两个阶段的构建中的第一阶段的结果开始,那么您还不如只有一个阶段......
通常使用多阶段构建,因为使用第一阶段(例如“构建器”)来构建一些需要大量开发工具的人工制品。在第二阶段,只有该人工制品将被复制到一个小的基础图像中,以获得一个非常小的最终图像,因为它不包含构建人工制品所需的工具。
来自 docker docs的示例:
FROM golang:1.7.3 as builder
WORKDIR /go/src/github.com/alexellis/href-counter/
RUN go get -d -v golang.org/x/net/html
COPY app.go .
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o app .
FROM alpine:latest
RUN apk --no-cache add ca-certificates
WORKDIR /root/
COPY --from=builder /go/src/github.com/alexellis/href-counter/app .
CMD ["./app"]
在您的情况下,我很确定您的最终图像确实包含 jenkins 用户,因为您的第二阶段是从基础阶段开始的。但是,这些从基础映像复制的复制命令会将权限重置为root
您的第二阶段:
COPY --from=base /opt/app/jenkins/jenkins_tools /opt/app/jenkins/jenkins_tools
COPY --from=base /etc/default/docker /etc/default/docker
COPY --from=base /usr/bin/phantomjs /usr/bin/phantomjs
当您开始时,此复制命令是多余的FROM base
。如果您删除这些行,jenkins_tools 目录将由 jenkins 用户正确拥有。
请注意,您可以更改用于在 docker 构建期间执行命令的用户USER <username>
推荐阅读
- ios - 在 iOS 中基于 scheme 管理 Pod
- c# - 用户控件并从放置在用户控件中的控件引发事件
- nginx - 在 NGINX 后面时所有网站链接都断开
- java - Java.lang.classnotfoundexception - HelloWorld.class
- javascript - 当应用程序在虚拟文件夹中运行时,Webpack 不加载脚本
- python - 无法重命名熊猫 DataFrame 中的第一列
- vba - 始终保持 Excel 最小化
- java - Java Melody - 点击命中 URL 时解析模板“错误”时出错
- vba - 如何同时在多个 Wksheets 中搜索字符串?
- c# - 一个大视图中的几个小视图 mvvm light