I am trying to run integration tests (in python) which depend on mysql. Currently they depend on SQL running locally, but I want them to depend on a MySQL running in docker.
Contents of Dockerfile:
ADD . /opt/workdir
RUN python setup.py install
docker-compose run my_common_package python testsql.py
pymysql.err.OperationalError: (2003, "Can't connect to MySQL server on
'localhost' ([Errno 99] Cannot assign requested address)")
docker-compose will by default create virtual network were all the containers/services in the compose file can reach each other by an IP address. By using
depends_on or network aliases they can reach each other by host name. In your case the host name is the service name, but this can be overridden. (see: docs)
Your script in
my_common_package container/service should then connect to
mysql on port
3306 according to your setup. (not
localhost on port
Also note that using
expose is only necessary if the Dockerfile for the service don't have an
EXPOSE statement. The standard mysql image already does this.
If you want to map a container port to
localhost you need to use
ports, but only do this if it's necessary.
services: mysql: image: mysql:5.6 container_name: test_mysql_container environment: - MYSQL_ROOT_PASSWORD=test - MYSQL_DATABASE=My_Database - MYSQL_USER=my_user - MYSQL_PASSWORD=my_password volumes: - db_data:/var/lib/mysql ports: - "3306:3306"
Here we are saying that port 3306 in the mysql container should be mapped to localhost on port 3306.
Now you can connect to mysql using
localhost:3306 outside of docker. For example you can try to run your
testsql.py locally (NOT in a container).
Container to container communication will always happen using the host name of each container. Think of containers as virtual machines.
You can even find the network docker-compose created using
docker network list:
1b1a54630639 myproject_default bridge local 82498fd930bb bridge bridge local
.. then use
docker network inspect <id> to look at the details.
Assigned IP addresses to containers can be pretty random, so the only viable way for container to container communication is using hostnames.