借鉴官方样例以及项目经验,以下是dockerfile的最佳实践
1. Dockerfile样例
FROM python:3.8.11-slim # 采用瘦身版基础镜像
# -m 用户主目录不存在则自动创建
RUN useradd -ms /bin/bash test
RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && echo 'Asia/Shanghai' >/etc/timezone
ENV LC_ALL=C.UTF-8
RUN sed -i s/deb.debian.org/mirrors.aliyun.com/g /etc/apt/sources.list
RUN apt clean && apt update && apt install gosu #gosu用来切换用户,代替sudo
EXPOSE 9020
EXPOSE 9001
VOLUME [ "/test/logs" ]
WORKDIR /test
COPY . .
RUN apt install procps -y # 安装ps
RUN pip install --upgrade pip -i https://mirrors.aliyun.com/pypi/simple/
RUN pip install -r requirements.txt -i https://mirrors.aliyun.com/pypi/simple/
#RUN supervisord -c /test/log_monitor/supervisor.conf
RUN chmod -R 777 /test/ # 可执行权限,不然没有权限执行sh文件
ENTRYPOINT [ "./entrypoint.sh" ]
CMD ["bash", "./start.sh"]
2. entrypoint.sh样例, 来自官网
#!/bin/bash
set -e
if [ "$1" = 'bash' ]; then
chown -R appl /appl
exec gosu appl "$@"
fi
exec "$@"
根据CMD第一个参数的不同,可以设置$1变量的值(bash),用于切换用户执行命令,尽量不以root用户启动容器。
3. start.sh样例
#!/bin/bash
supervisord -c /test/log_monitor/supervisor.conf &
python /test/log_monitor/work.py
# 具体的执行语句
4. 注意点
- 可执行文件要给与足够的权限,chmod
- 尽量不以root启动
- 镜像构建完成后,本身已有 ENTRYPOINT 和 CMD 的启动命令,所以不要再加bash作为一号进程
- 可以让CMD 执行启动脚本,在脚本里写入多个命令。
- win下docker需要配合Desktop使用