如何编写一个Dockerfile,我可以启动一个服务并运行一个shell并接受该shell的参数? [英] How to write a Dockerfile which I can start a service and run a shell and also accept arguments for the shell?

查看:170
本文介绍了如何编写一个Dockerfile,我可以启动一个服务并运行一个shell并接受该shell的参数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在Dockerfile中,最新指令是:

In a Dockerfile, the latest instruction is:

CMD  sudo chown -R user:user /home/user/che && \
     sudo service docker start && \
     cd /home/user/che/bin/ && ./che.sh run

它可以工作,但我不能将更多参数传递给 ./ che.sh

It works but I can't pass more arguments to ./che.sh.

che.sh 检查是否内部 docker 在执行其他任务后启动。它可以接受几个可选参数,例如 -r:111.111.111.111

The che.sh checks if the internal docker is started after doing other tasks. And it can accept several optional arguments, like -r:111.111.111.111.

我试图将指令修改为:

RUN sudo chown -R user:user /home/user/che && \
     sudo service docker start
ENTRYPOINT ["/home/user/che/bin/che.sh"]

以便像 docker run -it --privileged my / che -r:111.111.111.111 run 一样调用它,但是 che.sh shell将报告内部 docker 运行不正常。

in order to invoke it like docker run -it --priviledged my/che -r:111.111.111.111 run, but the che.sh shell will report internal docker is not working well.

我也尝试过:

ENTRYPOINT ["sudo service docker start", "&&", "/home/user/che/bin/che.sh run"]

甚至:

ENTRYPOINT ["sh", "-c" "sudo service docker start && /home/user/che/bin/che.sh run"]

但是它将报告 sudo服务docker start ,或者 che.sh 没有运行。

But it will report sudo service docker start is not found in $PATH, or the che.sh doesn't run.

什么是正确的


  1. sudo服务docker start 应该在<$ c时运行$ c> che.sh 被调用

  2. 我需要将参数从外部传递给 che.sh ,例如 docker run -it --privileged my / che -r:111.111.111.111 run

  1. sudo service docker start should run when che.sh is invoked
  2. I need to pass arguments from outside to che.sh, like docker run -it --priviledged my/che -r:111.111.111.111 run


推荐答案

在创建时,您必须在能够使用更复杂的Shell语法的Docker容器中使用超级用户

You have to use supervisord inside a Docker container able to use more complex shell syntax when you creating containers.

有关主管的Docker文档: https://docs.docker.com/engine/articles/using_supervisord/

Docker documentation about supervisord: https://docs.docker.com/engine/articles/using_supervisord/

您可以在使用复杂的shell语法(您要使用的语法)时使用您可以使用 $ docker run 命令创建一个新容器,但是,这在systemd服务文件(由于systemd的限制)以及docker-compose .yml文件和Dockerfile中不起作用

YOU CAN use more complex shell syntax (that you want to use) when you create a new container with $ docker run command, however this will not work within systemd service files (due to limitation in systemd) and docker-compose .yml files and the Dockerfiles also.

首先,您必须在Dockerfile中安装超级用户:

First, you have to install supervisord in your Dockerfile:

RUN apt-get -y update && apt-get -y dist-upgrade \
    && apt-get -y install \
        supervisor
RUN mkdir -p /var/log/supervisord

而不是将其放置在Dockerfile的末尾:

Than place this at the end of the Dockerfile:

COPY etc/supervisor/conf.d/supervisord.conf /etc/supervisor/conf.d/
CMD ["/usr/bin/supervisord", "-c", "/etc/supervisor/supervisord.conf"]

etc / supervisor / conf.d / supervisord.conf 中创建文件到您的Dockerfile:

Create a file in etc/supervisor/conf.d/supervisord.conf next to your Dockerfile:

[unix_http_server]
file=/var/run/supervisord.sock
chmod=0777
chown=root:root
username=root

[supervisord]
nodaemon=true
user=root
environment=HOME="/root",USER="root"
logfile=/var/log/supervisord/supervisord.log
pidfile=/var/run/supervisord.pid
childlogdir=/var/log/supervisord
logfile_maxbytes=10MB
loglevel=info

[program:keepalive]
command=/bin/bash -c 'echo Keep Alive service started... && tail -f /dev/null'
autostart=true
autorestart=true
stdout_events_enabled=true
stderr_events_enabled=true
stdout_logfile=/var/log/supervisord/keepalive-stdout.log
stdout_logfile_maxbytes=1MB
stderr_logfile=/var/log/supervisord/keepalive-stderr.log
stderr_logfile_maxbytes=1MB

[program:dcheck]
command=/bin/bash -c 'chmod +x /root/dcheck/repo/dcheck.sh && cd /root/dcheck/repo && ./dcheck.sh'
autostart=true
autorestart=true
stdout_events_enabled=true
stderr_events_enabled=true
stdout_logfile=/var/log/supervisord/dcheck-stdout.log
stdout_logfile_maxbytes=10MB
stderr_logfile=/var/log/supervisord/dcheck-stderr.log
stderr_logfile_maxbytes=1MB

这是一个更复杂的supervisord.conf,可能您不需要这里的许多命令,而且您还必须根据需要更改文件位置。但是,您可以看到如何从脚本的bash输出中创建日志文件。

This is a more complex supervisord.conf and probably you don't need many of the commands here, plus you have to change the file locations to your needs. However you can see how to create log files from the bash output of the script.

稍后,您必须 docker exec 在该容器中,您可以使用以下命令实时查看日志:

Later on you have to docker exec in that container and you can watch real-time the log with:

docker exec -it your_running_container /bin/bash -c 'tail -f /var/log/supervisord/dcheck-stdout.log'

选项可以在主主管日志中显示 loglevel = debug ,但这充满了时间戳和注释,而不是像直接运行脚本时那样的纯bash输出。

You have the option to show subprocess log in the main supervisord log with loglevel=debug, however this is full of timestamps and comments, not the pure bash output like when you run the script directly.

正如您在我的信条中所看到的那样,我使用 tail -f / dev / null 使容器保持活动状态,但是,这是一个不好的做法。 .sh脚本应自行保留容器。

As you can see in my scipt, I keeping alive the container with tail -f /dev/null, however this is a bad practice. The .sh script should keep alive your container on their own.

当您将scipt作为 ENTRYPOINT发送给ENTRYPOINT时[ sudo service docker start ,&&, / home / user / che / bin / che.sh运行] ,您想要将默认的Docker ENTRYPOINT更改为 / bin / sh -c sudo (也请使用完整的位置名称)。

When you sending your scipt to ENTRYPOINT as ENTRYPOINT ["sudo service docker start", "&&", "/home/user/che/bin/che.sh run"], you want to change the default docker ENTRYPOINT from /bin/sh -c to sudo (also, use full location names).

有有两种方法可以在Dockerfile中更改Docker ENTRYPOINT。一种是将其放在Dockerfile的头部:

There are two ways to change docker ENTRYPOINT in Dockerfile. One is to place this in the head section of your Dockerfile:

RUN ln -sf /bin/bash /bin/sh && ln -sf /bin/bash /bin/sh.distrib

或将其放在底部:

ENTRYPOINT ['/bin/bash', '-c']

将任何 CMD 发送到此Dockerfile后,它将由运行/ bin / bash -c 命令。

After when you send any CMD to this Dockerfile, it will be run by /bin/bash -c command.

还有一点要注意的是,第一个命令使用PID1,因此如果要运行在我的监督脚本中没有 tail -f / dev / null 的.sh脚本,它将占据PID1进程的位置,而CTRL + C命令将不起作用。您必须从另一个外壳程序实例关闭容器。

One more thing to note is that the first command takes PID1, so if you want to run the .sh script without tail -f /dev/null in my supervisord script, it will take PID1 process place and CTRL+C command will not gonna work. You have to shut down the container from another shell instance.

但是如果您使用以下命令运行命令:

But if you run the command with:

[program:dcheck]
command=/bin/bash -c 'echo pid1 > /dev/null && chmod +x /root/dcheck/repo/dcheck.sh && cd /root/dcheck/repo && ./dcheck.sh'

echo pid1> / dev / null 将使用PID1,SIGTERM,SIGKILL和SIGINT将再次与您的Shell脚本一起使用。

echo pid1 > /dev/null will take PID1 and SIGTERM, SIGKILL and SIGINT will work again with your shell script.

我尝试不使用Docker带有-特权标志。您还有更多选择可以摆脱限制。

I try to stay away running Docker with --privileged flag. You have many more options to get away on the limitations.

我对您的堆栈一无所知,但通常最好不要在容器中对Docker进行码头化。为什么 sudo服务docker start 在您的Dockerfile中是有特定原因的?

I don't know anything about your stack, but generally good idea to not dockerise Docker in a Container. Is there a specific reason why sudo service docker start is in your Dockerfile?

我一无所知这个容器,它必须还活着吗?因为如果没有,那么有一个更简单的解决方案,仅在容器必须从命令行处理某些内容时才运行该容器。将该文件放在名称为 run 的主机上,假设它位于 / home / hostuser 文件夹中,并赋予它 chmod + x run

I don't know anything about this container, is it have to be alive? Because if doesn't, there is a more simple solution, only running the container when it has to process something from the command line. Place this file on the host with the name of run let's say in /home/hostuser folder and give it chmod +x run:

#!/bin/bash
docker run --rm -it -v /home/hostuser/your_host_shared_folder/:/root/your_container_shared_folder/:rw your_docker_image "echo pid1 > /dev/null && chmod +x /root/script.sh && cd  /root && ./script.sh"

在这种情况下,首选ENTRYPOINT成为 ENTRYPOINT ['/ bin / bash','-c']

In this case, ENTRYPOINT is preferred to be ENTRYPOINT ['/bin/bash', '-c'].

在主机:

$ cd /home/hostuser
$ ./run -flag1 -flag2 args1 args2 args3

这篇关于如何编写一个Dockerfile,我可以启动一个服务并运行一个shell并接受该shell的参数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆