这个想法是要有一个容器,它将包含所有的小项目,并将基于参数运行。
当前的情况是什么:
我有这样的项目文件夹:
├── MAIN_PROJECT_FOLDER
│ ├── PROJECT_SUB_CATEGORY1
│ ├── ├── PROJECT_NAME_FOLDER1
│ │ │ ├── run.sh
│ │ │ ├── main.py
│ │ │ ├── config.py
│ ├── ├── PROJECT_NAME_FOLDER2
│ │ │ ├── run.sh
│ │ │ ├── main.py
│ │ │ ├── config.py
│ ├── PROJECT_SUB_CATEGORY2
│ ├── ├── PROJECT_NAME_FOLDER1
│ │ │ ├── run.sh
│ │ │ ├── main.py
│ │ │ ├── config.py
│ ├── ├── PROJECT_NAME_FOLDER2
│ │ │ ├── run.sh
│ │ │ ├── main.py
│ │ │ ├── config.py每个run.sh文件都有prod/dev参数,可以这样执行:
sudo ./run.sh prod = prod
sudo ./run.sh dev = dev
sudo ./run.sh = dev创建另一个.SH文件或Dockerfile的方法是什么,最后可以这样执行:
sudo docker run CONTAINER_NAME PROJECT_NAME PROD/DEV
sudo docker run test_contaner test_project1 prod
sudo docker run test_contaner test_project1 dev
sudo docker run test_contaner test_project2 prod
... and so one基本上,每个项目都是参数,prod/dev将在某种程度上成为run.sh执行的一部分。
寻找实现这一目标的最佳实践。
发布于 2019-07-19 10:47:23
最好的做法通常是有一个只做一件事的形象。在您的示例中,这将意味着四个单独的Docker映像;每个目录都有自己的Dockerfile。
使用环境变量来配置这样的设置也比使用命令行参数更容易。像https://12factor.net/、请描述一下和其他一些用于构建服务的实践。(根据我的经验,在像Docker或Kubernetes这样的YAML规范中,添加另一个键/值环境对比从多个不同的部分构建正确的命令行更容易。)
这就引出了一个序列,就像
sudo docker build -t me/cat1proj1 CATEGORY_1/PROJECT_1
sudo docker run -e ENVIRONMENT=prod me/cat1proj1在体系结构上,Docker容器运行任何单个进程,绝对没有什么能阻止您编写您描述的包装器脚本。该单个命令被指定为一个" entrypoint“和一个”命令“的组合;如果您同时指定了这两个命令,那么该命令将作为参数传递给入口点。“命令”部分可以在Dockerfile CMD中指定,但也可以在docker run命令行中重写。
如果您没有编写任何特殊的脚本,则可以运行(假设您已将项目COPYd放到正确的目录中)。
sudo docker run test_image ./test_project1/run.sh prod(我有两个项目,它们是同一个应用程序,有不同的脚本以不同的方式启动它们--例如,Web服务器与具有相同代码的异步作业运行程序-然后以这种方式使用备用启动脚本启动它们。)
有一种模式是让其他脚本成为ENTRYPOINT,并将“命令”解释为该脚本的参数。该命令只是作为参数$1、$2、"$@"传递。这样做的问题是,它破坏了一些常规调试路径。
# "test_project1" "prod" passed as arguments to entrypoint script
sudo docker run test_image test_project1 prod
# But that breaks getting a debug shell
sudo docker run --rm -it test_image bash
# More complex commands get awkward
sudo docker run --rm --entrypoint=/bin/ls test_image -l /app发布于 2019-07-19 09:47:37
我个人会使用像主管这样的工具,它可以在一个码头容器中运行。
在基于Ubuntu和Debian的发行版上安装supervisor:
sudo apt install supervisor启动supervisor守护进程:
sudo service supervisor start在/etc/supervisord/supervisord.conf中,您可以找到为您的项目提供信任的地方:
[include]
files = /etc/supervisor/conf.d/*.conf现在,您可以为主管创建配置并将其复制到/etc/supervisor/conf.d/。项目supervisor配置示例PROJECT_1
project_1_supervisor.conf
[program:project_1_app]
command=/usr/bin/bash /project_1_path/run.sh prod
directory=/project_1_path/
autostart=true
autorestart=true
startretries=3
stderr_logfile=/var/log/project_1.err.log
stdout_logfile=/var/log/project_1.out.log在此之后重新启动您的supervisor
sudo supervisorctl reread
sudo supervisorctl update在此之后,您可以检查项目程序是否运行:
$ supervisorctl
project_1_app RUNNING pid 590, uptime 0:02:45发布于 2019-07-19 12:01:26
我认为处理这个问题的最好方法是ENV,这是一个完整的例子,您想要的是什么。
这是目录结构

以下是克隆上述应用程序并执行智能操作的最智能的dockerfile ;)该文件将占用4个env,默认情况下它将运行项目A。
ENV BASE_PATH="/opt/project"此ENV用于克隆期间的项目基路径。
ENV PROJECT_PATH="/main/sub_folder_a/project_a"此ENV用于项目路径,例如项目B
ENV SCRIPT_NAME="hello.py"
这个ENV将用于运行实际文件,在您的情况下,实际文件可以是run.sh或main.py。
ENV SYSTEM_ENV=dev
这个env使用run.sh,可以是dev,也可以是prod
FROM python:3.7.4-alpine3.10
WORKDIR /opt/project
# Required Tools
RUN apk add --no-cache supervisor git tree && \
mkdir -p /etc/supervisord.d/
# clone remote project or copy your own one
RUN echo "Starting remote clonning...."
RUN git clone https://github.com/Adiii717/python-demo-app.git /opt/project
RUN tree /opt/project
# ENV for start different project, can be overide at run time
ENV BASE_PATH="/opt/project"
ENV PROJECT_PATH="/main/sub_folder_a/project_a"
ENV SCRIPT_NAME="hello.py"
# possible dev or prod
ENV SYSTEM_ENV=dev
RUN chmod +x /opt/project/main/*/*/run.sh
# general config
RUN echo $'[supervisord] \n\
[unix_http_server] \n\
file = /tmp/supervisor.sock \n\
chmod = 0777 \n\
chown= nobody:nogroup \n\
[supervisord] \n\
logfile = /tmp/supervisord.log \n\
logfile_maxbytes = 50MB \n\
logfile_backups=10 \n\
loglevel = info \n\
pidfile = /tmp/supervisord.pid \n\
nodaemon = true \n\
umask = 022 \n\
identifier = supervisor \n\
[supervisorctl] \n\
serverurl = unix:///tmp/supervisor.sock \n\
[rpcinterface:supervisor] \n\
supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface \n\
[include] \n\
files = /etc/supervisord.d/*.conf' >> /etc/supervisord.conf
# script supervisord Config
RUN echo $'[supervisord] \n\
nodaemon=true \n\
[program:run_project ] \n\
command= /run_project.sh \n\
stdout_logfile=/dev/fd/1 \n\
stdout_logfile_maxbytes=0MB \n\
stderr_logfile_maxbytes = 0 \n\
stderr_logfile=/dev/fd/2 \n\
redirect_stderr=true \n\
autorestart=false \n\
startretries=0 \n\
exitcodes=0 ' >> /etc/supervisord.d/run_project.conf
RUN echo $'#!/bin/ash \n\
echo -e "\x1B[31m starting project having name ${BASE_PATH}${PROJECT_PATH}/${SCRIPT_NAME} \x1B[0m" \n\
fullfilename=${BASE_PATH}${PROJECT_PATH}/${SCRIPT_NAME} \n\
filename=$(basename "$fullfilename") \n\
extension="${filename##*.}" \n\
if [[ ${extension} == "sh" ]];then \n\
sh ${BASE_PATH}${PROJECT_PATH}/${SCRIPT_NAME} ${SYSTEM_ENV} \n\
else \n\
python ${BASE_PATH}${PROJECT_PATH}/${SCRIPT_NAME} \n\
fi ' >> /run_project.sh
RUN chmod +x /run_project.sh
EXPOSE 9080 8000 9088 80
ENTRYPOINT ["supervisord", "--nodaemon", "--configuration", "/etc/supervisord.conf"]建立码头形象
docker build -t multipy .运行码头容器docker run --rm -it multipy
默认情况下,这将运行project a
要投射b,您的命令将是
docker run --rm -it --env PROJECT_PATH=/main/sub_folder_b/project_b --env SCRIPT_NAME=hello.py multipy
要运行您的run.sh bash命令,请将
docker run --rm -it --env SCRIPT_NAME=run.sh multipy
这是一些原木

https://stackoverflow.com/questions/57109216
复制相似问题