Reputation: 15070
I have a Dockerfile to install MySQL server in a container, which I then start like this:
sudo docker run -t -i 09d18b9a12be /bin/bash
But the MySQL service does not start automatically, I have to manually run (from within the container):
service mysql start
How do I automatically start the MySQL service when I run the docker container?
Upvotes: 213
Views: 396994
Reputation: 3184
Assuming you want to run your main process as pid 1 but you also let say want to have cron started or some other service you may add something like
#make sure some other service starts on container start, tested in Ubuntu 20.04 based container
RUN echo "cron" >> /etc/bash.bashrc
CMD ["myproc"] #should run as 1 to receive sigterm
Using that approach chances are high, but didn't test it you could do something like, to start a service besides main process
RUN echo "service mysql start" >> /etc/bash.bashrc
CMD ["myproc"] #should run as 1 to receive sigterm
So basically you add custom entry to /etc/bash.bashrc
and this is executed on system (container) start. Again Ubuntu 20.04, on other version the system bashrc
may be under different name
Upvotes: 0
Reputation: 29
ENTRYPOINT name-service
Inside your Dockerfile
Example:
ENTRYPOINT mysqld_explorer
/etc/systemd/system/mysqld_explorer.service
Upvotes: 1
Reputation: 1
I've just been I trying and searching for hours before I found this hint here. I have tweaked the above:
'/bin/sh' '-c' '/mypath/startup.sh; bash'
In Portainer (2.11.1) this is placed in "Command", "Entrypoint" is still empty.
Upvotes: 0
Reputation: 5947
I am using docker-compose.yml
(version: "3.9")
What I do is add a command like below in the service of docker-compose.yml
to start a service and running a non-end process.
command: /bin/sh -c "service mysql start; while sleep 1000; do :; done"
Upvotes: 0
Reputation: 186
if you can not change docker file /docker image. here is the workaround:
docker run imageid bash -c 'service mysql start ; while true ; do sleep 100; done; '
Upvotes: 0
Reputation: 27120
There's another way to do it that I've always found to be more readable.
Say that you want to start rabbitmq and mongodb when you run it then your CMD
would look something like this:
CMD /etc/init.d/rabbitmq-server start && \
/etc/init.d/mongod start
Since you can have only one CMD
per Dockerfile
the trick is to concatenate all instructions with &&
and then use \
for each command to start a new line.
If you end up adding to many of those I suggest you put all your commands in a script file and start it like @larry-cai suggested:
CMD /start.sh
Upvotes: 13
Reputation: 186
This not works CMD service mysql start && /bin/bash
This not works CMD service mysql start ; /bin/bash ;
-- i guess interactive mode would not support foreground.
This works !! CMD service nginx start ; while true ; do sleep 100; done;
This works !! CMD service nginx start && tail -F /var/log/nginx/access.log
beware you should using docker run -p 80:80 nginx_bash
without command parameter.
Upvotes: 7
Reputation: 51
I have the same problem when I want to automatically start ssh service. I found that append
/etc/init.d/ssh startto
~/.bashrccan resolve it ,but only you open it with bash will do.
Upvotes: 5
Reputation: 199
docker export -o <nameOfContainer>.tar <nameOfContainer>
Might need to prune the existing container using docker prune ...
Import with required modifications:
cat <nameOfContainer>.tar | docker import -c "ENTRYPOINT service mysql start && /bin/bash" - <nameOfContainer>
Run the container for example with always restart option to make sure it will auto resume after host/daemon recycle:
docker run -d -t -i --restart always --name <nameOfContainer> <nameOfContainer> /bin/bash
Side note: In my opinion reasonable is to start only cron service leaving container as clean as possible then just modify crontab or cron.hourly, .daily etc... with corresponding checkup/monitoring scripts. Reason is You rely only on one daemon and in case of changes it is easier with ansible or puppet to redistribute cron scripts instead of track services that start at boot.
Upvotes: 1
Reputation: 49
Here is how I automatically start the MySQL service whenever the docker container runs.
On my case, I need to run not just MySQL but also PHP, Nginx and Memcached
I have the following lines in Dockerfile
RUN echo "daemon off;" >> /etc/nginx/nginx.conf
EXPOSE 80
EXPOSE 3306
CMD service mysql start && service php-fpm start && nginx -g 'daemon off;' && service memcached start && bash
Adding && bash would keep Nginx, MySQL, PHP and Memcached running within the container.
Upvotes: 4
Reputation: 59953
First, there is a problem in your Dockerfile
:
RUN service mysql restart && /tmp/setup.sh
Docker images do not save running processes. Therefore, your RUN
command executes only during docker build
phase and stops after the build is completed. Instead, you need to specify the command when the container is started using the CMD
or ENTRYPOINT
commands like below:
CMD mysql start
Secondly, the docker container needs a process (last command) to keep running, otherwise the container will exit/stop. Therefore, the normal service mysql start
command cannot be used directly in the Dockerfile.
There are three typical ways to keep the process running:
Using service
command and append non-end command after that like tail -F
CMD service mysql start && tail -F /var/log/mysql/error.log
This is often preferred when you have a single service running as it makes the outputted log accessible to docker.
Or use foreground command to do this
CMD /usr/bin/mysqld_safe
This works only if there is a script like mysqld_safe
.
Or wrap your scripts into start.sh
and put this in end
CMD /start.sh
This is best if the command must perform a series of steps, again, /start.sh
should stay running.
For the beginner using supervisord
is not recommended. Honestly, it is overkill. It is much better to use single service / single command for the container.
BTW: please check https://registry.hub.docker.com for existing mysql docker images for reference
Upvotes: 274
Reputation: 51
I add the following code to /root/.bashrc to run the code only once,
Please commit the container to the image before run this script, otherwise the 'docker_services' file will be created in the images and no service will be run.
if [ ! -e /var/run/docker_services ]; then
echo "Starting services"
service mysql start
service ssh start
service nginx start
touch /var/run/docker_services
fi
Upvotes: 5
Reputation: 1533
In your Dockerfile
, add at the last line
ENTRYPOINT service ssh restart && bash
It works for me
And this is the result:
root@ubuntu:/home/vagrant/docker/add# docker run -i -t ubuntu
* Restarting OpenBSD Secure Shell server sshd [ OK ]
root@dccc354e422e:~# service ssh status
* sshd is running
Upvotes: 99
Reputation: 1374
In my case, I have a PHP web application being served by Apache2 within the docker container that connects to a MYSQL backend database. Larry Cai's solution worked with minor modifications. I created a entrypoint.sh
file within which I am managing my services. I think creating an entrypoint.sh
when you have more than one command to execute when your container starts up is a cleaner way to bootstrap docker.
#!/bin/sh
set -e
echo "Starting the mysql daemon"
service mysql start
echo "navigating to volume /var/www"
cd /var/www
echo "Creating soft link"
ln -s /opt/mysite mysite
a2enmod headers
service apache2 restart
a2ensite mysite.conf
a2dissite 000-default.conf
service apache2 reload
if [ -z "$1" ]
then
exec "/usr/sbin/apache2 -D -foreground"
else
exec "$1"
fi
Upvotes: 5
Reputation: 2137
The following documentation from the Docker website shows how to implement an SSH service in a docker container. It should be easily adaptable for your service:
A variation on this question has also been asked here:
Upvotes: 0
Reputation: 207
Simple! Add at the end of dockerfile:
ENTRYPOINT service mysql start && /bin/bash
Upvotes: 19