Dockerfile文件详细教程

写在前面

Dockerfile是用来构建镜像的,他实际上就是把在linux下的命令操作写到了Dockerfile中,通过Dockerfile去执行设置好的操作命令,保证通过Dockerfile的构建镜像是一致的。

实战分析

该例子来自于 chromium 项目

主要干的事情:

  1. 来指定用哪个镜像;
  2. 安装一些编译需要的环境:C++编译环境,Java环境等
sh 复制代码
# This Dockerfile specifies the recipe for creating an image for the tests
# to run in.
#
# We install as many test dependencies here as we can, because these setup
# steps can be cached.  They do *not* run every time we run the build.
# The Docker image is only rebuilt when the Dockerfile (ie. this file)
# changes.

# 指定了使用什么镜像 debian
# Base Dockerfile for gRPC dev images
FROM debian:latest

# 添加软件源
# Apt source for old Python versions.
RUN echo 'deb http://ppa.launchpad.net/fkrull/deadsnakes/ubuntu trusty main' > /etc/apt/sources.list.d/deadsnakes.list && \
  apt-key adv --keyserver keyserver.ubuntu.com --recv-keys DB82666C

# Apt source for Oracle Java.
RUN echo 'deb http://ppa.launchpad.net/webupd8team/java/ubuntu trusty main' > /etc/apt/sources.list.d/webupd8team-java-trusty.list && \
  apt-key adv --keyserver keyserver.ubuntu.com --recv-keys EEA14886 && \
  echo "oracle-java7-installer shared/accepted-oracle-license-v1-1 select true" | debconf-set-selections

# Apt source for Mono
RUN echo "deb http://download.mono-project.com/repo/debian wheezy main" | tee /etc/apt/sources.list.d/mono-xamarin.list && \
  echo "deb http://download.mono-project.com/repo/debian wheezy-libjpeg62-compat main" | tee -a /etc/apt/sources.list.d/mono-xamarin.list && \
  apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF

# Apt source for php
RUN echo "deb http://ppa.launchpad.net/ondrej/php/ubuntu trusty main" | tee /etc/apt/sources.list.d/various-php.list && \
  apt-key adv --keyserver keyserver.ubuntu.com --recv-keys F4FCBB07

# Install dotnet SDK based on https://www.microsoft.com/net/core#debian
# (Ubuntu instructions need apt to support https)
RUN apt-get update && apt-get install -y --force-yes curl libunwind8 gettext && \
  curl -sSL -o dotnet.tar.gz https://go.microsoft.com/fwlink/?LinkID=847105 &&  \
  mkdir -p /opt/dotnet && tar zxf dotnet.tar.gz -C /opt/dotnet && \
  ln -s /opt/dotnet/dotnet /usr/local/bin

# Install dependencies.  We start with the basic ones require to build protoc
# and the C++ build
RUN apt-get clean && apt-get update && apt-get install -y --force-yes \
  autoconf \
  autotools-dev \
  build-essential \
  bzip2 \
  ccache \
  curl \
  gcc \
  git \
  libc6 \
  libc6-dbg \
  libc6-dev \
  libgtest-dev \
  libtool \
  make \
  parallel \
  time \
  wget \
  # -- For csharp --
  mono-devel \
  referenceassemblies-pcl \
  nunit \
  # -- For all Java builds -- \
  maven \
  # -- For java_jdk6 -- \
  #   oops! not in jessie. too old? openjdk-6-jdk \
  # -- For java_jdk7 -- \
  openjdk-7-jdk \
  # -- For java_oracle7 -- \
  oracle-java7-installer \
  # -- For python / python_cpp -- \
  python-setuptools \
  python-pip \
  python-dev \
  python2.6-dev \
  python3.3-dev \
  python3.4-dev \
  # -- For Ruby --
  ruby \
  # -- For C++ benchmarks --
  cmake \
  # -- For PHP --
  php5.6     \
  php5.6-dev \
  php5.6-xml \
  php7.0     \
  php7.0-dev \
  php7.0-xml \
  phpunit    \
  valgrind   \
  libxml2-dev \
  && apt-get clean

##################
# C# dependencies

RUN wget www.nuget.org/NuGet.exe -O /usr/local/bin/nuget.exe

##################
# Python dependencies

# These packages exist in apt-get, but their versions are too old, so we have
# to get updates from pip.

RUN pip install pip --upgrade
RUN pip install virtualenv tox yattag

##################
# Ruby dependencies

# Install rvm
RUN gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3
RUN \curl -sSL https://get.rvm.io | bash -s stable

# Install Ruby 2.1, Ruby 2.2 and JRuby 1.7
RUN /bin/bash -l -c "rvm install ruby-2.1"
RUN /bin/bash -l -c "rvm install ruby-2.2"
RUN /bin/bash -l -c "rvm install jruby-1.7"
RUN /bin/bash -l -c "echo 'gem: --no-ri --no-rdoc' > ~/.gemrc"
RUN /bin/bash -l -c "echo 'export PATH=/usr/local/rvm/bin:$PATH' >> ~/.bashrc"
RUN /bin/bash -l -c "gem install bundler --no-ri --no-rdoc"

##################
# Java dependencies

# This step requires compiling protoc. :(

ENV MAVEN_REPO /var/maven_local_repository
ENV MVN mvn --batch-mode

RUN cd /tmp && \
  git clone https://github.com/google/protobuf.git && \
  cd protobuf && \
  git reset --hard 129a6e2aca95dcfb6c3e717d7b9cca1f104fde39 && \
  ./autogen.sh && \
  ./configure && \
  make -j4 && \
  cd java && \
  $MVN install dependency:go-offline -Dmaven.repo.local=$MAVEN_REPO && \
  cd ../javanano && \
  $MVN install dependency:go-offline -Dmaven.repo.local=$MAVEN_REPO

##################
# PHP dependencies.
RUN wget http://am1.php.net/get/php-5.5.38.tar.bz2/from/this/mirror
RUN mv mirror php-5.5.38.tar.bz2
RUN tar -xvf php-5.5.38.tar.bz2
RUN cd php-5.5.38 && ./configure --enable-maintainer-zts --prefix=/usr/local/php-5.5-zts && \
    make && make install && cd ..
RUN cd php-5.5.38 && make clean && ./configure --enable-bcmath --prefix=/usr/local/php-5.5 && \
    make && make install && cd ..

RUN wget http://am1.php.net/get/php-5.6.30.tar.bz2/from/this/mirror
RUN mv mirror php-5.6.30.tar.bz2
RUN tar -xvf php-5.6.30.tar.bz2
RUN cd php-5.6.30 && ./configure --enable-maintainer-zts --prefix=/usr/local/php-5.6-zts && \
    make && make install && cd ..
RUN cd php-5.6.30 && make clean && ./configure --enable-bcmath --prefix=/usr/local/php-5.6 && \
    make && make install && cd ..

RUN wget http://am1.php.net/get/php-7.0.18.tar.bz2/from/this/mirror
RUN mv mirror php-7.0.18.tar.bz2
RUN tar -xvf php-7.0.18.tar.bz2
RUN cd php-7.0.18 && ./configure --enable-maintainer-zts --prefix=/usr/local/php-7.0-zts && \
    make && make install && cd ..
RUN cd php-7.0.18 && make clean && ./configure --enable-bcmath --prefix=/usr/local/php-7.0 && \
    make && make install && cd ..

RUN wget http://am1.php.net/get/php-7.1.4.tar.bz2/from/this/mirror
RUN mv mirror php-7.1.4.tar.bz2
RUN tar -xvf php-7.1.4.tar.bz2
RUN cd php-7.1.4 && ./configure --enable-maintainer-zts --prefix=/usr/local/php-7.1-zts && \
    make && make install && cd ..
RUN cd php-7.1.4 && make clean && ./configure --enable-bcmath --prefix=/usr/local/php-7.1 && \
    make && make install && cd ..

RUN php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
RUN php composer-setup.php
RUN mv composer.phar /usr/bin/composer
RUN php -r "unlink('composer-setup.php');"
RUN composer config -g -- disable-tls true
RUN composer config -g -- secure-http false
RUN cd /tmp && \
  rm -rf protobuf && \
  git clone https://github.com/google/protobuf.git && \
  cd protobuf && \
  git reset --hard 49b44bff2b6257a119f9c6a342d6151c736586b8 && \
  cd php && \
  ln -sfn /usr/local/php-5.5/bin/php /usr/bin/php && \
  ln -sfn /usr/local/php-5.5/bin/php-config /usr/bin/php-config && \
  ln -sfn /usr/local/php-5.5/bin/phpize /usr/bin/phpize && \
  composer install && \
  mv vendor /usr/local/vendor-5.5 && \
  ln -sfn /usr/local/php-5.6/bin/php /usr/bin/php && \
  ln -sfn /usr/local/php-5.6/bin/php-config /usr/bin/php-config && \
  ln -sfn /usr/local/php-5.6/bin/phpize /usr/bin/phpize && \
  composer install && \
  mv vendor /usr/local/vendor-5.6 && \
  ln -sfn /usr/local/php-7.0/bin/php /usr/bin/php && \
  ln -sfn /usr/local/php-7.0/bin/php-config /usr/bin/php-config && \
  ln -sfn /usr/local/php-7.0/bin/phpize /usr/bin/phpize && \
  composer install && \
  mv vendor /usr/local/vendor-7.0 && \
  ln -sfn /usr/local/php-7.1/bin/php /usr/bin/php && \
  ln -sfn /usr/local/php-7.1/bin/php-config /usr/bin/php-config && \
  ln -sfn /usr/local/php-7.1/bin/phpize /usr/bin/phpize && \
  composer install && \
  mv vendor /usr/local/vendor-7.1

##################
# Go dependencies.
RUN apt-get install -y  \
  # -- For go -- \
  golang

##################
# Javascript dependencies.
RUN apt-get install -y \
  # -- For javascript -- \
  npm

##################
# Python 3.5 3.6 dependencies.
RUN apt-get clean && apt-get update && apt-get install -y --force-yes \
  python3.5-dev \
  python3.6-dev \
  && apt-get clean

# On Debian/Ubuntu, nodejs binary is named 'nodejs' because the name 'node'
# is taken by another legacy binary. We don't have that legacy binary and
# npm expects the binary to be named 'node', so we just create a symbol
# link here.
RUN ln -s `which nodejs` /usr/bin/node

##################
# Prepare ccache

RUN ln -s /usr/bin/ccache /usr/local/bin/gcc
RUN ln -s /usr/bin/ccache /usr/local/bin/g++
RUN ln -s /usr/bin/ccache /usr/local/bin/cc
RUN ln -s /usr/bin/ccache /usr/local/bin/c++
RUN ln -s /usr/bin/ccache /usr/local/bin/clang
RUN ln -s /usr/bin/ccache /usr/local/bin/clang++

# Define the default command.
CMD ["bash"]

常见命令解释

FROM 指定镜像源

sh 复制代码
FROM ubuntu
sh 复制代码
# Base Dockerfile for gRPC dev images
FROM debian:latest

网站:http://hub.docker.com

FROM命令是用来指定你需要用哪个镜像作为基础镜像进行构建,一般来说Dockerfile的第一行都会先指定一个镜像,官方仓库中有很多镜像,可以通过http://hub.docker.com进行搜索,建议尽量使用官方镜像作为基础镜像,因为官方镜像都是精简过的稳定版。

RUN 执行linux命令

比如我们需要安装vim

写法1:

sh 复制代码
RUN apt-get update -y
RUN apt-get install -y vim

RUN是用来执行linux命令的指令,例如ubuntu系统下,需要更新软件包list,就需要执行apt-get update,之后会跟着执行apt-get install

写法2:

sh 复制代码
RUN apt-get update -y \
    && apt-get install -y vim

参考例子:

sh 复制代码
# Apt source for old Python versions.
RUN echo 'deb http://ppa.launchpad.net/fkrull/deadsnakes/ubuntu trusty main' > /etc/apt/sources.list.d/deadsnakes.list && \
  apt-key adv --keyserver keyserver.ubuntu.com --recv-keys DB82666C

# Apt source for Oracle Java.
RUN echo 'deb http://ppa.launchpad.net/webupd8team/java/ubuntu trusty main' > /etc/apt/sources.list.d/webupd8team-java-trusty.list && \
  apt-key adv --keyserver keyserver.ubuntu.com --recv-keys EEA14886 && \
  echo "oracle-java7-installer shared/accepted-oracle-license-v1-1 select true" | debconf-set-selections

# Apt source for Mono
RUN echo "deb http://download.mono-project.com/repo/debian wheezy main" | tee /etc/apt/sources.list.d/mono-xamarin.list && \
  echo "deb http://download.mono-project.com/repo/debian wheezy-libjpeg62-compat main" | tee -a /etc/apt/sources.list.d/mono-xamarin.list && \
  apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF

# Apt source for php
RUN echo "deb http://ppa.launchpad.net/ondrej/php/ubuntu trusty main" | tee /etc/apt/sources.list.d/various-php.list && \
  apt-key adv --keyserver keyserver.ubuntu.com --recv-keys F4FCBB07

# Install dotnet SDK based on https://www.microsoft.com/net/core#debian
# (Ubuntu instructions need apt to support https)
RUN apt-get update && apt-get install -y --force-yes curl libunwind8 gettext && \
  curl -sSL -o dotnet.tar.gz https://go.microsoft.com/fwlink/?LinkID=847105 &&  \
  mkdir -p /opt/dotnet && tar zxf dotnet.tar.gz -C /opt/dotnet && \
  ln -s /opt/dotnet/dotnet /usr/local/bin

# Install dependencies.  We start with the basic ones require to build protoc
# and the C++ build
RUN apt-get clean && apt-get update && apt-get install -y --force-yes \
  autoconf \
  autotools-dev \
  build-essential \
  bzip2 \
  ccache \
  curl \
  gcc \
  git \
  libc6 \
  libc6-dbg \
  libc6-dev \
  libgtest-dev \
  libtool \
  make \
  parallel \
  time \
  wget \
  # -- For csharp --
  mono-devel \
  referenceassemblies-pcl \
  nunit \
  # -- For all Java builds -- \
  maven \
  # -- For java_jdk6 -- \
  #   oops! not in jessie. too old? openjdk-6-jdk \
  # -- For java_jdk7 -- \
  openjdk-7-jdk \
  # -- For java_oracle7 -- \
  oracle-java7-installer \
  # -- For python / python_cpp -- \
  python-setuptools \
  python-pip \
  python-dev \
  python2.6-dev \
  python3.3-dev \
  python3.4-dev \
  # -- For Ruby --
  ruby \
  # -- For C++ benchmarks --
  cmake \
  # -- For PHP --
  php5.6     \
  php5.6-dev \
  php5.6-xml \
  php7.0     \
  php7.0-dev \
  php7.0-xml \
  phpunit    \
  valgrind   \
  libxml2-dev \
  && apt-get clean
  
##################
# C# dependencies

RUN wget www.nuget.org/NuGet.exe -O /usr/local/bin/nuget.exe

##################
# Python dependencies

# These packages exist in apt-get, but their versions are too old, so we have
# to get updates from pip.

RUN pip install pip --upgrade
RUN pip install virtualenv tox yattag

##################
# Ruby dependencies

# Install rvm
RUN gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3
RUN \curl -sSL https://get.rvm.io | bash -s stable

# Install Ruby 2.1, Ruby 2.2 and JRuby 1.7
RUN /bin/bash -l -c "rvm install ruby-2.1"
RUN /bin/bash -l -c "rvm install ruby-2.2"
RUN /bin/bash -l -c "rvm install jruby-1.7"
RUN /bin/bash -l -c "echo 'gem: --no-ri --no-rdoc' > ~/.gemrc"
RUN /bin/bash -l -c "echo 'export PATH=/usr/local/rvm/bin:$PATH' >> ~/.bashrc"
RUN /bin/bash -l -c "gem install bundler --no-ri --no-rdoc"

USER 指定当前用户

sh 复制代码
USER root
sh 复制代码
USER username

EXPOSE 暴露端口

声明端口,作用是帮助镜像使用者理解这个镜像服务的守护端口,以方便配置映射。在运行时使用随机端口映射时,也就是 docker run -P时,会自动随机映射EXPOSE的端口。

sh 复制代码
EXPOSE <端口1> [<端口2>...]

在 Dockerfile 中写入这样的声明有两个好处:

  1. 一个是帮助镜像使用者理解这个镜像服务的守护端口,以方便配置映射;
  2. 另一个用处则是在运行时使用随机端口映射时,也就是 docker run -P 时,会自动随机映射 EXPOSE 的端口。
    例子:
sh 复制代码
EXPOSE 端口号
EXPOSE 端口号/协议

默认协议是 TCP

sh 复制代码
EXPOSE 80/tcp
EXPOSE 80/udp
sh 复制代码
FROM nginx
EXPOSE 80

在docker-compose中

通常在docker-compose中,会通过ports来映射并暴露端口,docker-compose用法如下:

sh 复制代码
ports:
    - "8001:80"
相关推荐
Y第五个季节10 小时前
Docker常见命令
docker
爱做梦Di猪11 小时前
openEuler 22.03 LTS Rootless Docker 安装指南
docker·eureka·openeuler
羊狗狗一只2022年11 小时前
x86上编译jetson nano的docker
运维·docker·容器
是魔王哒17 小时前
【终极指南】解决 Windows 11 更新后 Docker 连接 localhost 奇慢(卡顿、超时十几秒)的通用方案
后端·docker
wydxry17 小时前
在断网情况下,网线直接连接 Windows 笔记本和 Ubuntu 服务器进行数据传输
运维·docker·容器
明月与玄武18 小时前
Jenkins+Docker+Git实现自动化CI/CD
git·docker·jenkins·ci/cd流水线
小周学学学19 小时前
docker安装与简单项目上手
运维·docker·容器
小刘|20 小时前
腾讯云服务上下载docker以及使用Rabbitmq的流程
docker·rabbitmq·腾讯云
云途行者20 小时前
使用 docker 安装 openldap
运维·docker·容器
Andy杨1 天前
20250718-1-Kubernetes 应用程序生命周期管理-应用部署、升级、弹性_笔记
linux·docker·容器