更改端口号时无法连接到mysql服务器

时间:2020-09-17 08:43:42

标签: mysql docker docker-compose

我尝试将MYSQL容器更改为在docker-compose文件中的其他端口号(即 3307 )上运行,但是在使用docker-compose up启动服务后,出现如下所示的数据库连接错误可能是什么问题?

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撰写文件

  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

应用程序数据库设置

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql', 
        'NAME': 'default_schema',
        'USER': 'root',
        'PASSWORD': 'test',
        'HOST': 'db',
        'PORT': '3307',
    }
}

运行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 个答案:

答案 0 :(得分:2)

您还需要将计划变更告知MySQL:

environment:
  MYSQL_TCP_PORT: 3307 

(已修复,感谢@derpirscher,请参见下文)

(我以前猜想是PORTDB_PORTMYSQL_PORTMYSQLD_PORT,或者证明我愿意相信我在Github上发现的任何荒谬之处,MYSQL_HOST=db:3307

答案 1 :(得分:0)

容器之间的连接始终使用服务的“常规”端口号;这些连接将忽略ports:可能进行的任何重新映射。实际上,如果仅从另一个容器连接数据库,则根本不需要ports:;如果存在,则第二个端口号再次必须是该服务的“普通”端口号。

更改docker-compose.yml文件应该可以:

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:`

同样在您的配置中:

'HOST': 'db',
'PORT': '3306',  # the "normal" port, ignores `ports:`

正如我在评论中指出的,expose:links:仅与Docker网络的过时模式相关,可以安全地从docker-compose.yml文件中删除。让Compose选择自己的container_name:通常也没有什么害处。