Dockerfile for Docker containerized deployment practice

In the previous two articles, Docker containerized deployment practice-introduction , Docker containerized deployment practice Docker Compose , I talked about the use of Docker commonly used commands, and Docker containerized orchestration through the docker-compose.yml file.

Among them, we basically pull images directly by Docker pull. If we use some basic components, it is of course very convenient to directly pull the official, such as nginx, redis, mongo, etc.

But our application service will basically do some construction operations, do some customization operations, and install some specific packages we need. So today we will talk about Docker image production, and use Dockerfile to build the image.

one example

For a better understanding, we will use  hub.docker.com the official redis as an example to explain. Please see the back of the command for comments.

FROM debian:stretch-slim  # 基于debian进行安装
RUN groupadd -r redis && useradd -r -g redis redis # 执行命令,创建用户组
ENV GOSU_VERSION 1.10 # 设置环境变量 gosu 类sudo工具
RUN set -ex; \
    \
    fetchDeps=" \
        ca-certificates \
        dirmngr \
        gnupg \
        wget \
    "; \
    apt-get update; \
    apt-get install -y --no-install-recommends $fetchDeps; \
    # 省略部分命令
ENV REDIS_VERSION 5.0.1
ENV REDIS_DOWNLOAD_URL http://download.redis.io/releases/redis-5.0.1.tar.gz
ENV REDIS_DOWNLOAD_SHA 82a67c0eec97f9ad379384c30ec391b269e17a3e4596393c808f02db7595abcb

# for redis-sentinel see: http://redis.io/topics/sentinel
RUN set -ex; \
    \
    buildDeps=' \
        ca-certificates \
        wget \
        \
        gcc \
        libc6-dev \
        make \
    '; \
    apt-get update; \
    apt-get install -y $buildDeps --no-install-recommends; \
    # 省略部分命令
RUN mkdir /data && chown redis:redis /data
VOLUME /data  # 挂载匿名卷,避免容器存储层会发生写操作。
WORKDIR /data # 指定工作路径避免 RUN cd .. && do things

COPY docker-entrypoint.sh /usr/local/bin# 复制源文件sh到目标bin目录,文件权限保持不变
ENTRYPOINT ["docker-entrypoint.sh"# 配置容器启动时运行的命令

EXPOSE 6379  # 声明需要监听的端口
CMD ["redis-server"]  # 设置镜像的启动命令

The difference between ENTRYPOINT and CMD is that it ENTRYPOINTis the main command that provides the image, allowing the image to be run as the command itself. Here it is used in conjunction with the auxiliary script docker-entrypoint.sh to CMD provide the command default options. The docker-entrypoint.sh file and the Dockerfile directory are at the same level. Below is the docker-entrypoint.sh file.

# docker-entrypoint.sh
#!/bin/sh
set -e

# first arg is `-f` or `--some-option`
# or first arg is `something.conf`
if [ "${1#-}" != "$1" ] || [ "${1%.conf}" != "$1" ]; then
    set -- redis-server "$@"
fi

# allow the container to be started with `--user`
if [ "$1" = 'redis-server' -a "$(id -u)" = '0' ]; then
    find . \! -user redis -exec chown redis '{}' +
    exec gosu redis "$0" "$@"
fi
exec "$@"

If we want to add our own configuration file, we can add Dockerfile and corresponding redis.conf file based on official redis .

# Dockerfile
FROM redis
COPY redis.conf /usr/local/etc/redis/redis.conf
CMD [ "redis-server""/usr/local/etc/redis/redis.conf" ] # 后面配置文件是命令对应的参数。

上面的Dockerfile文件声明了镜像的基础镜像,记录着镜像的步骤命令,编写好上面的Dockerfile文件之后,我们使用docker build 命令就可以生成新镜像。

打包镜像要注意

  1. 精简镜像:尽量让每个镜像的用途都比较集中、单一;

  2. 避免不必要的包,比如编辑器

  3. 推荐使用 alpine 只有5MB 或者 debian等小巧镜像。

  4. 使用明确的版本号信息,而非latest,避免一些意外情况。

  5. 减少镜像层数,尽量合并指令,例如多个RUN指令可以合并为一条;

  6. 提高构建镜像速度,在目录下新建一个 .dockerignore 文件来指定要忽略的文件和目录同.gitignore.

另外如果我们没有使用自己构建的镜像,一定要注意第三方镜像的安全性,尽可能从官方维护拉取。因为Docker通过命名空间进行隔离,容器中的应用可以访问系统内核和部分系统文件。如果容器中应用是不可信的,会影响到本地系统。

最后官方提供了编写Dockerfile的最佳实践,感兴趣的同学强烈建议你点击原文进行查看。今天我们就分享到这儿,有问题欢迎交流。

容器化部署实践,我打算从基础操作到实战应用以一个系列进行分享,今天是第三篇Dockerfile 镜像构建,后期我将持续分享更多相关内容,从容器化入门使用到部署实践编排构建等等,欢迎大家持续进行关注。


Guess you like

Origin blog.51cto.com/15009257/2552387
Recommended