Dockerfile / 官方镜像仓库

  • Dockerfile 主要命令
  • 官方镜像仓库的使用
  • Dockerfile编写
  • 基于 Alpine的 JRE 和 Tomcat 的镜像制作与运行
  • MySQL 5.7.22 镜像制作与运行

Dockerfile 主要命令


  ADD     ARG    CMD              COPY    ENTRYPOINT     ENV

  EXPOSE     FROM    HEALTHCHECK      LABEL   MAINTAINER(弃用)    ONBUILD

  RUN      SHELL      STOPSIGNAL     USER     VOLUME       WORKDIR

  • ADD 命令
    • 有两个参数, 源和目标, 它的基本作用是从源系统的文件系统上复制文件到目标容器的文件系统, 如果源是一个 URL, 那该 URL 的内容将被下载并复制到容器中;
    • 如 ADD run.sh /
  • ARG 命令(一般不使用)
    • 设置变量, ARG命令定义了一个变量, 在 docker build 创建镜像的时候, 使用  --build-arg <varname>=<value> 来指定参数;
    • 如果用户在 build 镜像时指定了一个参数没有定义在 Dockerfile 中, 那么将有一个 Warning;
  • CMD
    • 和 RUN 命令相似, CMD 可以用于执行特定的命令, 和 RUN 不同的是, 这些命令不是在构建镜像的过程中执行的, 而是在用镜像启动容器后被调用的;
    • 如 CMD "command" "arg1" "arg2"
  • COPY
    • 复制文件到镜像
    • COPY <src> <dst>
    • src 只能是与 Dockerfile 同级的本地文件
    • 如:  COPY run.sh /
  • ENTRYPOINT
    • 配置一个容器使之可执行化, 如果结合 CMD 命令和 ENTRYPOINT 命令, 可以从 CMD 命令中移除 "application" 而仅仅保留参数, 参数将传递给 ENTRYPOINT 命令;
    • 如:  ENTRYPOINT ["/run.sh","arg1","arg2"]
  • ENV
    • 用于设置环境变量, 这些变量以 "key=value" 的形式存在, 在 Dockerfile 中其它命令里可以直接引用, 并可以在容器内被脚本或者程序调用;
    • 如:
      • ENV version=1.2.5
      • ENV release 1.0.1
  • EXPOSE
    • 用来指定容器内端口映射到外部,使容器内的应用可以通过端口和外界交互;
    • 如: EXPOSE 8080
  • FROM -- 一般是在Dockerfile中不算注释的第一行
    • 指定基础镜像
    • 如: FROM cenos:7
  • HEALTHCHECK
    • 容器健康检查命令, 但是容器一般使用的是编排工具的健康检查, 这个使用的别较少;
    • 语法两种
      • HEALTHCHECK [OPTIONS] CMD command
      • HEALTHCHECK NONE
    • 第一个的功能是在容器内部运行一个命令来检查容器的健康状况;
    • 第二个的功能是在基础镜像中取消健康检查命令
  • LABEL
    • 为镜像定义标签信息
    • 如: LABEL job.name="Tian" maintainer="TianFei tzhr@xxx.com"
  • MAINTAINER
    • 用于声明镜像维护者的信息
    • 如: MAINTAINER Tian Fei <tzhr@xxx.com>
    • 已弃用, 使用 LABEL 代替
      • LABEL maintainer="TianFei tzhr@xxx.com"
  • ONBUILD <使用的比较少>
    • 只对基于 (FROM) 当前镜像的镜像生效
  • RUN
    • Dockerfile执行 shell 命令的核心部分, 它接受命令作为参数并用于创建镜像, 不像 CMD 命令, RUN 命令作用于创建镜像过程中;
    • 多条命令以 "&" 或 ";" 结合
    • 如:  RUN yum update -y &&
               yum -y install vim
  • SHELL
    • 指定 shell , 影响后面的:
      • RUN
      • CMD
      • ENTRYPOINT
    • SHELL ["command", "parameters"]
  • STOPSIGNAL
    • 当容器退出时, 给系统发送什么样的指令
  • USER
    • 用于设置运行容器的用户和组
    • 如:
      • USER www.www
      • USER admin
      • USER 1000
  • VOLUME
    • 创建一个可以从本地主机或其他容器挂载的挂载点, 一般用来存放数据库等各种需要持久化的数据;
    • 如: VOLUME ["/data"]
  • WORKDIR
    • 用于设置CMD指明的命令的运行目录
    • 如 WORKDIR /tmp

官方镜像仓库的使用


     官方镜像仓库的地址: https:hub.docker.com

     没有登录信息的话,点击 Sign up for Docker Hub ;自己进行注册; 注册成功或已经有账户, 直接使用Sign in 登录;

     搜索到需要的镜像,可以看到生成镜像时的 Dockerfile 文件;

     可以点击 Create a Repositort 或者 点击 Repositories 后 点击 create Repository 进行创建仓库, 例: 仓库名为 httpd

       创建完成后, 有如何使用的介绍; 如何进行推送; 或者 命令行中创建 仓库;

       OFFICIAL IMAGE 为官方的镜像;

     使用命令行查看镜像 docker search 镜像:[tags];

     Docker 登录  docker login -u tzhr -p xxx ,会提示这样使用不安全; 或者 docker login -u tzhr 直接回车,再按提示输入密码;  登录私有仓库 docker login -u tzhr -p xxxx 私有地址

     登录后才能上传镜像;tzhr 为登录用户名;

    给镜像打标签, 然后推送镜像

[root@localhost ~]# docker tag tian/httpd:v.2.0 tzhr/httpd:v.1.0
[root@localhost ~]# docker push tzhr/httpd:v.1.0
The push refers to repository [docker.io/tzhr/httpd]
48ecba369a69: Pushed 
0b97b1c81a32: Pushed 
v.1.0: digest: sha256:2eb0d2b7ea219fccf26550f45d6f1b5f6706813ac39041f7548381b3e48d95f1 size: 734

      查看docker hub中登录后已经上传 tzhr/httpd:v.1.0

Dockerfile编写


// 创建存放 Dockerfile 及文件的 目录
mkdir -p /data/centos/7 && cd /data/centos/7

//编写Dockerfile, RUN 更改时区,从 清华镜像网站下载 epel 源; 升级; 安装 vim ; 清理缓存.
vim Dockerfile
FROM docker.io/library/centos:7

LABEL maintainer="TianFei tzhr1225@xxx.com"

RUN ln -sfv /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && 
    rpm -ivh https://mirrors.tuna.tsinghua.edu.cn/centos/7/extras/x86_64/drpms/epel-release-7-6_7-9.noarc
h.drpm && 
    yum update -y && 
    yum -y install vim && 
    yum clean all

// 保存退出, 构建镜像
[root@localhost 7]# docker build -t zxjr/centos:7 ./

// 运行容器, 查看已安装 vim
[root@localhost 7]# docker run --name C7 --rm -it zxjr/centos:7
[root@70f88d49d901 /]# vim
// 创建 alpine , 最新版本 3.9
[root@localhost ~]# mkdir -pv /alpine/3.9
mkdir: created directory ‘/alpine’
mkdir: created directory ‘/alpine/3.9’
[root@localhost ~]# cd /alpine/3.9

// 编写 Dockerfile, 使用 alpine:3.9 镜像, alpine中没有 localtime 文件, 使用本地的通过 COPY 复制到alpine中, 定义路径地址变量为清华大学镜像地址; RUN中通过 echo 调用变量写入 /etc/apk/repositories 文件中(相当于/etc/yum.repos); apk update 更新缓存; apk upgrade 更新系统; apk add curl 添加 curl;
[root@localhost 3.9]# vim Dockerfile

# Description alpine 3.9
FROM alpine:3.9

COPY localtime /etc/

ENV REPO_ADDR="https://mirrors.tuna.tsinghua.edu.cn/alpine/v3.9"

RUN echo -e "$REPO_ADDR/main
$REPO_ADDR/community" > /etc/apk/repositories && 
    apk update && 
    apk upgrade && 
    apk add curl

// 在/alpine/3.9 目录中生成 localtime 文件
[root@localhost 3.9]# cp /usr/share/zoneinfo/Asia/Shanghai ./localtime

// 构建镜像
[root@localhost 3.9]# docker build -t tzhr/alpine:3.9 ./

// 使用新的镜像运行容器, 交互式验证; alpine镜像没有 bash , 所以需要指定 /bin/sh
[root@localhost 3.9]# docker run --name A110 --rm -it tzhr/alpine:3.9 /bin/sh
/ # curl www.baidu.com                      // 安装curl成功
<!DOCTYPE html>
/ # apk search bash                           // 查看可以安装的包
/ # apk add bash                                // 安装 bash
(1/5) Installing ncurses-terminfo-base (6.1_p20190105-r0)
(2/5) Installing ncurses-terminfo (6.1_p20190105-r0)
(3/5) Installing ncurses-libs (6.1_p20190105-r0)
(4/5) Installing readline (7.0.003-r1)
(5/5) Installing bash (4.4.19-r1)
Executing bash-4.4.19-r1.post-install
Executing busybox-1.29.3-r10.trigger
OK: 16 MiB in 24 packages              // 表示容器多大, 安装了多少个包
/ # apk del bash                                 // 卸载
OK: 7 MiB in 19 packages

// 安装上bash 后, 可以不指定/bin/sh 进行登录
[root@localhost 3.9]# docker run --name A110 --rm -it tzhr/alpine:3.9
/ #

基于 Alpine的 JRE 和 Tomcat 的镜像制作与运行


// 需要安装 jre 环境,, 首先启动alpine容器查看一下 jre 版本;
[root@localhost ~]# docker run --name A0 --rm -it alpine:3.9 /bin/sh
/ # apk update
/ # apk upgrade
/ # apk search jre
openjdk7-jre-7.211.2.6.17-r0
jreen-dev-1.3.0-r0
openjdk7-jre-lib-7.211.2.6.17-r0
texlive-20170524-r6
openjdk8-jre-base-8.212.04-r0
jreen-1.3.0-r0
openjdk8-jre-lib-8.212.04-r0
openjdk7-jre-base-7.211.2.6.17-r0
openjdk8-jre-8.212.04-r0

// 创建镜像目录并进入
[root@localhost ~]# mkdir -p /data/alpine/tomcat/
[root@localhost ~]# cd /data/alpine/tomcat/

// 编写 Dockerfile, 使用openjdk8-jre; 通过清华镜像网站下载tomcat包
[root@localhost tomcat]# vim Dockerfile

FROM alpine:3.9

LABEL maintainer="TianFei tzhr1225@xxx.com"

RUN apk update && 
    apk upgrade && 
    apk add curl openjdk8-jre && 
    curl -Ljk https://mirrors.tuna.tsinghua.edu.cn/apache/tomcat/tomcat-9/v9.0.21/bin/apache-tomcat-9.0.21.tar.gz | tar zxf - && 
    mv apache-tomcat-9.0.21 /usr/local/tomcat

CMD ["/usr/local/tomcat/bin/catalina.sh","run"]

// 构建镜像,这样只有85MiB, 如何使用centos的话, 加上jre和tomcat得200多兆;
[root@localhost tomcat]# docker build -t tzhr/tomcat:v.1.0 .
... ...
OK: 85 MiB in 57 packages
... ...

// 使用镜像后台运行容器,
[root@localhost tomcat]# docker run -d tzhr/tomcat:v.1.0
fda814531df36ddf33bdfa6045bee7683e35f721faaaee42ab0ac31cc3924842
[root@localhost tomcat]# docker ps -a |grep tomcat
fda814531df3        tzhr/tomcat:v.1.0   "/usr/local/tomcat/b…"   6 seconds ago       Up 5 seconds                                    quizzical_shaw

// 查看容器信息,获取IP地址
[root@localhost tomcat]# docker container inspect fda814531df3
... ...
            "Networks": {
                "bridge": {
                    "IPAMConfig": null,
                    "Links": null,
                    "Aliases": null,
                    "NetworkID": "dd54f129406eb1e595af66fc0abe6a6b1cba8d0c69bff35a4a1eba549e3fb820",
                    "EndpointID": "e58fe4263092664dbbe7db8a7713ab9a58769b8f8eeb75815cb2f40c1b718424",
                    "Gateway": "172.17.0.1",
                    "IPAddress": "172.17.0.6",
... ...

// 访问 IP:8080 端口
[root@localhost tomcat]# curl -I 172.17.0.6:8080
HTTP/1.1 200 
Content-Type: text/html;charset=UTF-8
Transfer-Encoding: chunked
Date: Wed, 26 Jun 2019 03:11:27 GMT

MySQL 5.7.22 镜像制作与运行


 在相应的目录中创建 Dockerfile ,init-db.sh(初始化数据库的脚本) , run.sh(启动mysql的脚本) 三个文件;

// 创建并进入目录
[root@localhost ~]# mkdir -p /data/mysql/
[root@localhost ~]# cd /data/mysql/

// 编写生成 Dockerfile 文件
[root@localhost mysql]# vim Dockerfile 


FROM centos:7                       // 基层调用 centos:7 镜像

ENV MYSQL_VERSION="5.7.22-1"        // 定义 mysql 版本变量

COPY run.sh /                       // 复制 run.sh 脚本到镜像中
COPY init-db.sh /                   // 复制 init-db.sh脚本

RUN yum update -y &&               // 更新系统
    yum install -y libaio-devel numactl-libs net-tools perl perl-Data-Dumper-Names perl-Data-Dumper perl-DBI &&          // 安装基础包
    yum clean all &&               // 清空 yum 缓存
    for pkg in common libs devel client server;                     // for 循环,安装mysql的rpm 包, 从清华镜像网站安装;
    do rpm -ivh https://mirrors.tuna.tsinghua.edu.cn/mysql/yum/mysql57-community-el7/mysql-community-$pkg-$MYSQL_VERSION.el7.x86_64.rpm; done && 
    chmod 755 /run.sh /init-db.sh && rm -rf /var/lib/mysql           // 给 run.sh 及 init-db.sh 脚本可执行权限, 删除 mysql 的数据存储目录

ENTRYPOINT ["/run.sh"]              // 启动容器后运行run.sh脚本
// 编写 mysql 初始化脚本 init-db.sh
[root@localhost mysql]# vim init-db.sh 

#!/bin/bash

# -------------------------------
# - Create by Tian, 2019.06.26  -
# -       I'm tzhr1225@xxx.com  -
# -------------------------------

# The passwd for mysql
M_P="Zxjr@tian"                             // 定义mysql的密码变量

DBDIR="/var/lib/mysql"                      // 定义存储目录

test -d "$DBDIR/mysql" || mysqld --initialize               // 测试有没有mysql库, 没有的话进行初始化, 5.7 以前使用mysql_install_db;
chown -R mysql:mysql $DBDIR                 // 改MySQL存储目录的属主属组为 mysql;

echo "Start MySQL Server"
su - mysql -s /bin/bash -c "mysqld &"       // 切换到 mysql 用户,启动MySQL;

echo "Wait 5 seconds for MySQL start"
sleep 5              // 等待 5 秒钟;

echo "Set password for root(default is :$M_P)"
mysqladmin -u root password $M_P            // 修改数据库 root 用户的密码

echo "Update privilege for root"
mysql -u root -p$M_P -e "grant all on *.* to root@'%' identified by '$M_P' with grant option;"         // 授权,所有的地址可登录

# Stop MySQL Server & Start MySQL Server
PID=`ps aux |grep "[m]yslq" |awk '{print $2}'`    // 定义PID变量
kill -9 $PID                                      // 杀掉mysql进程;
// 编写 MySQL 的启动脚本 run.sh
[root@localhost mysql]# vim run.sh 

#!/bin/bash

# -------------------------------------
# - Create by statemood, 2019.06.26   -
# -           I'm tzhr1225@xxx.com    -
# -------------------------------------

if [ -z "$@" ]                                  // $@ 表示脚本后面的参数, -z判断为空时; $# 参数的数量
then
    if [ ! -z "$MYSQL_CONFIG_FILE" ]            // MySQL配置文件变量不为空时
    then
        test -f $MYSQL_CONFIG_FILE && cp -fv $MYSQL_CONFIG_FILE /etc/my.cnf               // 配置文件不为空时, 复制生成my.cnf
    fi

    DIR="/var/lib/mysql/mysql"                  // 定义存储目录变量;

    test -d "$DIR" && chown -R mysql:mysql $(dirname $DIR) || /init-db.sh                // 测试存储目录存在, 给定义的目录上一层目录修改属主属组为mysql, 否则执行初始化脚本;
    mysqld --user=mysql                         // 指定用户启动mysql
else
    "$@"
fi
原文地址:https://www.cnblogs.com/haorong/p/11076209.html