Docker-Dockerfile学习

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
简介: Docker-Dockerfile学习

什么是Dockerfile?

Dockerfile简介

Dockerfile 是一个用来构建镜像的文本文件,文本内容包含了一条条构建镜像时所需命令和容器运行时执行的指令和说明。

指令详解

FROM

构建镜像基于哪个镜像

例如,

FROM alpine:latest

MAINTAINER

镜像维护者姓名或邮箱地址,例如

MAINTAINER lady_killer9

WORKDIR

为 RUN、CMD、ENTRYPOINT、COPY 和 ADD 设置工作目录,就是切换目录,没有会自动创建,命令在该目录下执行。进入容器也是进入到此目录。例如,

WORKDIR /app

ADD(不推荐)

拷贝文件或目录到容器中,如果是URL或压缩包便会自动下载或自动解压

COPY(推荐)

拷贝文件或目录到容器中,跟ADD类似,但不具备自动下载或解压的功能。例如,

COPY src/ /app

RUN

构建镜像时运行的指令,例如

RUN pip install requests

CMD

运行容器时执行的命令,如果 Dockerfile 中如果存在多个 CMD 指令,仅最后一个生效

CMD有三种形式

  • CMD [“executable”,“param1”,“param2”] ,json数组
  • CMD command param1 param2,shell形式
  • CMD [“param1”,“param2”] ,作为 ENTRYPOINT的默认参数
    例如,
CMD python3 test.py

注意:CMD命令执行的脚本等需要一直运行,否则创建容器后会很快停止。

ENTRYPOINT

ENTRYPOINT 有两种形式:

  1. ENTRYPOINT [“executable”, “param1”, “param2”] ,json数组
  2. ENTRYPOINT command param1 param2,shell形式
    运行容器时执行,如果 Dockerfile 中如果存在多个 ENTRYPOINT 指令,仅最后一个生效。不会被 docker run 的命令行参数指定的指令所覆盖,而且这些命令行参数会被当作参数送给 ENTRYPOINT 指令指定的程序。
    但是, 如果运行 docker run 时使用了 --entrypoint 选项,将覆盖 ENTRYPOINT 指令指定的程序。
    优点:在执行 docker run 的时候可以指定 ENTRYPOINT 运行所需的参数。
    CMD与ENTRYPOINT的情况(官方文档):

博主总结如下:

  • CMD和ENTRYPOINT至少有一个
  • 仅有一个时就按照这个命令
  • 有两个时,ENTRYPOINT不是json数组形式,则以ENTRYPOINT为准
  • 有两个时,若ENTRYPOINT与CMD都是json数组形式,则ENTRYPOINT与CMD拼接成shell形式

USER

为RUN、CMD、和 ENTRYPOINT 执行命令指定运行用户,一般不指定为root

EXPOSE

声明容器的服务端口

EXPOSE <port> [<port>/<protocol>...]

例如,

EXPOSE 80
EXPOSE 8080/http

之后run的时候可以配合-p参数映射到宿主机上

ENV

设置容器环境变量

ENV <key>=<value> ...

例如,

ENV JAVA_HOME=/home/myuser/jdk1.7.0_03

VOLUME

定义匿名数据卷。在启动容器时忘记挂载数据卷,会自动挂载到匿名卷。

作用:

  • 避免重要的数据,因容器重启而丢失,这是非常致命的。
  • 避免容器不断变大。
VOLUME ["<路径1>", "<路径2>"...]
VOLUME <路径>

例如,

VOLUME /var/log/nginx

Docker 命令

之前的文章Docker命令学习已经讲解了部分命令,但是构建等命令没有提及。

docker build

用于使用 Dockerfile 创建镜像。

docker build [OPTIONS] PATH | URL | -

OPTIONS说明:

  • –build-arg=[] :设置镜像创建时的变量;
  • –cpu-shares :设置 cpu 使用权重;
  • –cpu-period :限制 CPU CFS周期;
  • –cpu-quota :限制 CPU CFS配额;
  • –cpuset-cpus :指定使用的CPU id;
  • –cpuset-mems :指定使用的内存 id;
  • –disable-content-trust :忽略校验,默认开启;
  • -f :指定要使用的Dockerfile路径;
  • –force-rm :设置镜像过程中删除中间容器;
  • –isolation :使用容器隔离技术;
  • –label=[] :设置镜像使用的元数据;
  • -m :设置内存最大值;
  • –memory-swap :设置Swap的最大值为内存+swap,"-1"表示不限swap;
  • –no-cache :创建镜像的过程不使用缓存;
  • –pull :尝试去更新镜像的新版本;
  • –quiet, -q :安静模式,成功后只输出镜像 ID;
  • –rm :设置镜像成功后删除中间容器;
  • –shm-size :设置/dev/shm的大小,默认值是64M;
  • –ulimit :Ulimit配置。
  • –squash :将 Dockerfile 中所有的操作压缩为一层。
  • –tag, -t: 镜像的名字及标签,通常 name:tag 或者 name 格式;可以在一次构建中为一个镜像设置多个标签。
  • –network: 默认 default。在构建期间设置RUN指令的网络模式

一般都是把Dockerfile放到项目里面,例如

docker build -t myapp:v1.0 .

docker commit

从容器创建一个新的镜像。

docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]

OPTIONS说明:

  • -a :提交的镜像作者;
  • -c :使用Dockerfile指令来创建镜像;
  • -m :提交时的说明文字;
  • -p :在commit时,将容器暂停。

docker save

将镜像输出到一个文件。

docker save [OPTIONS] IMAGE [IMAGE...]

OPTIONS 说明:

  • -o :输出到的文件。

例如,

docker save -o myapp_v1.0.tar myapp:v1.0

docker load

从一个文件加载镜像

docker load [OPTIONS]

OPTIONS 说明:

  • –input , -i : 指定导入的文件,代替 STDIN。
  • –quiet , -q : 精简输出信息。

例如,

docker load -i myapp_v1.0.tar

Dockerfile举例

mysql debian

#
# NOTE: THIS DOCKERFILE IS GENERATED VIA "apply-templates.sh"
#
# PLEASE DO NOT EDIT IT DIRECTLY.
#
FROM debian:buster-slim
# add our user and group first to make sure their IDs get assigned consistently, regardless of whatever dependencies get added
RUN groupadd -r mysql && useradd -r -g mysql mysql
RUN apt-get update && apt-get install -y --no-install-recommends gnupg dirmngr && rm -rf /var/lib/apt/lists/*
# add gosu for easy step-down from root
# https://github.com/tianon/gosu/releases
ENV GOSU_VERSION 1.14
RUN set -eux; \
  savedAptMark="$(apt-mark showmanual)"; \
  apt-get update; \
  apt-get install -y --no-install-recommends ca-certificates wget; \
  rm -rf /var/lib/apt/lists/*; \
  dpkgArch="$(dpkg --print-architecture | awk -F- '{ print $NF }')"; \
  wget -O /usr/local/bin/gosu "https://github.com/tianon/gosu/releases/download/$GOSU_VERSION/gosu-$dpkgArch"; \
  wget -O /usr/local/bin/gosu.asc "https://github.com/tianon/gosu/releases/download/$GOSU_VERSION/gosu-$dpkgArch.asc"; \
  export GNUPGHOME="$(mktemp -d)"; \
  gpg --batch --keyserver hkps://keys.openpgp.org --recv-keys B42F6819007F00F88E364FD4036A9C25BF357DD4; \
  gpg --batch --verify /usr/local/bin/gosu.asc /usr/local/bin/gosu; \
  gpgconf --kill all; \
  rm -rf "$GNUPGHOME" /usr/local/bin/gosu.asc; \
  apt-mark auto '.*' > /dev/null; \
  [ -z "$savedAptMark" ] || apt-mark manual $savedAptMark > /dev/null; \
  apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false; \
  chmod +x /usr/local/bin/gosu; \
  gosu --version; \
  gosu nobody true
RUN mkdir /docker-entrypoint-initdb.d
RUN set -eux; \
  apt-get update; \
  apt-get install -y --no-install-recommends \
    openssl \
# FATAL ERROR: please install the following Perl modules before executing /usr/local/mysql/scripts/mysql_install_db:
# File::Basename
# File::Copy
# Sys::Hostname
# Data::Dumper
    perl \
    xz-utils \
    zstd \
  ; \
  rm -rf /var/lib/apt/lists/*
RUN set -eux; \
# gpg: key 3A79BD29: public key "MySQL Release Engineering <mysql-build@oss.oracle.com>" imported
  key='859BE8D7C586F538430B19C2467B942D3A79BD29'; \
  export GNUPGHOME="$(mktemp -d)"; \
  gpg --batch --keyserver keyserver.ubuntu.com --recv-keys "$key"; \
  mkdir -p /etc/apt/keyrings; \
  gpg --batch --export "$key" > /etc/apt/keyrings/mysql.gpg; \
  gpgconf --kill all; \
  rm -rf "$GNUPGHOME"
ENV MYSQL_MAJOR 5.7
ENV MYSQL_VERSION 5.7.37-1debian10
RUN echo 'deb [ signed-by=/etc/apt/keyrings/mysql.gpg ] http://repo.mysql.com/apt/debian/ buster mysql-5.7' > /etc/apt/sources.list.d/mysql.list
# the "/var/lib/mysql" stuff here is because the mysql-server postinst doesn't have an explicit way to disable the mysql_install_db codepath besides having a database already "configured" (ie, stuff in /var/lib/mysql/mysql)
# also, we set debconf keys to make APT a little quieter
RUN { \
    echo mysql-community-server mysql-community-server/data-dir select ''; \
    echo mysql-community-server mysql-community-server/root-pass password ''; \
    echo mysql-community-server mysql-community-server/re-root-pass password ''; \
    echo mysql-community-server mysql-community-server/remove-test-db select false; \
  } | debconf-set-selections \
  && apt-get update \
  && apt-get install -y \
    mysql-server="${MYSQL_VERSION}" \
# comment out a few problematic configuration values
  && find /etc/mysql/ -name '*.cnf' -print0 \
    | xargs -0 grep -lZE '^(bind-address|log)' \
    | xargs -rt -0 sed -Ei 's/^(bind-address|log)/#&/' \
# don't reverse lookup hostnames, they are usually another container
  && echo '[mysqld]\nskip-host-cache\nskip-name-resolve' > /etc/mysql/conf.d/docker.cnf \
  && rm -rf /var/lib/apt/lists/* \
  && rm -rf /var/lib/mysql && mkdir -p /var/lib/mysql /var/run/mysqld \
  && chown -R mysql:mysql /var/lib/mysql /var/run/mysqld \
# ensure that /var/run/mysqld (used for socket and lock files) is writable regardless of the UID our mysqld instance ends up having at runtime
  && chmod 1777 /var/run/mysqld /var/lib/mysql
VOLUME /var/lib/mysql
COPY docker-entrypoint.sh /usr/local/bin/
RUN ln -s usr/local/bin/docker-entrypoint.sh /entrypoint.sh # backwards compat
ENTRYPOINT ["docker-entrypoint.sh"]
EXPOSE 3306 33060
CMD ["mysqld"]

这是mysql的官方Dockerfile,基于debian:buster-slim镜像,执行了一些命令,添加了环境变量GOSU_VERSION、MYSQL_VERSION 等,添加了匿名挂载卷/var/lib/mysql,复制了docker-entrypoint.sh脚本到 /usr/local/bin/下,运行脚本,暴露端口3306和33060。

参考

菜鸟教程-Docker Dockerfile

Docker如何制作镜像-Dockerfile的使用

docker官方文档-docker命令

docker官方文档-dockerfile

Github-mysql-5.7-dockerfile-debian

相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
6月前
|
运维 虚拟化 开发者
Docker-全面详解(学习总结---从入门到深化)
Docker-全面详解(学习总结---从入门到深化)
108 1
|
6月前
|
分布式计算 Java Linux
【深入浅出Docker原理及实战】「原理实战体系」零基础+全方位带你学习探索Docker容器开发实战指南(Dockerfile使用手册)
Docker 是一套构建在 Linux 内核之上的高级工具,旨在帮助开发人员和运维人员更轻松地交付应用程序和依赖关系,实现跨系统和跨主机的部署。使用安全且轻量级的容器环境来实现这一目标。容器可以手动创建,也可以通过编写 Dockerfile 自动创建。开发人员和运维人员可以将应用程序及其依赖打包到容器中,实现应用程序的可移植性和环境一致性。
253 5
【深入浅出Docker原理及实战】「原理实战体系」零基础+全方位带你学习探索Docker容器开发实战指南(Dockerfile使用手册)
|
23天前
|
存储 Ubuntu Linux
学习docker
学习docker
26 1
|
24天前
|
NoSQL Linux Redis
Docker学习二(Centos):Docker安装并运行redis(成功运行)
这篇文章介绍了在CentOS系统上使用Docker安装并运行Redis数据库的详细步骤,包括拉取Redis镜像、创建挂载目录、下载配置文件、修改配置以及使用Docker命令运行Redis容器,并检查运行状态和使用Navicat连接Redis。
172 3
|
27天前
|
运维 Kubernetes 开发者
Docker Swarm学习
【10月更文挑战第5天】
33 3
|
1月前
|
Kubernetes Linux 持续交付
docker容器学习
【10月更文挑战第1天】
32 1
|
2月前
|
存储 Ubuntu Docker
Docker学习
Docker学习
59 4
|
1月前
|
Linux 应用服务中间件 Shell
docker学习--docker容器镜像常用命令大全(简)
本文档详细介绍了Docker中的镜像命令与容器管理命令。镜像命令部分涵盖了镜像搜索、下载、上传等操作;容器管理命令则包括了容器的创建、启动、停止、删除及日志查看等功能。通过具体示例,帮助用户更好地理解和使用Docker相关命令。
131 0
|
1月前
|
Shell 应用服务中间件 nginx
docker学习--最详细的docker run 各子命令解释与应用
`docker run` 是 Docker 中用于启动容器的基本命令。常用子命令包括 `-i`(交互模式)、`-t`(分配终端)、`-d`(后台运行)、`-p`(端口映射)、`--name`(指定容器名)。例如,`docker run -it nginx:1.20 /bin/bash` 可以创建并进入交互式容器。使用 `-d` 可在后台运行容器,`-p` 可将容器端口映射到主机端口,`--name` 则用于自定义容器名称以便管理。
100 0
|
3月前
|
网络协议 Shell Docker
docker 学习之路
docker 学习之路
34 1