Install mysql in dockerfile?
Question: I want to write simple python application and put in docker conteiner with
dockerfile. My dockerfile is:

    
    
    FROM ubuntu:saucy
    
    # Install required packages
    RUN apt-get update
    RUN DEBIAN_FRONTEND=noninteractive apt-get -y install python
    RUN DEBIAN_FRONTEND=noninteractive apt-get -y install mysql-server python-mysqldb
    
    # Add our python app code to the image
    RUN mkdir -p /app
    ADD . /app
    WORKDIR /app
    
    # Set the default command to execute
    CMD ["python", "main.py"]
    

In my python application I only want to connect to the database. main.py look
something like this:

    
    
    import MySQLdb as db
    
    connection = db.connect(
                    host='localhost',
                    port=3306,
                    user='root',
                    passwd='password',
                )
    

When I built docker image with:

    
    
    docker build -t myapp .
    

and run docker image with:

    
    
    docker run -i myapp
    

I got error:

    
    
    _mysql_exceptions.OperationalError: (2002, "Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock' (2)")
    

What is the problem?


Answer: The problem is that you've never started the database - you need to explicitly
start services in most Docker images. But if you want to run two processes in
Docker (the DB and your python program), things get a little more complex. You
either have to use a process manager like supervisor, or be a bit cleverer in
your start-up script.

To see what I mean, create the following script, and call it `cmd.sh`:

    
    
    #!/bin/bash
    
    mysqld &
    python main.py
    

Add it to the Dockerfile:

    
    
    FROM ubuntu:saucy
    
    # Install required packages
    RUN apt-get update
    RUN DEBIAN_FRONTEND=noninteractive apt-get -y install python
    RUN DEBIAN_FRONTEND=noninteractive apt-get -y install mysql-server python-mysqldb
    
    # Add our python app code to the image
    RUN mkdir -p /app
    ADD . /app
    WORKDIR /app
    
    # Set the default command to execute
    COPY cmd.sh /cmd.sh
    RUN chmod +x /cmd.sh
    CMD cmd.sh
    

Now build and try again. (Apologies if this doesn't work, it's off the top of
my head and I haven't tested it).

Note that this is _not_ a good solution; mysql will not be getting signals
proxied to it, so probably won't shutdown properly when the container stops.
You could fix this by using a process manager like supervisor, but the easiest
and best solution is to use separate containers. You can find stock containers
for [mysql](https://registry.hub.docker.com/_/mysql/) and also for
[python](https://registry.hub.docker.com/_/python/), which would save you a
lot of trouble. To do this:

  1. Take the mysql installation stuff out of the Dockerfile
  2. Change `localhost` in your python code to `mysql` or whatever you want to call your MySQL container.
  3. Start a MySQL container with something like `docker run -d --name mysql mysql`
  4. Start your container and link to the mysql container e.g: `docker run myapp --link mysql:mysql`

