I have a Dockerized django application I am running and I am trying to connect it to a mysql server I have that is port forwarded from another docker container. I have done a sanity test already and confirmed that I can connect to my mysql server using mysql workbench on my localhost.
I have my dockerized django application running on network_mode: host
so I thought I would be able to simply connect. Sadly I currently error out on docker-compose build
with the error django.db.utils.OperationalError: (2002, "Can't connect to MySQL server on '127.0.0.1' (115)")
An accepted resolution to this issue means that my dockerized django application would be able to connect successfully to my mysql server running localhost:29998
SETTINGS.PY (Django Application)
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'mytestdb',
'USER': 'userone',
'PASSWORD': 'password',
'HOST': '127.0.0.1',
'PORT': '29998',
}
}
DJANGO App compose file
version: '3.3'
services:
mydjangoapp:
container_name: mydjangoapp
restart: always
env_file: .env
build: .
volumes:
- ./apps:/apps
- ./core:/core
network_mode: host
Django app dockerfile:
FROM python:3.9
COPY . .
# set environment variables
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1
COPY requirements.txt .
# install python dependencies
RUN pip install --upgrade pip
RUN pip install --no-cache-dir -r requirements.txt
# running migrations
RUN python manage.py migrate
# gunicorn
CMD ["gunicorn", "--config", "gunicorn-cfg.py", "core.wsgi"]
Dockerized mysql server (port forwarded to localhost)
version: '3.3'
services:
mysql:
image: mysql:latest
container_name: mymysqlserver
environment:
- MYSQL_DATABASE=mytestdb
- MYSQL_USER=userone
- MYSQL_ROOT_PASSWORD=password
- MYSQL_PASSWORD=password
ports:
- 29998:3306
Do I need to create some sort of docker network / bridge for this to work? (never tried that before).
I have already attempted the following solutions: sol1 (network_mode=host), sol2,
CodePudding user response:
Why not put the two services in same docker compose file and run it from there, like this:
version: '3.3'
services:
mydjangoapp:
container_name: mydjangoapp
restart: always
env_file: .env
build: .
volumes:
- ./apps:/apps
- ./core:/core
network_mode: host
depends_on: mysql
mysql:
image: mysql:latest
container_name: mymysqlserver
environment:
- MYSQL_DATABASE=mytestdb
- MYSQL_USER=userone
- MYSQL_ROOT_PASSWORD=password
- MYSQL_PASSWORD=password
ports:
- 29998:3306
And then update the settings like this:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'mytestdb',
'USER': 'userone',
'PASSWORD': 'password',
'HOST': 'mysql',
'PORT': '3306',
}
}
In that way, the communication between Django and MySQL will be done through docker network, rather than accessing the host machine network.
Apart from that, you need to change the Dockerfile, so that the migration runs after the MySQL server is running. To ensure that, you can add the migration command in the CMD part:
CMD ["sh", "-c", "python manage.py migrate;gunicorn --config gunicorn-cfg.py core.wsgi"]
CodePudding user response:
You django app is not working because:
You are running the containers in separated docker-compose files, this causes django container runs in different network than mysql container.
You are trying to connect to localhost (127.0.0.1) inside the django container. This localhost is different to 'localhost' of your computer and is different to the 'localhost' of mysql container. There are 3 different networks. If you want to connect django container with mysql container use the same network (docker network or your computer IP assigned by a router also will works).
You are trying to connect to the exposed port 29998, but this port is exposed from mysql container to your computer. If you are trying to make an internal connection you should use 3306. (If you are using an internal connection, then you don't need to expose the port)