12

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?

Vladimir Fejsov
  • 579
  • 3
  • 7
  • 16
  • Err, the database isn't running? It would be easier and make more sense to put the DB in a separate container. – Adrian Mouat Apr 02 '15 at 19:30
  • I do not understand. How to run database. If I install mysql on my host computer, and try to connect to database on my host it working as it should to work. Is that mean that database on my host is running? – Vladimir Fejsov Apr 02 '15 at 19:39
  • You should've just search for your error message: [1](http://stackoverflow.com/q/11657829/484666), [2](http://stackoverflow.com/q/11990708/484666), [3](http://stackoverflow.com/q/11443504/484666) - it is not related to Docker or the way you use it. – scriptin Apr 02 '15 at 20:12
  • It's just that the db isn't started by default in Docker like it is in Ubuntu normally. – Adrian Mouat Apr 02 '15 at 20:41

1 Answers1

11

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 and also for 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
Adrian Mouat
  • 44,585
  • 16
  • 110
  • 102