Django cannot connect to mysql - mysql

So i put my django app and mysql inside docker container. Here is what i do
Docker file
FROM python:3
ENV PYTHONUNBUFFERED 1
WORKDIR /app
COPY requirements.txt /app/requirements.txt
RUN pip install -r requirements.txt
COPY . /app
and here is my docker-compose-yml
version: '3'
services:
db:
container_name: database
image: mysql:8
ports:
- "3306:3306"
command: --default-authentication-plugin=mysql_native_password
environment:
- MYSQL_DATABASE=django_example
- MYSQL_USER=root
- MYSQL_PASSWORD=123456
- MYSQL_ROOT_PASSWORD=123456
- MYSQL_ROOT_HOST=%
volumes:
- "./db:/var/lib/mysql"
web:
container_name: app
build: .
command: python manage.py runserver 0.0.0.0:8000
ports:
- "8000:8000"
volumes:
- .:/app
- /tmp/app/mysqld:/run/mysqld
depends_on:
- db
Then i run it with docker-compose up
I get this error
MySQLdb._exceptions.OperationalError: (2002, "Can't connect to local
MySQL server through socket '/var/run/mysqld/mysqld.sock' (2)")
Here is my database setting
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'django_example',
'USER': 'root',
'PASSWORD': '123456',
'HOST': 'localhost',
'PORT': '3306',
}
}
My docker ps --all
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
c61ac60bc037 mysql:latest "docker-entrypoint.s…" 2 minutes ago Up 34 seconds 0.0.0.0:3306->3306/tcp, 33060/tcp py_rest_api_db_1
f00857755a46 py_rest_api_web "python manage.py ru…" 5 minutes ago Up 34 seconds 0.0.0.0:8000->8000/tcp py_rest_api_web_1
So how can i fix it ? did i miss something?
Full Log
Starting database ... done
Starting app ... done
Attaching to database, app
database | 2020-10-23 06:03:42+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 8.0.22-1debian10 started.
database | 2020-10-23 06:03:42+00:00 [Note] [Entrypoint]: Switching to dedicated user 'mysql'
database | 2020-10-23 06:03:42+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 8.0.22-1debian10 started.
database | 2020-10-23T06:03:43.191491Z 0 [System] [MY-010116] [Server] /usr/sbin/mysqld (mysqld 8.0.22) starting as process 1
database | 2020-10-23T06:03:43.199528Z 0 [Warning] [MY-010159] [Server] Setting lower_case_table_names=2 because file system for /var/lib/mysql/ is case insensitive
database | 2020-10-23T06:03:43.214677Z 1 [System] [MY-013576] [InnoDB] InnoDB initialization has started.
app | Watching for file changes with StatReloader
app | Performing system checks...
app |
app | System check identified no issues (0 silenced).
app | Exception in thread django-main-thread:
app | Traceback (most recent call last):
app | File "/usr/local/lib/python3.9/site-packages/django/db/backends/base/base.py", line 219, in ensure_connection
app | self.connect()
app | File "/usr/local/lib/python3.9/site-packages/django/utils/asyncio.py", line 26, in inner
app | return func(*args, **kwargs)
app | File "/usr/local/lib/python3.9/site-packages/django/db/backends/base/base.py", line 200, in connect
app | self.connection = self.get_new_connection(conn_params)
app | File "/usr/local/lib/python3.9/site-packages/django/utils/asyncio.py", line 26, in inner
app | return func(*args, **kwargs)
app | File "/usr/local/lib/python3.9/site-packages/django/db/backends/mysql/base.py", line 234, in get_new_connection
app | return Database.connect(**conn_params)
app | File "/usr/local/lib/python3.9/site-packages/MySQLdb/__init__.py", line 130, in Connect
app | return Connection(*args, **kwargs)
app | File "/usr/local/lib/python3.9/site-packages/MySQLdb/connections.py", line 185, in __init__
app | super().__init__(*args, **kwargs2)
app | MySQLdb._exceptions.OperationalError: (2002, "Can't connect to MySQL server on 'db' (115)")
app |
app | The above exception was the direct cause of the following exception:
app |
app | Traceback (most recent call last):
app | File "/usr/local/lib/python3.9/threading.py", line 950, in _bootstrap_inner
app | self.run()
app | File "/usr/local/lib/python3.9/threading.py", line 888, in run
app | self._target(*self._args, **self._kwargs)
app | File "/usr/local/lib/python3.9/site-packages/django/utils/autoreload.py", line 53, in wrapper
app | fn(*args, **kwargs)
app | File "/usr/local/lib/python3.9/site-packages/django/core/management/commands/runserver.py", line 121, in inner_run
app | self.check_migrations()
app | File "/usr/local/lib/python3.9/site-packages/django/core/management/base.py", line 459, in check_migrations
app | executor = MigrationExecutor(connections[DEFAULT_DB_ALIAS])
app | File "/usr/local/lib/python3.9/site-packages/django/db/migrations/executor.py", line 18, in __init__
app | self.loader = MigrationLoader(self.connection)
app | File "/usr/local/lib/python3.9/site-packages/django/db/migrations/loader.py", line 53, in __init__
app | self.build_graph()
app | File "/usr/local/lib/python3.9/site-packages/django/db/migrations/loader.py", line 216, in build_graph
app | self.applied_migrations = recorder.applied_migrations()
app | File "/usr/local/lib/python3.9/site-packages/django/db/migrations/recorder.py", line 77, in applied_migrations
app | if self.has_table():
app | File "/usr/local/lib/python3.9/site-packages/django/db/migrations/recorder.py", line 55, in has_table
app | with self.connection.cursor() as cursor:
app | File "/usr/local/lib/python3.9/site-packages/django/utils/asyncio.py", line 26, in inner
app | return func(*args, **kwargs)
app | File "/usr/local/lib/python3.9/site-packages/django/db/backends/base/base.py", line 259, in cursor
app | return self._cursor()
app | File "/usr/local/lib/python3.9/site-packages/django/db/backends/base/base.py", line 235, in _cursor
app | self.ensure_connection()
app | File "/usr/local/lib/python3.9/site-packages/django/utils/asyncio.py", line 26, in inner
app | return func(*args, **kwargs)
app | File "/usr/local/lib/python3.9/site-packages/django/db/backends/base/base.py", line 219, in ensure_connection
app | self.connect()
app | File "/usr/local/lib/python3.9/site-packages/django/db/utils.py", line 90, in __exit__
app | raise dj_exc_value.with_traceback(traceback) from exc_value
app | File "/usr/local/lib/python3.9/site-packages/django/db/backends/base/base.py", line 219, in ensure_connection
app | self.connect()
app | File "/usr/local/lib/python3.9/site-packages/django/utils/asyncio.py", line 26, in inner
app | return func(*args, **kwargs)
app | File "/usr/local/lib/python3.9/site-packages/django/db/backends/base/base.py", line 200, in connect
app | self.connection = self.get_new_connection(conn_params)
app | File "/usr/local/lib/python3.9/site-packages/django/utils/asyncio.py", line 26, in inner
app | return func(*args, **kwargs)
app | File "/usr/local/lib/python3.9/site-packages/django/db/backends/mysql/base.py", line 234, in get_new_connection
app | return Database.connect(**conn_params)
app | File "/usr/local/lib/python3.9/site-packages/MySQLdb/__init__.py", line 130, in Connect
app | return Connection(*args, **kwargs)
app | File "/usr/local/lib/python3.9/site-packages/MySQLdb/connections.py", line 185, in __init__
app | super().__init__(*args, **kwargs2)
app | django.db.utils.OperationalError: (2002, "Can't connect to MySQL server on 'db' (115)")
database | 2020-10-23T06:03:45.429683Z 1 [System] [MY-013577] [InnoDB] InnoDB initialization has ended.
database | 2020-10-23T06:03:45.557475Z 0 [System] [MY-011323] [Server] X Plugin ready for connections. Bind-address: '::' port: 33060, socket: /var/run/mysqld/mysqlx.sock
database | 2020-10-23T06:03:45.635937Z 0 [System] [MY-010229] [Server] Starting XA crash recovery...
database | 2020-10-23T06:03:45.639397Z 0 [System] [MY-010232] [Server] XA crash recovery finished.
database | 2020-10-23T06:03:45.805023Z 0 [Warning] [MY-010068] [Server] CA certificate ca.pem is self signed.
database | 2020-10-23T06:03:45.805494Z 0 [System] [MY-013602] [Server] Channel mysql_main configured to support TLS. Encrypted connections are now supported for this channel.
database | 2020-10-23T06:03:45.818355Z 0 [Warning] [MY-011810] [Server] Insecure configuration for --pid-file: Location '/var/run/mysqld' in the path is accessible to all OS users. Consider choosing a different directory.
database | 2020-10-23T06:03:45.855862Z 0 [System] [MY-010931] [Server] /usr/sbin/mysqld: ready for connections. Version: '8.0.22' socket: '/var/run/mysqld/mysqld.sock' port: 3306 MySQL Community Server - GPL.

Your Database settings has HOST set to localhost. when your django service spins up in container, service will look for mysql on the same container (django) instead of connecting to actual mysql container.
Change the HOST value to db (db container name).
Add a depends_on to web in docker compose, to make sure web container waits for db to be up and running.
You may also need to set MYSQL_ROOT_HOST=% environment variable in mysql container to allow mysql to accept remote connections.
Edit
You can try using below options to wait for db container to be up.
use wait-for-sh as suggested in docker official docs
or try the approach here

In your Django settings.py file, change localhost to 127.0.0.1
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'django_example',
'USER': 'root',
'PASSWORD': '123456',
'HOST': '127.0.0.1', # <- Change here
'PORT': '3306',
}
}
Also make sure you are running the docker image with --net=host.
docker run --net=host [image-name]

Related

Docker compose error with hue and mysql - 1130, "Host '172.20.0.3' is not allowed to connect to this MySQL server"

I need help to connect hue with my database. When I run docker-compose up, the hue down/fail.
docker-compose.yml
hue:
image: hue
hostname: hue
container_name: hue
dns: 8.8.8.8
ports:
- "8888:8888"
volumes:
- ./data/hue/hue-overrides.ini:/usr/share/hue/desktop/conf/z-hue.ini
depends_on:
- "database"
deploy:
resources:
limits:
memory: 500m
database:
image: mysql
container_name: database
hostname: database
ports:
- "33061:3306"
deploy:
resources:
limits:
memory: 500m
command: mysqld --innodb-flush-method=O_DSYNC --innodb-use-native-aio=OFF --init-file /data/application/init.sql
volumes:
- ./data/mysql/data:/var/lib/mysql
- ./data/init.sql:/data/application/init.sql
environment:
MYSQL_ROOT_USER: root
MYSQL_ROOT_PASSWORD: secret
MYSQL_DATABASE: hue
MYSQL_USER: root
MYSQL_PASSWORD: secret
Docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
41a3cbb80704 mysql "docker-entrypoint.s…" 19 seconds ago Up 18 seconds 33060/tcp, 0.0.0.0:33061->3306/tcp, :::33061->3306/tcp database
Log:
hue | [02/Oct/2022 13:34:51 -0700] decorators INFO Using django-axes 2.2.0
hue | Traceback (most recent call last):
hue | File "./build/env/bin/hue", line 11, in <module>
hue | load_entry_point('desktop', 'console_scripts', 'hue')()
hue | File "/usr/share/hue/desktop/core/src/desktop/manage_entry.py", line 225, in entry
hue | execute_from_command_line(sys.argv)
hue | File "/usr/share/hue/build/env/local/lib/python2.7/site-packages/Django-1.11.22-py2.7.egg/django/core/management/__init__.py", line 364, in execute_from_command_line
hue | utility.execute()
hue | File "/usr/share/hue/build/env/local/lib/python2.7/site-packages/Django-1.11.22-py2.7.egg/django/core/management/__init__.py", line 356, in execute
hue | self.fetch_command(subcommand).run_from_argv(self.argv)
hue | File "/usr/share/hue/build/env/local/lib/python2.7/site-packages/Django-1.11.22-py2.7.egg/django/core/management/base.py", line 283, in run_from_argv
hue | self.execute(*args, **cmd_options)
hue | File "/usr/share/hue/build/env/local/lib/python2.7/site-packages/Django-1.11.22-py2.7.egg/django/core/management/base.py", line 327, in execute
hue | self.check()
hue | File "/usr/share/hue/build/env/local/lib/python2.7/site-packages/Django-1.11.22-py2.7.egg/django/core/management/base.py", line 359, in check
hue | include_deployment_checks=include_deployment_checks,
hue | File "/usr/share/hue/build/env/local/lib/python2.7/site-packages/Django-1.11.22-py2.7.egg/django/core/management/commands/migrate.py", line 61, in _run_checks
hue | issues = run_checks(tags=[Tags.database])
hue | File "/usr/share/hue/build/env/local/lib/python2.7/site-packages/Django-1.11.22-py2.7.egg/django/core/checks/registry.py", line 81, in run_checks
hue | new_errors = check(app_configs=app_configs)
hue | File "/usr/share/hue/build/env/local/lib/python2.7/site-packages/Django-1.11.22-py2.7.egg/django/core/checks/database.py", line 10, in check_database_backends
hue | issues.extend(conn.validation.check(**kwargs))
hue | File "/usr/share/hue/build/env/local/lib/python2.7/site-packages/Django-1.11.22-py2.7.egg/django/db/backends/mysql/validation.py", line 9, in check
hue | issues.extend(self._check_sql_mode(**kwargs))
hue | File "/usr/share/hue/build/env/local/lib/python2.7/site-packages/Django-1.11.22-py2.7.egg/django/db/backends/mysql/validation.py", line 13, in _check_sql_mode
hue | with self.connection.cursor() as cursor:
hue | File "/usr/share/hue/build/env/local/lib/python2.7/site-packages/Django-1.11.22-py2.7.egg/django/db/backends/base/base.py", line 254, in cursor
hue | return self._cursor()
hue | File "/usr/share/hue/build/env/local/lib/python2.7/site-packages/Django-1.11.22-py2.7.egg/django/db/backends/base/base.py", line 229, in _cursor
hue | self.ensure_connection()
hue | File "/usr/share/hue/build/env/local/lib/python2.7/site-packages/Django-1.11.22-py2.7.egg/django/db/backends/base/base.py", line 213, in ensure_connection
hue | self.connect()
hue | File "/usr/share/hue/build/env/local/lib/python2.7/site-packages/Django-1.11.22-py2.7.egg/django/db/utils.py", line 94, in __exit__
hue | six.reraise(dj_exc_type, dj_exc_value, traceback)
hue | File "/usr/share/hue/build/env/local/lib/python2.7/site-packages/Django-1.11.22-py2.7.egg/django/db/backends/base/base.py", line 213, in ensure_connection
hue | self.connect()
hue | File "/usr/share/hue/build/env/local/lib/python2.7/site-packages/Django-1.11.22-py2.7.egg/django/db/backends/base/base.py", line 189, in connect
hue | self.connection = self.get_new_connection(conn_params)
hue | File "/usr/share/hue/build/env/local/lib/python2.7/site-packages/Django-1.11.22-py2.7.egg/django/db/backends/mysql/base.py", line 274, in get_new_connection
hue | conn = Database.connect(**conn_params)
hue | File "/usr/share/hue/build/env/local/lib/python2.7/site-packages/MySQL_python-1.2.5-py2.7-linux-x86_64.egg/MySQLdb/__init__.py", line 81, in Connect
hue | return Connection(*args, **kwargs)
hue | File "/usr/share/hue/build/env/local/lib/python2.7/site-packages/MySQL_python-1.2.5-py2.7-linux-x86_64.egg/MySQLdb/connections.py", line 193, in __init__
hue | super(Connection, self).__init__(*args, **kwargs2)
hue | django.db.utils.OperationalError: (1130, "Host '172.21.0.3' is not allowed to connect to this MySQL server")
This is my local mysql:
mysql> SELECT host FROM mysql.user WHERE User = 'root';
+-----------+
| host |
+-----------+
| % |
| localhost |
+-----------+
2 rows in set (0,00 sec)
When I run docker exec -it database bash:
$ docker exec -it database bash
root#database:/# mysql -u root -p
Enter password:
ERROR 1045 (28000): Access denied for user 'root'#'localhost' (using password: YES)
Can someone please help me?
The error message is:
Host '172.21.0.3' is not allowed to connect to this MySQL server
So you have to create a new user and allow access from anywhere(%) and grant the necessary permissions to it:
CREATE USER 'hueuser'#'localhost' IDENTIFIED BY 'mysafepass';
CREATE USER 'hueuser'#'%' IDENTIFIED BY 'mysafepass';
GRANT ALL ON *.* TO 'hueuser'#'localhost';
GRANT ALL ON *.* TO 'hueuser'#'%';
FLUSH PRIVILEGES;

django.db.utils.OperationalError: (1045, 'Plugin caching_sha2_password could not be

I'm trying to containerize my Django app with mysql and I get the following error when I try to run docker-compose up --build.
Successfully tagged drosmokers_web:latest
[+] Running 3/2
⠿ Network drosmokers_default Created 0.1s
⠿ Container drosmokers-db-1 Created 0.3s
⠿ Container drosmokers-web-1 Created 0.1s
Attaching to drosmokers-db-1, drosmokers-web-1
drosmokers-db-1 | 2022-05-19 02:09:40+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 8.0.28-1debian10 started.
drosmokers-db-1 | 2022-05-19 02:09:40+00:00 [Note] [Entrypoint]: Switching to dedicated user 'mysql'
drosmokers-db-1 | 2022-05-19 02:09:40+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 8.0.28-1debian10 started.
drosmokers-db-1 | 2022-05-19T02:09:40.450429Z 0 [System] [MY-010116] [Server] /usr/sbin/mysqld (mysqld 8.0.28) starting as process 1
drosmokers-db-1 | 2022-05-19T02:09:40.459416Z 1 [System] [MY-013576] [InnoDB] InnoDB initialization has started.
drosmokers-db-1 | 2022-05-19T02:09:40.971548Z 1 [System] [MY-013577] [InnoDB] InnoDB initialization has ended.
drosmokers-db-1 | 2022-05-19T02:09:41.218218Z 0 [Warning] [MY-010068] [Server] CA certificate ca.pem is self signed.
drosmokers-db-1 | 2022-05-19T02:09:41.218279Z 0 [System] [MY-013602] [Server] Channel mysql_main configured to support TLS. Encrypted connections are now supported for this channel.
drosmokers-db-1 | 2022-05-19T02:09:41.229850Z 0 [Warning] [MY-011810] [Server] Insecure configuration for --pid-file: Location '/var/run/mysqld' in the path is accessible to all OS users. Consider choosing a different directory.
drosmokers-db-1 | 2022-05-19T02:09:41.261835Z 0 [System] [MY-010931] [Server] /usr/sbin/mysqld: ready for connections. Version: '8.0.28' socket: '/var/run/mysqld/mysqld.sock' port: 3306 MySQL Community Server - GPL.
drosmokers-db-1 | 2022-05-19T02:09:41.262088Z 0 [System] [MY-011323] [Server] X Plugin ready for connections. Bind-address: '::' port: 33060, socket: /var/run/mysqld/mysqlx.sock
drosmokers-web-1 | Watching for file changes with StatReloader
drosmokers-web-1 | Exception in thread django-main-thread:
drosmokers-web-1 | Traceback (most recent call last):
drosmokers-web-1 | File "/usr/local/lib/python3.9/site-packages/django/db/backends/base/base.py", line 244, in ensure_connection
drosmokers-web-1 | self.connect()
drosmokers-web-1 | File "/usr/local/lib/python3.9/site-packages/django/utils/asyncio.py", line 26, in inner
drosmokers-web-1 | return func(*args, **kwargs)
drosmokers-web-1 | File "/usr/local/lib/python3.9/site-packages/django/db/backends/base/base.py", line 225, in connect
drosmokers-web-1 | self.connection = self.get_new_connection(conn_params)
drosmokers-web-1 | File "/usr/local/lib/python3.9/site-packages/django/utils/asyncio.py", line 26, in inner
drosmokers-web-1 | return func(*args, **kwargs)
drosmokers-web-1 | File "/usr/local/lib/python3.9/site-packages/django/db/backends/mysql/base.py", line 244, in get_new_connection
drosmokers-web-1 | connection = Database.connect(**conn_params)
drosmokers-web-1 | File "/usr/local/lib/python3.9/site-packages/MySQLdb/__init__.py", line 123, in Connect
drosmokers-web-1 | return Connection(*args, **kwargs)
drosmokers-web-1 | File "/usr/local/lib/python3.9/site-packages/MySQLdb/connections.py", line 185, in __init__
drosmokers-web-1 | super().__init__(*args, **kwargs2)
drosmokers-web-1 | MySQLdb._exceptions.OperationalError: (1045, 'Plugin caching_sha2_password could not be loaded: /usr/lib/x86_64-linux-gnu/mariadb19/plugin/caching_sha2_password.so: cannot open shared object file: No such file or directory')
drosmokers-web-1 |
drosmokers-web-1 | The above exception was the direct cause of the following exception:
drosmokers-web-1 |
drosmokers-web-1 | Traceback (most recent call last):
drosmokers-web-1 | File "/usr/local/lib/python3.9/threading.py", line 954, in _bootstrap_inner
drosmokers-web-1 | self.run()
drosmokers-web-1 | File "/usr/local/lib/python3.9/threading.py", line 892, in run
drosmokers-web-1 | self._target(*self._args, **self._kwargs)
drosmokers-web-1 | File "/usr/local/lib/python3.9/site-packages/django/utils/autoreload.py", line 64, in wrapper
drosmokers-web-1 | fn(*args, **kwargs)
drosmokers-web-1 | File "/usr/local/lib/python3.9/site-packages/django/core/management/commands/runserver.py", line 137, in inner_run
drosmokers-web-1 | self.check_migrations()
drosmokers-web-1 | File "/usr/local/lib/python3.9/site-packages/django/core/management/base.py", line 576, in check_migrations
drosmokers-web-1 | executor = MigrationExecutor(connections[DEFAULT_DB_ALIAS])
drosmokers-web-1 | File "/usr/local/lib/python3.9/site-packages/django/db/migrations/executor.py", line 18, in __init__
drosmokers-web-1 | self.loader = MigrationLoader(self.connection)
drosmokers-web-1 | File "/usr/local/lib/python3.9/site-packages/django/db/migrations/loader.py", line 58, in __init__
drosmokers-web-1 | self.build_graph()
drosmokers-web-1 | File "/usr/local/lib/python3.9/site-packages/django/db/migrations/loader.py", line 235, in build_graph
drosmokers-web-1 | self.applied_migrations = recorder.applied_migrations()
drosmokers-web-1 | File "/usr/local/lib/python3.9/site-packages/django/db/migrations/recorder.py", line 81, in applied_migrations
drosmokers-web-1 | if self.has_table():
drosmokers-web-1 | File "/usr/local/lib/python3.9/site-packages/django/db/migrations/recorder.py", line 57, in has_table
drosmokers-web-1 | with self.connection.cursor() as cursor:
drosmokers-web-1 | File "/usr/local/lib/python3.9/site-packages/django/utils/asyncio.py", line 26, in inner
drosmokers-web-1 | return func(*args, **kwargs)
drosmokers-web-1 | File "/usr/local/lib/python3.9/site-packages/django/db/backends/base/base.py", line 284, in cursor
drosmokers-web-1 | return self._cursor()
drosmokers-web-1 | File "/usr/local/lib/python3.9/site-packages/django/db/backends/base/base.py", line 260, in _cursor
drosmokers-web-1 | self.ensure_connection()
drosmokers-web-1 | File "/usr/local/lib/python3.9/site-packages/django/utils/asyncio.py", line 26, in inner
drosmokers-web-1 | return func(*args, **kwargs)
drosmokers-web-1 | File "/usr/local/lib/python3.9/site-packages/django/db/backends/base/base.py", line 244, in ensure_connection
drosmokers-web-1 | self.connect()
drosmokers-web-1 | File "/usr/local/lib/python3.9/site-packages/django/db/utils.py", line 91, in __exit__
drosmokers-web-1 | raise dj_exc_value.with_traceback(traceback) from exc_value
drosmokers-web-1 | File "/usr/local/lib/python3.9/site-packages/django/db/backends/base/base.py", line 244, in ensure_connection
drosmokers-web-1 | self.connect()
drosmokers-web-1 | File "/usr/local/lib/python3.9/site-packages/django/utils/asyncio.py", line 26, in inner
drosmokers-web-1 | return func(*args, **kwargs)
drosmokers-web-1 | File "/usr/local/lib/python3.9/site-packages/django/db/backends/base/base.py", line 225, in connect
drosmokers-web-1 | self.connection = self.get_new_connection(conn_params)
drosmokers-web-1 | File "/usr/local/lib/python3.9/site-packages/django/utils/asyncio.py", line 26, in inner
drosmokers-web-1 | return func(*args, **kwargs)
drosmokers-web-1 | File "/usr/local/lib/python3.9/site-packages/django/db/backends/mysql/base.py", line 244, in get_new_connection
drosmokers-web-1 | connection = Database.connect(**conn_params)
drosmokers-web-1 | File "/usr/local/lib/python3.9/site-packages/MySQLdb/__init__.py", line 123, in Connect
drosmokers-web-1 | return Connection(*args, **kwargs)
drosmokers-web-1 | File "/usr/local/lib/python3.9/site-packages/MySQLdb/connections.py", line 185, in __init__
drosmokers-web-1 | super().__init__(*args, **kwargs2)
drosmokers-web-1 | django.db.utils.OperationalError: (1045, 'Plugin caching_sha2_password could not be loaded: /usr/lib/x86_64-linux-gnu/mariadb19/pl
ugin/caching_sha2_password.so: cannot open shared object file: No such file or directory')
Here is my docker-compose.yml:
version: '3.9'
services:
db:
image: mysql
restart: always
environment:
- MYSQL_USER="dexter"
- MYSQL_PASSWORD="password"
- MYSQL_DATABASE="drosmokers_db"
- MYSQL_ROOT_PASSWORD="password"
volumes:
- dev_vol:/var/lib/mysql/
ports:
- 3305:3306
web:
build: .
command: python manage.py runserver 0.0.0.0:8000
volumes:
- .:/app
ports:
- "8000:8000"
depends_on:
- db
volumes:
dev_vol:
My Dockerifle:
FROM python:3
ENV PYTHONDONTWRITEBYTECODE=1
ENV PYTHONBUFFERED=1
WORKDIR /app
COPY requirements.txt /app/
RUN pip install -r requirements.txt
COPY . /app/
...and finally my settings.py:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'drosmokers_db',
'USER': 'root',
'PASSWORD': 'password',
'HOST': 'drosmokers-db-1', # the container name
'PORT': 3306
}
}
I don't know why I'm getting this error and what this error means. I've been able to successfully containerize this app before, but I really was just following instructions, not really knowing what was going on with each command. I spent the last hour trying to figure out why running docker-compose up --build produces this error : django.db.utils.OperationalError: (2002, "Can't connect to MySQL server on <database> (115), and now I get this error, and I don't even know what I did or where to start looking. Any help is greatly appreciated. Thanks!

"Error: Cannot find module 'mysql2/promise'" when running "docker-compose up"

I want to use docker compose to connect a node program, in one container, to a MySQL database, in another container. The database seems to start fine, but my index.js file throws an error: Cannot find module 'mysql2/promise'
I've tried installing different packages with npm, and even edited various lines in my package.json file in desperation, but to no avail; always the same error. Here are the relevant files, and the output of the commands that work so far.
$ npm install mysql2
npm WARN simplyanything#1.0.0 No repository field.
npm WARN simplyanything#1.0.0 No license field.
+ mysql2#2.3.3
updated 1 package and audited 101 packages in 3.302s
found 0 vulnerabilities
$ sudo npm install mysql2-promise
+ mysql2-promise#0.1.4
updated 1 package and audited 101 packages in 3.772s
found 0 vulnerabilities
package.json
{
"name": "simplyanything",
"version": "1.0.0",
"scripts": {
"start": "node index.js"
},
"description": "Actions party game",
"dependencies": {
"express": "^4.17.1",
"mysql2": "^2.3.3",
"mysql2-promise": "^0.1.4",
"socket.io": "^4.4.1"
},
"author": "Chris DeHaan"
}
index.js
const express = require('express');
let app = express();
let http = require('http').createServer(app);
const io = require('socket.io')(http, {pingTimeout: 60000});
app.use(express.static('public'));
app.get('/', (req, res) => { res.sendFile(__dirname + '/index.html'); });
http.listen(3000, () => { console.log('listening on *:3000'); });
const mysql = require('mysql2/promise');
const pool = mysql.createPool({
connectionLimit : 100,
host: process.env.MYSQL_HOST,
user: process.env.MYSQL_USER,
[.... and so on]
Dockerfile
FROM node:latest
WORKDIR /sa/
COPY package.json .
RUN npm install
COPY . .
docker-compose.yml
version: '3.8'
services:
web:
build:
context: .
env_file: ./.env
command: npm start
volumes:
- .:/sa/
- /sa/node_modules
ports:
- $NODE_LOCAL_PORT:$NODE_DOCKER_PORT
depends_on:
- mysqldb
environment:
MYSQL_HOST: mysqldb
mysqldb:
image: mysql
env_file: ./.env
environment:
MYSQL_ROOT_PASSWORD: $MYSQL_ROOT_PASSWORD
MYSQL_DATABASE: $MYSQL_DATABASE
ports:
- $MYSQL_LOCAL_PORT:$MYSQL_DOCKER_PORT
volumes:
- mysql:/var/lib/mysql
- mysql_config:/etc/mysql
volumes:
mysql:
mysql_config:
.env
MYSQL_USER=simplyanythingUser
MYSQL_ROOT_PASSWORD=[Well, you don't need to know this]
MYSQL_DATABASE=simplyanything
MYSQL_LOCAL_PORT=3306
MYSQL_DOCKER_PORT=3306
NODE_LOCAL_PORT=3000
NODE_DOCKER_PORT=3000
$ sudo docker build -t sa .
Sending build context to Docker daemon 9.526MB
Step 1/5 : FROM node:latest
---> e6bed6a65a54
Step 2/5 : WORKDIR /sa/
---> Using cache
---> 3da61e5a5928
Step 3/5 : COPY package.json .
---> Using cache
---> 1e7bbeaaa894
Step 4/5 : RUN npm install
---> Using cache
---> 52f36e54d698
Step 5/5 : COPY . .
---> e0a50567567b
Successfully built e0a50567567b
Successfully tagged sa:latest
$ node index.js
Debugger listening on ws://127.0.0.1:44273/a1b49bfc-83e7-47dd-ba53-64a8df19ccc9
For help, see: https://nodejs.org/en/docs/inspector
Debugger attached.
listening on *:3000
(and it works in the browser at this point)
$ sudo docker-compose up
Starting sa_mysqldb_1 ... done
Starting sa_web_1 ... done
Attaching to sa_mysqldb_1, sa_web_1
mysqldb_1 | 2022-02-08 08:31:21+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 8.0.28-1debian10 started.
mysqldb_1 | 2022-02-08 08:31:21+00:00 [Note] [Entrypoint]: Switching to dedicated user 'mysql'
mysqldb_1 | 2022-02-08 08:31:21+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 8.0.28-1debian10 started.
mysqldb_1 | 2022-02-08T08:31:21.660916Z 0 [System] [MY-010116] [Server] /usr/sbin/mysqld (mysqld 8.0.28) starting as process 1
mysqldb_1 | 2022-02-08T08:31:21.747461Z 1 [System] [MY-013576] [InnoDB] InnoDB initialization has started.
web_1 |
web_1 | > simplyanything#1.0.0 start
web_1 | > node index.js
web_1 |
mysqldb_1 | 2022-02-08T08:31:23.587278Z 1 [System] [MY-013577] [InnoDB] InnoDB initialization has ended.
web_1 | node:internal/modules/cjs/loader:936
web_1 | throw err;
web_1 | ^
web_1 |
web_1 | Error: Cannot find module 'mysql2/promise'
web_1 | Require stack:
web_1 | - /sa/index.js
web_1 | at Function.Module._resolveFilename (node:internal/modules/cjs/loader:933:15)
web_1 | at Function.Module._load (node:internal/modules/cjs/loader:778:27)
web_1 | at Module.require (node:internal/modules/cjs/loader:999:19)
web_1 | at require (node:internal/modules/cjs/helpers:102:18)
web_1 | at Object.<anonymous> (/sa/index.js:13:15)
web_1 | at Module._compile (node:internal/modules/cjs/loader:1097:14)
web_1 | at Object.Module._extensions..js (node:internal/modules/cjs/loader:1149:10)
web_1 | at Module.load (node:internal/modules/cjs/loader:975:32)
web_1 | at Function.Module._load (node:internal/modules/cjs/loader:822:12)
web_1 | at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:77:12) {
web_1 | code: 'MODULE_NOT_FOUND',
web_1 | requireStack: [ '/sa/index.js' ]
web_1 | }
web_1 |
web_1 | Node.js v17.4.0
mysqldb_1 | 2022-02-08T08:31:25.086275Z 0 [Warning] [MY-010068] [Server] CA certificate ca.pem is self signed.
mysqldb_1 | 2022-02-08T08:31:25.086445Z 0 [System] [MY-013602] [Server] Channel mysql_main configured to support TLS. Encrypted connections are now supported for this channel.
mysqldb_1 | 2022-02-08T08:31:25.277625Z 0 [Warning] [MY-011810] [Server] Insecure configuration for --pid-file: Location '/var/run/mysqld' in the path is accessible to all OS users. Consider choosing a different directory.
mysqldb_1 | 2022-02-08T08:31:25.354311Z 0 [System] [MY-011323] [Server] X Plugin ready for connections. Bind-address: '::' port: 33060, socket: /var/run/mysqld/mysqlx.sock
mysqldb_1 | 2022-02-08T08:31:25.355558Z 0 [System] [MY-010931] [Server] /usr/sbin/mysqld: ready for connections. Version: '8.0.28' socket: '/var/run/mysqld/mysqld.sock' port: 3306 MySQL Community Server - GPL.
I'm really stuck because everything it needs seems to be installed, and it works when I run it on the command line with node index.js so obviously there's something I'm missing in setting up my container, or getting compose to connect them. Any advice would be much appreciated. Cheers.
Good afternoon, I had the same problem. You could try to use
npm install mysql2

Python Flask SQLAlchemy container unable to connect to MySQL container

I am unable to connect to my MySQL database from Flask application.
I am learning to build web application with Python Flask from this tutorial but tried modifying some elements of it for experimenting with Docker. Even without using docker-compose, I was unable to connect to the database from the web application.
Let me first give the error traceback in the application log (flask_test container):
[2021-12-20 18:13:18 +0000] [1] [INFO] Starting gunicorn 20.1.0
[2021-12-20 18:13:18 +0000] [1] [INFO] Listening at: http://0.0.0.0:5000 (1)
[2021-12-20 18:13:18 +0000] [1] [INFO] Using worker: sync
[2021-12-20 18:13:18 +0000] [8] [INFO] Booting worker with pid: 8
[2021-12-20 18:13:19,105] INFO in __init__: Microblog startup
[2021-12-20 18:14:19,239] ERROR in app: Exception on /auth/register [POST]
Traceback (most recent call last):
File "/home/flasktest/venv/lib/python3.10/site-packages/urllib3/connection.py", line 174, in _new_conn
conn = connection.create_connection(
File "/home/flasktest/venv/lib/python3.10/site-packages/urllib3/util/connection.py", line 96, in create_connection
raise err
File "/home/flasktest/venv/lib/python3.10/site-packages/urllib3/util/connection.py", line 86, in create_connection
sock.connect(sa)
ConnectionRefusedError: [Errno 111] Connection refused
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/home/flasktest/venv/lib/python3.10/site-packages/elasticsearch/connection/http_urllib3.py", line 255, in perform_request
response = self.pool.urlopen(
File "/home/flasktest/venv/lib/python3.10/site-packages/urllib3/connectionpool.py", line 755, in urlopen
retries = retries.increment(
File "/home/flasktest/venv/lib/python3.10/site-packages/urllib3/util/retry.py", line 507, in increment
raise six.reraise(type(error), error, _stacktrace)
File "/home/flasktest/venv/lib/python3.10/site-packages/urllib3/packages/six.py", line 770, in reraise
raise value
File "/home/flasktest/venv/lib/python3.10/site-packages/urllib3/connectionpool.py", line 699, in urlopen
httplib_response = self._make_request(
File "/home/flasktest/venv/lib/python3.10/site-packages/urllib3/connectionpool.py", line 394, in _make_request
conn.request(method, url, **httplib_request_kw)
File "/home/flasktest/venv/lib/python3.10/site-packages/urllib3/connection.py", line 239, in request
super(HTTPConnection, self).request(method, url, body=body, headers=headers)
File "/usr/local/lib/python3.10/http/client.py", line 1282, in request
self._send_request(method, url, body, headers, encode_chunked)
File "/usr/local/lib/python3.10/http/client.py", line 1328, in _send_request
self.endheaders(body, encode_chunked=encode_chunked)
File "/usr/local/lib/python3.10/http/client.py", line 1277, in endheaders
self._send_output(message_body, encode_chunked=encode_chunked)
File "/usr/local/lib/python3.10/http/client.py", line 1037, in _send_output
self.send(msg)
File "/usr/local/lib/python3.10/http/client.py", line 975, in send
self.connect()
File "/home/flasktest/venv/lib/python3.10/site-packages/urllib3/connection.py", line 205, in connect
conn = self._new_conn()
File "/home/flasktest/venv/lib/python3.10/site-packages/urllib3/connection.py", line 186, in _new_conn
raise NewConnectionError(
urllib3.exceptions.NewConnectionError: <urllib3.connection.HTTPConnection object at 0x7f73470be7d0>: Failed to establish a new connection: [Errno 111] Connection refused
And this is the MySQL container (mysql_test) log:
2021-12-20T18:13:14.094155Z 0 [System] [MY-013602] [Server] Channel mysql_main configured to support TLS. Encrypted connections are now supported for this channel.
2021-12-20T18:13:14.098891Z 0 [Warning] [MY-011810] [Server] Insecure configuration for --pid-file: Location '/var/run/mysqld' in the path is accessible to all OS users. Consider choosing a different directory.
2021-12-20T18:13:14.110089Z 0 [System] [MY-011323] [Server] X Plugin ready for connections. Bind-address: '::' port: 33060, socket: /var/run/mysqld/mysqlx.sock
2021-12-20T18:13:14.110149Z 0 [System] [MY-010931] [Server] /usr/sbin/mysqld: ready for connections. Version: '8.0.27' socket: '/var/run/mysqld/mysqld.sock' port: 3306 MySQL Community Server - GPL.
mbind: Operation not permitted
mbind: Operation not permitted
2021-12-20 18:13:10+00:00 [Note] [Entrypoint]: Creating database test_db
2021-12-20 18:13:10+00:00 [Note] [Entrypoint]: Creating user test_user
2021-12-20 18:13:10+00:00 [Note] [Entrypoint]: Giving user test_user access to schema test_db
2021-12-20 18:13:10+00:00 [Note] [Entrypoint]: Stopping temporary server
2021-12-20 18:13:13+00:00 [Note] [Entrypoint]: Temporary server stopped
2021-12-20 18:13:13+00:00 [Note] [Entrypoint]: MySQL init process done. Ready for start up.
Here is the starting point of Python application (microblog.py):
from app_pkg import create_app, cli
app = create_app()
cli.register(app)
Here is the model class:
class User(UserMixin, SearchableMixin, db.Model):
__searchable__ = ['username']
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(64), index=True, unique=True)
email = db.Column(db.String(120), index=True, unique=True)
password_hash = db.Column(db.String(128))
posts = db.relationship('Post', backref='author', lazy='dynamic')
about_me = db.Column(db.String(140))
last_seen = db.Column(db.DateTime, default=datetime.utcnow)
followed = db.relationship(
'User', secondary=followers,
primaryjoin=(followers.c.follower_id == id),
secondaryjoin=(followers.c.followed_id == id),
backref=db.backref('followers', lazy='dynamic'), lazy='dynamic')
This is my compose.yaml:
version: '3'
services:
python_app:
container_name: flask_test
build: .
env_file: .env
ports:
- 8000:5000
links:
- mysqldb:dbserver
depends_on:
mysqldb:
condition: service_healthy
mysqldb:
container_name: mysql_test
image: mysql:latest
env_file: database.conf
volumes:
- db-data:/var/lib/mysql
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "127.0.0.1", "--silent"]
interval: 3s
retries: 5
start_period: 30s
volumes:
db-data:
This is my Dockerfile:
FROM python:slim
RUN useradd flasktest
WORKDIR /home/flasktest
COPY requirements.txt requirements.txt
RUN python -m venv venv
RUN venv/bin/pip install -r requirements.txt
RUN venv/bin/pip install gunicorn pymysql cryptography
COPY app_pkg app_pkg
COPY migrations migrations
COPY microblog.py config.py boot.sh ./
RUN chmod +x boot.sh
ENV FLASK_APP microblog.py
RUN chown -R flasktest:flasktest ./
USER flasktest
EXPOSE 5000
ENTRYPOINT ["./boot.sh"]
And finally, this is the boot.sh:
#!/bin/bash
source venv/bin/activate
while true; do
flask db upgrade
if [[ "$?" == "0" ]]; then
break
fi
echo Upgrade command failed, retrying in 5 secs...
sleep 5
done
exec gunicorn -b :5000 --access-logfile - --error-logfile - microblog:app
And these are some necessary environment variables that are being used in the application:
DATABASE_URL=mysql+pymysql://test_user:abc123#dbserver/test_db
MYSQL_ROOT_PASSWORD=root123
MYSQL_DATABASE=test_db
MYSQL_USER=test_user
MYSQL_PASSWORD=abc123
Sorry if the question has become too lengthy. I wanted to give as much detail as possible in the question. Let me know if any other details is required. I have been trying to debug this issue for the past week, but am unable to find a way to connect the app with the sql server.
Also let me know if I should try any specific method to try to debug this issue.
Edit:
create_app function:
from flask_sqlalchemy import SQLAlchemy
from flask_migrate import Migrate
from flask_login import LoginManager
from flask_mail import Mail
from flask_bootstrap import Bootstrap
from flask_moment import Moment
db = SQLAlchemy()
migrate = Migrate()
login = LoginManager()
login.login_view = 'auth.login'
login.login_message = _l('Please log in to access this page.')
mail = Mail()
bootstrap = Bootstrap()
moment = Moment()
def create_app(config_class=Config):
app = Flask(__name__)
app.config.from_object(config_class)
db.init_app(app)
migrate.init_app(app, db)
login.init_app(app)
mail.init_app(app)
bootstrap.init_app(app)
moment.init_app(app)
from app_pkg.errors import bp as errors_bp
app.register_blueprint(errors_bp)
from app_pkg.auth import bp as auth_bp
app.register_blueprint(auth_bp, url_prefix='/auth')
from app_pkg.main import bp as main_bp
app.register_blueprint(main_bp)
I tried changing DATABASE_URL from mysql+pymysql://test_user:abc123#dbserver/test_db to mysql+pymysql://test_user:abc123#mysqldb/test_db, but the issue still persists.
I also tried adding 'ports: -3306:3306' to compose.yaml and changing DATABASE_URL to 0.0.0.0 as host, but this is giving this error:
[+] Running 3/4
- Network flask_tutorial_default Created 0.7s
- Volume "flask_tutorial_db-data" Created 0.0s
- Container mysql_test Starting 2.4s
- Container flask_test Created 0.2s
Error response from daemon: Ports are not available: listen tcp 0.0.0.0:3306: bind: Only one usage of each socket address (protocol/network address/port) is normally permitted.
You are currently using the docker-compose dns feature in which you can use the container name as domain name for services running in docker-compose, thats neat - unless when you rename containers ;) Did you rename the mysqldb from dbserver?
If you want to continue using this feature, modify the env vars as so: (change dbserver to mysqldb)
DATABASE_URL=mysql+pymysql://test_user:abc123#mysqldb/test_db
...
If you instead what to use a more explicit approach:
In your docker-compose, you need to bind the port 3306 to your host network by
version: '3'
services:
python_app:
container_name: flask_test
build: .
env_file: .env
ports:
- 8000:5000
links:
- mysqldb:dbserver
depends_on:
mysqldb:
condition: service_healthy
mysqldb:
container_name: mysql_test
image: mysql:latest
env_file: database.conf
volumes:
- db-data:/var/lib/mysql
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "127.0.0.1", "--silent"]
interval: 3s
retries: 5
start_period: 30s
ports:
- 3306:3306
...
Then change the env var to:
DATABASE_URL=mysql+pymysql://test_user:abc123#0.0.0.0/test_db
Thanks for all the info, you did not post too much - needed it all :)

Failing to connect to mysql server when I change port number

I attempted to change MYSQL container to run on a different port number ie 3307 in my docker-compose file but I get a database connection error as shown below after launching services with docker-compose up what could be the issue?
web_1 | Traceback (most recent call last):
web_1 | File "/usr/local/lib/python3.7/site-packages/django/db/backends/base/base.py", line 216, in ensure_connection
web_1 | self.connect()
web_1 | File "/usr/local/lib/python3.7/site-packages/django/db/backends/base/base.py", line 194, in connect
web_1 | self.connection = self.get_new_connection(conn_params)
web_1 | File "/usr/local/lib/python3.7/site-packages/django/db/backends/mysql/base.py", line 227, in get_new_connection
web_1 | return Database.connect(**conn_params)
web_1 | File "/usr/local/lib/python3.7/site-packages/MySQLdb/__init__.py", line 130, in Connect
web_1 | return Connection(*args, **kwargs)
web_1 | File "/usr/local/lib/python3.7/site-packages/MySQLdb/connections.py", line 185, in __init__
web_1 | super().__init__(*args, **kwargs2)
web_1 | MySQLdb._exceptions.OperationalError: (2002, "Can't connect to MySQL server on 'db' (115)")
web_1 |
web_1 | The above exception was the direct cause of the following exception:
web_1 |
web_1 | Traceback (most recent call last):
web_1 | File "/usr/local/lib/python3.7/site-packages/gunicorn/arbiter.py", line 583, in spawn_worker
web_1 | worker.init_process()
web_1 | File "/usr/local/lib/python3.7/site-packages/gunicorn/workers/base.py", line 129, in init_process
web_1 | self.load_wsgi()
web_1 | File "/usr/local/lib/python3.7/site-packages/gunicorn/workers/base.py", line 138, in load_wsgi
web_1 | self.wsgi = self.app.wsgi()
web_1 | File "/usr/local/lib/python3.7/site-packages/gunicorn/app/base.py", line 67, in wsgi
web_1 | self.callable = self.load()
web_1 | File "/usr/local/lib/python3.7/site-packages/gunicorn/app/wsgiapp.py", line 52, in load
web_1 | return self.load_wsgiapp()
web_1 | File "/usr/local/lib/python3.7/site-packages/gunicorn/app/wsgiapp.py", line 41, in load_wsgiapp
web_1 | return util.import_app(self.app_uri)
web_1 | File "/usr/local/lib/python3.7/site-packages/gunicorn/util.py", line 350, in import_app
web_1 | __import__(module)
web_1 | File "/src/core/wsgi.py", line 16, in <module>
web_1 | application = get_wsgi_application()
web_1 | File "/usr/local/lib/python3.7/site-packages/django/core/wsgi.py", line 12, in get_wsgi_application
web_1 | django.setup(set_prefix=False)
web_1 | File "/usr/local/lib/python3.7/site-packages/django/__init__.py", line 24, in setup
web_1 | apps.populate(settings.INSTALLED_APPS)
web_1 | File "/usr/local/lib/python3.7/site-packages/django/apps/registry.py", line 120, in populate
web_1 | app_config.ready()
web_1 | File "/usr/local/lib/python3.7/site-packages/django_prometheus/apps.py", line 23, in ready
web_1 | ExportMigrations()
web_1 | File "/usr/local/lib/python3.7/site-packages/django_prometheus/migrations.py", line 49, in ExportMigrations
web_1 | executor = MigrationExecutor(connections[alias])
web_1 | File "/usr/local/lib/python3.7/site-packages/django/db/migrations/executor.py", line 18, in __init__
web_1 | self.loader = MigrationLoader(self.connection)
web_1 | File "/usr/local/lib/python3.7/site-packages/django/db/migrations/loader.py", line 49, in __init__
web_1 | self.build_graph()
web_1 | File "/usr/local/lib/python3.7/site-packages/django/db/migrations/loader.py", line 212, in build_graph
web_1 | self.applied_migrations = recorder.applied_migrations()
web_1 | File "/usr/local/lib/python3.7/site-packages/django/db/migrations/recorder.py", line 61, in applied_migrations
web_1 | if self.has_table():
web_1 | File "/usr/local/lib/python3.7/site-packages/django/db/migrations/recorder.py", line 44, in has_table
web_1 | return self.Migration._meta.db_table in self.connection.introspection.table_names(self.connection.cursor())
web_1 | File "/usr/local/lib/python3.7/site-packages/django/db/backends/base/base.py", line 255, in cursor
web_1 | return self._cursor()
web_1 | File "/usr/local/lib/python3.7/site-packages/django/db/backends/base/base.py", line 232, in _cursor
web_1 | self.ensure_connection()
web_1 | File "/usr/local/lib/python3.7/site-packages/django/db/backends/base/base.py", line 216, in ensure_connection
web_1 | self.connect()
web_1 | File "/usr/local/lib/python3.7/site-packages/django/db/utils.py", line 89, in __exit__
web_1 | raise dj_exc_value.with_traceback(traceback) from exc_value
web_1 | File "/usr/local/lib/python3.7/site-packages/django/db/backends/base/base.py", line 216, in ensure_connection
web_1 | self.connect()
web_1 | File "/usr/local/lib/python3.7/site-packages/django/db/backends/base/base.py", line 194, in connect
web_1 | self.connection = self.get_new_connection(conn_params)
web_1 | File "/usr/local/lib/python3.7/site-packages/django/db/backends/mysql/base.py", line 227, in get_new_connection
web_1 | return Database.connect(**conn_params)
web_1 | File "/usr/local/lib/python3.7/site-packages/MySQLdb/__init__.py", line 130, in Connect
web_1 | return Connection(*args, **kwargs)
web_1 | File "/usr/local/lib/python3.7/site-packages/MySQLdb/connections.py", line 185, in __init__
web_1 | super().__init__(*args, **kwargs2)
web_1 | django.db.utils.OperationalError: (2002, "Can't connect to MySQL server on 'db' (115)")
Docker Compose File
db:
restart: always
image: mysql:5.7
command: --default-authentication-plugin=mysql_native_password
environment:
MYSQL_ROOT_PASSWORD: test
MYSQL_DATABASE: default_schema
MYSQL_USER: test
MYSQL_PASSWORD: test
expose:
- "3307"
ports:
- "3307:3307"
volumes:
- ../mysql-data:/var/lib/mysql
phpmyadmin:
image: phpmyadmin/phpmyadmin
container_name: pma
links:
- db
environment:
PMA_HOST: db
PMA_PORT: 3307
PMA_ARBITRARY: 1
restart: always
ports:
- 8183:80
Application DB Settings
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'default_schema',
'USER': 'root',
'PASSWORD': 'test',
'HOST': 'db',
'PORT': '3307',
}
}
After running docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
2d60c0265ed9 nllb_frontend "/docker-entrypoint.…" 7 seconds ago Up 6 seconds 0.0.0.0:80->80/tcp frontend
323a7dd77121 nllb_web "gunicorn --bind 0.0…" 7 seconds ago Up 2 seconds 7000/tcp nllb_web_1
89ad90d1fb10 phpmyadmin/phpmyadmin "/docker-entrypoint.…" 7 seconds ago Up 6 seconds 0.0.0.0:8183->80/tcp pma
e5c5e2bda22c mysql:5.7 "docker-entrypoint.s…" 8 seconds ago Up 7 seconds 3306/tcp, 33060/tcp, 0.0.0.0:3307->3307/tcp nllb_db_1
1332ad2e136b redis:latest "docker-entrypoint.s…" 9 seconds ago Up 8 seconds 6379/tcp nllb_redis_1
You need to also tell MySQL about the change of plans:
environment:
MYSQL_TCP_PORT: 3307
(fixed, thanks to #derpirscher, see below)
(I previously guessed it would be PORT, DB_PORT, MYSQL_PORT, MYSQLD_PORT, or, as a testament to my willingness to believe any absurdity I find on Github, MYSQL_HOST=db:3307)
Connections between containers always use the "normal" port number for the service; these connections ignore any remapping that ports: might do. If you are only connecting to the database from another container, in fact, ports: isn't required at all; if it is present, the second port number again needs to be the "normal" port number for the service.
It should work to change the docker-compose.yml file:
version: '3.8'
services:
db:
# do not need `expose:`
ports: # optional, if you're not going to connect from outside Docker
- '3307:3306' # second port _must_ be "normal" port 3306
phpmyadmin:
# do not need `container_name:` or `links:`
environment:
PMA_HOST: db # Compose service name
PMA_PORT: 3306 # always the "normal" port, ignores `ports:`
And similarly in your configuration:
'HOST': 'db',
'PORT': '3306', # the "normal" port, ignores `ports:`
As I noted in comments, expose: and links: are only relevant for an outdated mode of Docker networking, and can be safely removed from the docker-compose.yml file. There's also usually no harm in letting Compose pick its own container_name:.