openssh-server doesn't start in Docker container - docker

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 :)

Related

Is it possible to run nginx automatically on every startup in a docker container?

I'm new to docker.
I'm setting up nginx server to serve static files inside a docker container. I'd like to enable nginx to start automatically on every startup inside a docker container.
I've tried changing ENTRYPOINT, CMD and crontab when building DockerImage. But these settings to run nginx on every startup works only the first time I "run" a container. When I "stop" the container and "start" it again, nginx does not start automatically inside the container.
I'm looking for a way to start nginx on every startup of a container and my first question is "is it possible to do this?"
My second question is about a container cycle. Given that there are not many discussions on this subject (all discussions are about automatically running a script or sth else at the moment of "run"), I wonder if it is more efficient to "run" and "kill" a container each time than just "stopping" and "starting" a container.
Here are the lines of code I tried for DockerImage (with crontab), which was my first try.
RUN apt-get install -y cron
COPY run_server /etc/cron.d/run_server
RUN chmod 0644 /etc/cron.d/run_server
RUN crontab /etc/cron.d/run_server
RUN touch /var/log/cron.log
CMD cron && tail -f /var/log/cron.log
run_server is a simple crontab config file which includes:
#reboot service nginx start
Since this was not the solution I was looking for (it worked only when I "ran" a conainer, not "stopped" and "started" a container) I tried with supervisor, too.
RUN apt-get -y install supervisor && \
mkdir -p /var/log/supervisor && \
mkdir -p /etc/supervisor/conf.d
ADD supervisor.conf /etc/supervisor.conf
CMD ["supervisord", "-c", "/etc/supervisor.conf"]
supervisor.confg contains:
[supervisord]
nodaemon=true
[program:run_server]
command=/usr/bin/python3.6 /home/server.py
autostart=true
directory=/home
redirect_stderr=true
But neither of them worked the way I wanted ..
my Dockerfile , container ( CentOS 8 and nginx ) linux mint 19.3 Docker version 19.03.4
# howto: Dockerfile
# CentOS 8 and nginx
# docker build -t centose .
# docker run -it -p 80:80 centose
# curl localhost
FROM centos:latest
# MAINTAINER їван
RUN yum -y install nginx
EXPOSE 80
CMD ["/usr/sbin/nginx", "-g", "daemon off;"]
#WORKDIR /usr/sbin/
I would try to update my docker file and enable the nginx service so it will be started during the next reboot.
Here is a couple of different ways:
RUN systemctl enable nginx
RUN service nginx start
Another way would be to add a bootstrap script that starts the service:
#!/bin/bash
sudo service nginx start
tail -f /var/log/nginx/error.log
Make sure the bootstrap.sh is executable i.e sudo chmod +x bootstrap.sh.
Then update your docker file:
COPY boostrap.sh /bin/.
CMD ["bootstrap.sh"]
you can apply that using docker restart policy
you can simply set it when creating the container or updating the created ones
examples: docker run -t -d --restart unless-stopped nginx
to update the created ones: docker update --restart unless-stopped {container ID}

Docker Startup Multiple service is not working

Dockerfile
FROM drupal
RUN apt-get update
RUN apt-get install openssh-server -y
RUN apt-get install -y supervisor
#SS Related Fix : https://github.com/Microsoft/WSL/issues/3621
RUN mkdir -p /run/sshd
# SS Access Configuration
RUN echo "root:Docker!" | chpasswd
#Project Uplaod
RUN rm -rf /var/www/html/*
COPY ./html/ /var/www/html/
# Startup Configuration
COPY servername.conf /etc/apache2/conf-enabled/servername.conf
ADD supervisord.conf /etc/supervisor/conf.d/supervisord.conf
CMD ["/usr/bin/supervisord"]
Start Command : docker -D run -p 80:80 -p 2222:22 -it /bin/bash
[supervisord]
nodaemon=true
[program:SSH]
command=/usr/sbin/sshd start
[program:Apache]
command=/etc/init.d/apache2 start
when i jump into Shell and run that command it works but when i start container its not starting up the web server.
As standing in documentation
To start supervisord, run $BINDIR/supervisord. The resulting process
will daemonize itself and detach from the terminal. It keeps an
operations log at $CWD/supervisor.log by default.
You may start the supervisord executable in the foreground by passing
the -n flag on its command line. This is useful to debug startup
problems.
So systemd detach from main process what means for docker that process ended - exit container. To solve your problem you need to change CMD section to
CMD ["/usr/bin/supervisord", "-n"]
When you run
docker -D run -p 80:80 -p 2222:22 -it /bin/bash
The last part of the command, /bin/bash, replaces the CMD in the Dockerfile, so you only get the GNU bash shell. You should remove that part of the line and the standard command from your image will run.
You might consider how much you actually need an interactive shell in your Docker environment. Most application images are set up to run totally on their own without manual setup steps; compare the stock mysql or nginx images, for instance, which don't include any kind of remote login system. Also consider that anyone who can run docker history can now trivially find out your root password, and you have no way to manage the sshd host keys. I'd suggest removing this entire supervisord/sshd system and just packaging your application.

Running multiple commands after docker create

I want to make a script run a series of commands in a Docker container and then copy a file out. If I use docker run to do this, I don't get back the container ID, which I would need for the docker cp. (I could try and hack it out of docker ps, but that seems risky.)
It seems that I should be able to
Create the container with docker create (which returns the container ID).
Run the commands.
Copy the file out.
But I don't know how to get step 2. to work. docker exec only works on running containers...
If i understood your question correctly, all you need is docker "run exec & cp" -
For example -
Create container with a name --name with docker run -
$ docker run --name bang -dit alpine
Run few commands using exec -
$ docker exec -it bang sh -c "ls -l"
Copy a file using docker cp -
$ docker cp bang:/etc/hosts ./
Stop the container using docker stop -
$ docker stop bang
All you really need is Dockerfile and then build the image from it and run the container using the newly built image. For more information u can refer to
this
A "standard" content of a dockerfile might be something like below:
#Download base image ubuntu 16.04
FROM ubuntu:16.04
# Update Ubuntu Software repository
RUN apt-get update
# Install nginx, php-fpm and supervisord from ubuntu repository
RUN apt-get install -y nginx php7.0-fpm supervisor && \
rm -rf /var/lib/apt/lists/*
#Define the ENV variable
ENV nginx_vhost /etc/nginx/sites-available/default
ENV php_conf /etc/php/7.0/fpm/php.ini
ENV nginx_conf /etc/nginx/nginx.conf
ENV supervisor_conf /etc/supervisor/supervisord.conf
#Copy supervisor configuration
COPY supervisord.conf ${supervisor_conf}
# Configure Services and Port
COPY start.sh /start.sh
CMD ["./start.sh"]
EXPOSE 80 443

docker, mariadb doesn't start at "init", based in debian:stable

i am trying write a Dockerfile like that
FROM debian:stable
RUN apt-get update
RUN apt-get install -y mariadb-server
EXPOSE 3306
CMD ["mysqld"]
I create the image with
docker build -t debian1 .
And i create the container with
docker run -d --name my_container_debian -i -t debian1
20 seconds after, docker ps -a tells that container is exited. Why? I want the container is up and mariadb running. Thanks. Sorry for the question.
mysqld alone would exit too soon.
If you look at a MySQL server Dockerfile, you will note its ENTRYPOINT is a script docker-entrypoint.sh which will exec mysqld in foreground.
exec "$#"

How can I run two commands in CMD or ENTRYPOINT in Dockerfile

In the Dockerfile builder, ENTRYPOINT and CMD run in one time by using /bin/sh -c in back.
Are there any simple solution to run two command inside without extra script
In my case, I want to setup docker in docker in jenkins slave node, so I pass the docker.sock into container, and I want to change the permission to be executed by normal user, so it shall be done before sshd command.
The normal is like jenkins, which will be login into container via ssh command.
$ docker run -d -v /var/run/docker.sock:/docker.sock larrycai/jenkins-slave
In larrycai/jenkins-slave Dockerfile, I hope to run
CMD chmod o+rw /docker.sock && /usr/sbin/sshd -D
Currently jenkins is given sudo permission, see larrycai/jenkins-slave
I run docker in docker in jenkins slave:
First: my slave know run docker.
Second: I prepare one docker image who knows run docker in docker. See one fragment of dockerfile
RUN echo 'deb [trusted=yes] http://myrepo:3142/get.docker.io/ubuntu docker main' > /etc/apt/sources.list.d/docker.list
RUN apt-get update -qq
RUN apt-get install -qqy iptables ca-certificates lxc apt-transport-https lxc-docker
ADD src/wrapdocker /usr/local/bin/wrapdocker
RUN chmod +x /usr/local/bin/wrapdocker
VOLUME /var/lib/docker
Third: The jenkins job running in this slave contain one .sh file with a set of command to run over app code like:
export RAILS_ENV=test
# Bundle install
bundle install
# spec_no_rails
bundle exec rspec spec_no_rails -I spec_no_rails
bundle exec rake db:migrate:reset
bundle exec rake db:test:prepare
etc...
Fourth: one run shell step job with something like this
docker run --privileged -v /etc/localtime:/etc/localtime:ro -v `pwd`:/code myimagewhorundockerindocker /bin/bash -xec 'cd /code && ./myfile.sh'
--privileged necessary for run docker in docker
-v /etc/localtime:/etc/localtime:ro for synchronize host clock vs container clock
-v pwd:/code for share jenkins workspace (app-code) previously cloned from VCS with /code inside container
note: If you have service dependencies you can use fig with similar strategy.

Resources