2

I am learning docker these days. And I want to install mysql inside docker container.

Here is my Dockerfile

FROM ubuntu:14.04

ADD ./setup_mysql.sh /setup_mysql.sh
RUN chmod 755 /setup_mysql.sh
RUN /setup_mysql.sh

EXPOSE 3306

CMD ["/usr/sbin/mysqld"]

and shell script setup_mysql.sh

apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y mysql-server

sed -i -e "s/^bind-address\s*=\s*127.0.0.1/bind-address = 0.0.0.0/" /etc/mysql/my.cnf

service mysql start &
sleep 5

echo "UPDATE mysql.user SET password=PASSWORD('rootpass') WHERE user='root'" | mysql
echo "CREATE DATABASE devdb" | mysql
echo "GRANT ALL ON devdb.* TO devuser @'%' IDENTIFIED BY 'devpass'" | mysql

sleep 5
service mysql stop

Something wrong happend when running sudo docker build -t test/devenv .

Setting up mysql-server-5.5 (5.5.38-0ubuntu0.14.04.1) ...
invoke-rc.d: policy-rc.d denied execution of stop.
invoke-rc.d: policy-rc.d denied execution of start.

And if I remove the second sleep 5, the command service mysql stop will throw

ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock' (2)

Why does this happen?

Thank you!

San Lee
  • 59
  • 1
  • 10
  • Installing mysql as part of the container startup is bad. IMO. Put the install in the DOCKERFILE. – user2105103 Jan 14 '15 at 20:08
  • 1
    In official Debian image `/usr/sbin/policy-rc.d` has a comment explaining this behaviour. Workaround is [simple](http://www.monblocnotes.com/node/2057), but [this answer](http://stackoverflow.com/a/25150809/2072035) gives better explanation of the problem and solution. – saaj Apr 20 '15 at 13:04
  • thanks! sorry for the late – San Lee Jun 20 '15 at 17:57

3 Answers3

1

I high recommend leveraging the work of others. For example checkout the Mysql image from the docker registry:

Here's the associated git repository files:

If you look into the Dockerfile you'll notice the software is being installed as expected:

.. apt-get update && apt-get install -y mysql-server="${MYSQL_VERSION}"* ..

The trick is to realize that a database instance is not the same thing as the database software, only the latter is shipped with the image. Creating DBs and loading them with data is something that is done at run-time. So that work is done by an extra script, pulled into the image and setup to be executed when you run the container:

COPY docker-entrypoint.sh /entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"]

Hope this helps.

Mark O'Connor
  • 76,015
  • 10
  • 139
  • 185
  • Thanks Mark. You are right. But I just want to go through a small example to try to learn docker:) – San Lee Jul 29 '14 at 03:25
  • @SanLee Certainly. My point was that some there's lots of examples out there to emulate. The need to run services in the foreground is a common docker "gotcha" :-) – Mark O'Connor Jul 29 '14 at 17:36
  • yep. Right now I can connect to the mysql service. But there still are two problems left... – San Lee Jul 30 '14 at 00:09
  • @Mark It would be super helpful if you could explain the source of the error messages (I suspect the apt-get install is trying to start a service and it's not allowed?) and how your solution corrects the problem (I suspect it doesn't prevent the error, but ensures the service is run as a foreground task instead of a daemon) – The Trav Jan 14 '15 at 02:40
  • @TheTrav Refactored my answer. The Docker github links changed. Sorry if I mislead you. I realised your failure to connect was in fact during the build process, rather than a runtime error. – Mark O'Connor Jan 14 '15 at 19:59
  • It's a good answer to the question. I was looking at it in my first day of trying docker, there's a bit of a mental shift to get the "build time vs run time" stuff sorted that isn't necessarily apparent just from the existing docker files (you need to read docs as well) – The Trav Jan 16 '15 at 23:35
0

Add this to your dockerfile:

RUN su
RUN echo exit 0 > /usr/sbin/policy-rc.d

I was facing the same issue. This code fixed it.

sheldonzy
  • 5,505
  • 9
  • 48
  • 86
0

Here is a good post which tries to root cause the issue you are facing.

Shorter way:

  1. RUN echo "#!/bin/sh\nexit 0" > /usr/sbin/policy-rc.d should resolve your issue OR

  2. If that doesn't resolve the issue, try running your docker container with privileged option. Like this, docker run --privileged -d -ti DOCKER_IMAGE:TAG

Ideally, I would not recommend running container with privileged option unless its a test bed container. The reason being running a docker container with privileged gives all capabilities to the container, and it also lifts all the limitations enforced. In other words, the container can then do almost everything that the host can do. But this is not a good practice. This defeats the docker purpose of isolating from host machine.

The ideal way to do this is to set capabilities of your docker container based on what you want to achieve. Googling this should help you out to provide appropriate capability for your docker container.

Nikhil Katre
  • 2,114
  • 23
  • 22