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
It works but I can't pass more arguments to ./che.sh
.
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
.
I tried to modify the instruction as:
RUN sudo chown -R user:user /home/user/che && \
sudo service docker start
ENTRYPOINT ["/home/user/che/bin/che.sh"]
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.
I also tried:
ENTRYPOINT ["sudo service docker start", "&&", "/home/user/che/bin/che.sh run"]
even:
ENTRYPOINT ["sh", "-c" "sudo service docker start && /home/user/che/bin/che.sh run"]
But it will report sudo service docker start
is not found in $PATH, or the che.sh
doesn't run.
What's the correct way to write it?
sudo service docker start
should run when che.sh
is invokedche.sh
, like docker run -it --priviledged my/che -r:111.111.111.111 run
The SHELL instruction allows the default shell used for the shell form of commands to be overridden. The default shell on Linux is ["/bin/sh", "-c"] , and on Windows is ["cmd", "/S", "/C"] . The SHELL instruction must be written in JSON form in a Dockerfile.
From Dockerfile reference: The ARG instruction defines a variable that users can pass at build-time to the builder with the docker build command using the --build-arg <varname>=<value> flag. The ENV instruction sets the environment variable <key> to the value <value> .
You have to use supervisord inside a Docker container able to use more complex shell syntax when you creating containers.
Docker documentation about supervisord: https://docs.docker.com/engine/articles/using_supervisord/
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.
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
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"]
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
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.
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'
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.
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.
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).
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
Or place this at the bottom:
ENTRYPOINT ['/bin/bash', '-c']
After when you send any CMD
to this Dockerfile, it will be run by /bin/bash -c
command.
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
will take PID1 and SIGTERM, SIGKILL and SIGINT will work again with your shell script.
I try to stay away running Docker with --privileged
flag. You have many more options to get away on the limitations.
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?
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"
In this case, ENTRYPOINT is preferred to be ENTRYPOINT ['/bin/bash', '-c']
.
Run this script on the host with:
$ cd /home/hostuser
$ ./run -flag1 -flag2 args1 args2 args3
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With