首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >最佳实践10+项目将使用一个容器/参数化运行

最佳实践10+项目将使用一个容器/参数化运行
EN

Stack Overflow用户
提问于 2019-07-19 09:12:48
回答 3查看 106关注 0票数 1

这个想法是要有一个容器,它将包含所有的小项目,并将基于参数运行。

当前的情况是什么:

我有这样的项目文件夹:

代码语言:javascript
复制
├── 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参数,可以这样执行:

代码语言:javascript
复制
sudo ./run.sh prod = prod
sudo ./run.sh dev  = dev
sudo ./run.sh      = dev

创建另一个.SH文件或Dockerfile的方法是什么,最后可以这样执行:

代码语言:javascript
复制
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执行的一部分。

寻找实现这一目标的最佳实践。

EN

回答 3

Stack Overflow用户

发布于 2019-07-19 10:47:23

最好的做法通常是有一个只做一件事的形象。在您的示例中,这将意味着四个单独的Docker映像;每个目录都有自己的Dockerfile。

使用环境变量来配置这样的设置也比使用命令行参数更容易。像https://12factor.net/请描述一下和其他一些用于构建服务的实践。(根据我的经验,在像Docker或Kubernetes这样的YAML规范中,添加另一个键/值环境对比从多个不同的部分构建正确的命令行更容易。)

这就引出了一个序列,就像

代码语言:javascript
复制
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放到正确的目录中)。

代码语言:javascript
复制
sudo docker run test_image ./test_project1/run.sh prod

(我有两个项目,它们是同一个应用程序,有不同的脚本以不同的方式启动它们--例如,Web服务器与具有相同代码的异步作业运行程序-然后以这种方式使用备用启动脚本启动它们。)

有一种模式是让其他脚本成为ENTRYPOINT,并将“命令”解释为该脚本的参数。该命令只是作为参数$1$2"$@"传递。这样做的问题是,它破坏了一些常规调试路径。

代码语言:javascript
复制
# "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
票数 2
EN

Stack Overflow用户

发布于 2019-07-19 09:47:37

我个人会使用像主管这样的工具,它可以在一个码头容器中运行。

在基于Ubuntu和Debian的发行版上安装supervisor

代码语言:javascript
复制
sudo apt install supervisor

启动supervisor守护进程:

代码语言:javascript
复制
sudo service supervisor start

/etc/supervisord/supervisord.conf中,您可以找到为您的项目提供信任的地方:

代码语言:javascript
复制
[include]
files = /etc/supervisor/conf.d/*.conf

现在,您可以为主管创建配置并将其复制到/etc/supervisor/conf.d/。项目supervisor配置示例PROJECT_1

project_1_supervisor.conf

代码语言:javascript
复制
[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

代码语言:javascript
复制
sudo supervisorctl reread
sudo supervisorctl update

在此之后,您可以检查项目程序是否运行:

代码语言:javascript
复制
$ supervisorctl
project_1_app               RUNNING    pid 590, uptime 0:02:45
票数 1
EN

Stack Overflow用户

发布于 2019-07-19 12:01:26

我认为处理这个问题的最好方法是ENV,这是一个完整的例子,您想要的是什么。

这是目录结构

以下是克隆上述应用程序并执行智能操作的最智能的dockerfile ;)该文件将占用4个env,默认情况下它将运行项目A。

代码语言:javascript
复制
ENV BASE_PATH="/opt/project"

此ENV用于克隆期间的项目基路径。

代码语言:javascript
复制
  ENV PROJECT_PATH="/main/sub_folder_a/project_a"

此ENV用于项目路径,例如项目B

ENV SCRIPT_NAME="hello.py"

这个ENV将用于运行实际文件,在您的情况下,实际文件可以是run.shmain.py

ENV SYSTEM_ENV=dev

这个env使用run.sh,可以是dev,也可以是prod

代码语言:javascript
复制
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"]

建立码头形象

代码语言:javascript
复制
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

这是一些原木

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57109216

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档