我们手写一枚Redis镜像Dockerfile,来理解与实践CMD与ENTRYPOINT。

 1#  Dockerfile - Redis 5.0.5
 2# ================================
 3# Using Base OS -> CentOS 7 Latest
 4# ================================
 5FROM  centos:latest
 6# =============================================
 7# LABEL following the standard set of labels by
 8# The Open Containers Initiative (OCI)
 9# =============================================
10LABEL      org.opencontainers.image.title="DockerImage - Redis" \
11           org.opencontainers.image.version="1.0.0" \
12           org.opencontainers.image.licenses="MIT" \
13# ==============================================================
14RUN        PKG_BASE_DEPS="epel-release \
15                          make \
16                          gcc \
17                          gcc-c++" && \
18           REDIS_PKG_PATH="/root/redis-5.0.5.tar.gz" && \
19           REDIS_PKG_ROOT="/root/redis-5.0.5/" && \
20           REDIS_PKG_INSTALLED="/opt/redis_5.0.5/" && \
21           REDIS_PKG_URL="http://download.redis.io/releases/redis-5.0.5.tar.gz" && \
22           cp "/usr/share/zoneinfo/Asia/Shanghai" "/etc/localtime" && \
23           echo "Asia/Shanghai" > "/etc/timezone" && \
24           yum -y install "epel-release" && \
25           yum -y install ${PKG_BASE_DEPS} && \
26           curl -o ${REDIS_PKG_PATH} ${REDIS_PKG_URL} && \
27           cd "/root/" && \
28           tar -xvz -f ${REDIS_PKG_PATH} && \
29           cd ${REDIS_PKG_ROOT} && \
30           make V=1 && \
31           make PREFIX=${REDIS_PKG_INSTALLED} install && \
32           rm -rf ${REDIS_PKG_ROOT} ${REDIS_PKG_PATH} && \
33           yum -y autoremove ${PKG_BASE_DEPS} && \
34           yum clean all
35# ======================================
36WORKDIR    /root/
37# ======================================
38# Using a Docker `entrypoint.sh` and CMD
39# ======================================
40COPY ./entrypoint.sh /root/
41ENTRYPOINT ["sh", "/root/entrypoint.sh"]
42CMD ["redis-cli"]

这里,我们使用一枚启动脚本entrypoint.sh作为容器入口点ENTRYPOINT,该脚本接受命令行参数并执行相应的命令。使用CMD指令为启动脚本提供默认参数redis-cli。

 1#!/bin/bash
 2# -------------------------------
 3set -e
 4# -------------------------------
 5REDIS_FLAG=false
 6REDIS_PATH='/opt/redis_5.0.5/bin'
 7REDIS_COMMANDS="redis-cli \
 8                redis-server"
 9# -------------------------------
10for redis_cmd in ${REDIS_COMMANDS}
11do
12    if [[ ${1} == ${redis_cmd} ]]
13    then
14        REDIS_FLAG=true
15    fi
16done
17# -------------------------------
18if [[ ${REDIS_FLAG} == true ]]
19then
20    ${REDIS_PATH}/${@}
21else
22    echo '[ERROR]: No such Redis command...'
23    exit 1
24fi

使用docker build构建起Redis镜像后,可在docker run后附加容器需执行的Redis命令及其参数。

 1#!/bin/bash
 2# ------------------------------
 3REDIS_COMMAND="redis-server"
 4REDIS_OPTIONS="--loglevel verbose \
 5               --bind 0.0.0.0 \
 6               --port 6379 \
 7               --requirepass foobar123 \
 8               --maxclients 10000 \
 9               --timeout 0 \
10               --tcp-keepalive 300 \
11               --daemonize no \
12               --supervised no \
13               --pidfile none \
14               --databases 32 \
15               --always-show-logo yes \
16               --appendonly no \
17               --appendfsync no"
18# ------------------------------
19sudo docker run -d -i -t \
20                --env LC_ALL=en_US.UTF-8 \
21                --name redis_test \
22                -p 0.0.0.0:6379:6379 \
23                yunwei/redis:latest \
24                ${REDIS_COMMAND} ${REDIS_OPTIONS}