skip to Main Content

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

2

Answers


  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)

    Login or Signup to reply.
  2. 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:.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search