This question already has answers here:
systemctl command doesn't work inside docker-container
(2 answers)
Closed 1 year ago.
I am new in docker, I want to build an image with Ubuntu 20.04 and bind9 service installation.
below is my code of docker file
FROM ubuntu:20.04
ENV TZ=Asia
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
RUN apt-get update && apt-get install -y \
apt-utils \
systemctl \
bind9
CMD ["/usr/sbin/named", "-g", "-c", "/etc/bind/named.conf", "-u", "bind"]
CMD systemctl restart bind9
When I execute following command to build an image,
sudo docker image build --tag bind9server .
It works fine.
Step 6/6 : CMD systemctl restart bind9
---> Running in f982f314c216
But when I run this docker image, I am getting an error like below
ERROR:systemctl:Unit bind9.service could not be found.
Can anyone help me, after installation of Bind9, why I am getting an error with above command?
Error comes with Docker only, if I run same command in Host environment which is Ubuntu 20.04 then it works fine.
First thing: you should use a long running command for your last CMD, otherwise the container will exit once done. The purpose of CMD is to provide a default entry-point to your container, so even if there was a bind9 service, you container would exit immediately. Also, only the last CMD takes effect (see docs).
Second: see this question for an explanation of why it's not such a good idea to run with systemd inside a Docker container. You are much better off with your first try, that is calling named directly.
Third: on a "normal" host, when you are unsure about an unit name such as bind9, you can try to inspect all the known units with systemctl list-units --all. It looks like your service is called named.
Related
I am new in docker, I want to build an image with Ubuntu 20.04 and bind9 service installation.
below is my code of docker file
FROM ubuntu:20.04
ENV TZ=Asia
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
RUN apt-get update && apt-get install -y \
apt-utils \
systemctl \
bind9
RUN /usr/sbin/named -g -c /etc/bind/named.conf -u bind
RUN systemctl restart bind9
I am getting an error like below
ERROR:systemctl:Unit bind9.service could not be found.
Can anyone help me, after installation of Bind9, why I am getting an error with above command?
Error comes with Docker only, if I run same command in Host environment which is Ubuntu 20.04 then it works fine.
You generally cannot use service management commands (like service or systemctl, etc) in a container, because there is no service manager running.
Additionally, even if there were a service manager running, it wouldn't make any sense to interact with it in a RUN command: these commands are part of the image build process, and there are no persistent services running at this point. A RUN command runs in an isolated environment that is completely torn down when the RUN command completes.
If you want bind to start when you run a container using your image, you would need to place the appropriate bind command line into the CMD option. For example, the official bind9 image includes:
CMD ["/usr/sbin/named", "-g", "-c", "/etc/bind/named.conf", "-u", "bind"]
(See the Dockerfile for details)
I'm french and new here (so I don't know how stack overflow works, his community) I'm gonna try to adapt myself.
So, my first problem is the following :
I run docker container with my image who it created with Dockerfile. (there is DNS container)
In Dockerfile, this container have to start script.sh when it start.
But after use that :
docker run -d -ti -p 53:53 alex/dns
(Use -p 53:53 because DNS.)
I can see my DNS runing at the end of my script.sh but, when I do :
Docker ps -a ; but > container is not running.
I'm novice with docker. I have started to learn it 2days ago.
I tried to add (one by one of course):
CMD ["bash"]
CMD ["/bin/bash"]
to run bash and make sure that does not poweroff.
I tried to add -d in Docker run command
I tried to use :
docker commit ti alex/dns
and
docker exec -ti alex/dns /bin/bsh
My dockerfile file :
FROM debian
...
RUN apt-get install bind9
...
ADD script.sh /usr/bin/script.sh
...
ENTRYPOINT ["/bin/bash", "script.sh]
CMD ["/bin/bash"]
My file script.sh :
service bind9 stop
*It copy en remplace conf file for bind9*
service bind9 restart
I hope that there are not too many mistakes and that I managed to make myself understood
I expect the DNS container stay runing and can use it with docker exec.
But now, after use docker run, the container start en stop juste after my script finish. Yes, the DNS server is runing the container tell me before close [ok] Bind9 running or somthing like that. But after container stop.
I suspect the problem you're facing is that your container will terminate once service bind9 restart completes.
You need to have a foreground process running to keep the container running.
I'm unfamiliar with bind9 but I recommend you explore ways to run bind9 in the foreground in your container.
Your command to run the container is correct:
docker run -d -ti -p 53:53 alex/dns
You may need to:
RUN apt-get update && apt-get -y install bind9
You will likely need something like (don't know):
ENTRYPOINT ["/bind9"]
Googled it ;-)
https://manpages.debian.org/jessie/bind9/named.8.en.html
After you've configured it, you can run it as a foreground process:
ENTRYPOINT ["named","-g"]
I am containerizing the latest version of grafana and want to start the grafana-process when the container starts and then use it in my K8S (kubernetes) cluster.
My Dockerfile looks like :
FROM armdocker/baseimages/rhel:7-20161207
MAINTAINER xxxxxxxx
ENV GRAFANA_VERSION_MAJOR=4 GRAFANA_VERSION_MINOR=4 GRAFANA_VERSION_PATCH=3-1
ENV GRAFANA_VERSION=${GRAFANA_VERSION_MAJOR}.${GRAFANA_VERSION_MINOR}.${GRAFANA_VERSION_PATCH}
RUN yum clean all && yum install -y unzip tar
RUN curl -f -L -o grafana-${GRAFANA_VERSION}.x86_64.rpm https://s3-us-west-2.amazonaws.com/grafana-releases/release/grafana-${GRAFANA_VERSION}.x86_64.rpm && \
yum localinstall grafana-${GRAFANA_VERSION}.x86_64.rpm -y
EXPOSE 3000
ENTRYPOINT ["/etc/init.d/grafana-server start"]
Building the Dockerfile is successful and returns no errors.
When I try to run this image, I get the ERROR.
docker run -dit -p 3000:3000 armdocker/proj/grafana:1.0.5
471b2acb964caad69bbb78831a59ee9d2b27997911b5b104b0057ddc957d1101
Error response from daemon: Cannot start container 471b2acb964caad69bbb78831a59ee9d2b27997911b5b104b0057ddc957d1101: [8] System error: exec: "/etc/init.d/grafana-server start": stat /etc/init.d/grafana-server start: no such file or directory
This seems to be very weird since I am installing the RPM first (which makes the file /etc/init.d/grafana-server ) and then I am trying to start the process as my ENTRYPOINT
I then tried
CMD ["/etc/init.d/grafana-server start"]
This also results in the same ERROR /etc/init.d/grafana-server start: no such file or directory
I then tried using the systemctl command :
docker run -dit -p 3000:3000 armdocker/proj/grafana:1.0.6
bfd492c75a0f4c284fc0fdbd5a590f0155f6f67bcb4834e144f344bb789546f3
Error response from daemon: Cannot start container bfd492c75a0f4c284fc0fdbd5a590f0155f6f67bcb4834e144f344bb789546f3: [8] System error: exec: "/bin/systemctl start grafana-server.service": stat /bin/systemctl start grafana-server.service: no such file or directory
I am out of ideas as to what am I doing wrong to have a container with a started grafana process.
Unless you're running your own systemd daemon inside of the container (I don't recommend this, it creates lots of issues), you shouldn't be trying to start the process with a systemctl or /etc/init.d command. Containers are not a VM, they are a method to run an application within their own namespace. And when that application exits, so do your container. When your application is something like a systemctl start command, your container will exit the moment that systemctl command returns, which isn't useful it you were hopping it would stay up for the duration of the grafana process running.
Rather than trying to reinvent the wheel, I'd recommend you look at how grafana themselves packages their docker container. Specifically their run.sh ends with:
exec gosu grafana /usr/sbin/grafana-server \
--homepath=/usr/share/grafana \
--config=/etc/grafana/grafana.ini \
cfg:default.log.mode="console" \
cfg:default.paths.data="$GF_PATHS_DATA" \
cfg:default.paths.logs="$GF_PATHS_LOGS" \
cfg:default.paths.plugins="$GF_PATHS_PLUGINS" \
"$#"
Their repo is over at https://github.com/grafana/grafana-docker
As an alternative you could use the docker-systemctl-replacement script and register it as the main CMD of the image. It will check out the *.service scripts to know how to start and stop a service (without the help of a systemd daemon). So if the Grafana guys change their startup scenario then your builds will continue to work. ;)
I am a newbie to docker and trying to understand how to create dockerfiles.
While attempting the same I created this sample file
FROM debian
RUN apt-get update && apt-get upgrade -y
RUN apt-get install apache2 -y
COPY ./index.html /etc/www/html/
CMD service apache2 start && /bin/bash
The CMD part has always confused me and I am using the /bin/bash mostly because I read somewhere that we need to make sure that there is some running command in the Docker Image when we are bringing it up. I use this to run the image :-
docker run -t -p 5000:8080 --name myfinal 912ccd578eae
where I'm using the id of the image built. As you can see, I'm a novice and even the minutest of details would help.
The usual CMD for apache2 should be
CMD ["/usr/sbin/apache2", "-D", "FOREGROUND"]
That way, you don't have to use the "bash" trick to keep a foreground process running.
And any exit signal will impact correctly the apache2 process, not the bash one.
No need for ENTRYPOINT here: Docker maintains a default entrypoint, /bin/sh.
So this (with CMD) is the same as:
/bin/sh -c “apachectl -D FOREGROUND”
I am having a weird problem.
I am not able to ssh to docker container having ip address 172.17.0.61.
I am getting following error:
$ ssh 172.17.0.61
ssh: connect to host 172.17.0.61 port 22: Connection refused
My Dockerfile does contain openssh-server installation step:
RUN apt-get -y install curl runit openssh-server
And also step to start ssh:
RUN service ssh start
What could be the issue?
When I enter into container using nsenter and start ssh service then I am able to ssh. But while creating container ssh-server doesn't seems to start.
What should I do?
When building a Dockerfile you would create an image. But you can't create an image with an already running ssh daemon or any running service else. First if you create a running container out of the image you can start services inside. E.g. by appending the start instruction to the docker run command:
sudo docker run -d mysshserver service ssh start
You can define a default command for your docker image with CMD. Here is an example Dockerfile:
FROM ubuntu:14.04.1
MAINTAINER Thomas Steinbach
EXPOSE 22
RUN apt-get install -y openssh-server
CMD service ssh start && while true; do sleep 3000; done
You can build an run this image with the following two commands:
sudo docker build -t sshtest .
sudo docker run -d -P --name ssht sshtest
Now you can connect to this container via ssh. Note that in the example Dockerfile no user and no login was created. This image is just for example and you can start an ssh connection to it, but not login.
In my opinion there is a better approach:
Dockerfile
FROM ubuntu:14.04.1
EXPOSE 22
COPY docker-entrypoint.sh /docker-entrypoint.sh
RUN chmod +x /docker-entrypoint.sh
RUN apt-get install -y openssh-server
ENTRYPOINT ["sh", "/docker-entrypoint.sh"]
# THIS PART WILL BE REPLACED IF YOU PASS SOME OTHER COMMAND TO docker RUN
CMD while true; do echo "default arg" && sleep 1; done
docker-entrypoint.sh
#!/bin/bash
service ssh restart
exec "$#"
Build command
docker build -t sshtest .
The benefit of this approach is that your ssh daemon will always start when you use docker run, but you can also specify optional arguments e.g.:
docker run sshtest will print default arg every 1 second
whether docker run sshtest sh -c 'while true; do echo "passed arg" && sleep 3; done' will print passed arg every 3 seconds
I had the same problem.
Luckily I could solve it by checking kenorb answer and adapting it to my Dockerfile:
https://stackoverflow.com/a/61738823/4058295
It's worth a try :)