I want to simply launch an openedx platform via tutor (version 20.0.1) … but the LMS/CMS can’t connect to MYSQL database
I have freshly installed tutor (20.0.1) on a new server (all detailed steps for easy reproduction of this problem are described at the bottom). After running tutor local launch the mysql container seems to run correctly (container is up and the logs dont show any error only some warnings (attached at bottom). But the LMS and CMS containers are failing. The reason for this can be found in the logs (complete logs are attached at bottom):
**MYSQL Connectivity error: **
MySQLdb.OperationalError: (2003, “Can’t connect to MySQL server on ‘mysql:3306’ (111)”)
and
User authentication error:
MySQLdb.OperationalError: (1045, “Access denied for user ‘openedx’@‘172.18.0.10’ (using password: YES)”)
According to the documentation the password for mysql database is generated automatically.
Using
Tutor version: 20.0.1
OS: Ubuntu-24.0.4
Logs
MYSQL logs
(.venv) openedx@ubuntu:~$ tutor local logs mysql
docker compose -f /home/openedx/.local/share/tutor/env/local/docker-compose.yml -f /home/openedx/.local/share/tutor/env/local/docker-compose.prod.yml --project-name tutor_local logs mysql
mysql-1 | 2025-10-04 09:59:33+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 8.4.0-1.el9 started.
mysql-1 | 2025-10-04 09:59:34+00:00 [Note] [Entrypoint]: Initializing database files
mysql-1 | 2025-10-04T09:59:34.433961Z 0 [System] [MY-015017] [Server] MySQL Server Initialization - start.
mysql-1 | 2025-10-04T09:59:34.439794Z 0 [System] [MY-013169] [Server] /usr/sbin/mysqld (mysqld 8.4.0) initializing of server in progress as process 42
mysql-1 | 2025-10-04T09:59:34.473398Z 1 [System] [MY-013576] [InnoDB] InnoDB initialization has started.
mysql-1 | 2025-10-04T09:59:36.166158Z 1 [System] [MY-013577] [InnoDB] InnoDB initialization has ended.
mysql-1 | 2025-10-04T09:59:39.575521Z 0 [Warning] [MY-010161] [Server] You need to use --log-bin to make --binlog-expire-logs-seconds work.
mysql-1 | 2025-10-04T09:59:42.468088Z 6 [Warning] [MY-010453] [Server] root@localhost is created with an empty password ! Please consider switching off the --initialize-insecure option.
mysql-1 | 2025-10-04T09:59:48.804253Z 0 [System] [MY-015018] [Server] MySQL Server Initialization - end.
mysql-1 | 2025-10-04 09:59:48+00:00 [Note] [Entrypoint]: Database files initialized
mysql-1 | 2025-10-04 09:59:48+00:00 [Note] [Entrypoint]: Starting temporary server
mysql-1 | 2025-10-04T09:59:48.980815Z 0 [System] [MY-015015] [Server] MySQL Server - start.
mysql-1 | 2025-10-04T09:59:49.758851Z 0 [System] [MY-010116] [Server] /usr/sbin/mysqld (mysqld 8.4.0) starting as process 81
mysql-1 | 2025-10-04T09:59:49.873838Z 1 [System] [MY-013576] [InnoDB] InnoDB initialization has started.
mysql-1 | 2025-10-04T09:59:50.999030Z 1 [System] [MY-013577] [InnoDB] InnoDB initialization has ended.
mysql-1 | 2025-10-04T09:59:52.259281Z 0 [Warning] [MY-010068] [Server] CA certificate ca.pem is self signed.
mysql-1 | 2025-10-04T09:59:52.259374Z 0 [System] [MY-013602] [Server] Channel mysql_main configured to support TLS. Encrypted connections are now supported for this channel.
mysql-1 | 2025-10-04T09:59:52.294396Z 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.
mysql-1 | 2025-10-04T09:59:52.430784Z 0 [System] [MY-010931] [Server] /usr/sbin/mysqld: ready for connections. Version: ‘8.4.0’ socket: ‘/var/run/mysqld/mysqld.sock’ port: 0 MySQL Community Server - GPL.
mysql-1 | 2025-10-04T09:59:52.484144Z 0 [System] [MY-011323] [Server] X Plugin ready for connections. Socket: /var/run/mysqld/mysqlx.sock
mysql-1 | 2025-10-04 09:59:52+00:00 [Note] [Entrypoint]: Temporary server started.
mysql-1 | ‘/var/lib/mysql/mysql.sock’ → ‘/var/run/mysqld/mysqld.sock’
mysql-1 | Warning: Unable to load ‘/usr/share/zoneinfo/iso3166.tab’ as time zone. Skipping it.
mysql-1 | Warning: Unable to load ‘/usr/share/zoneinfo/leap-seconds.list’ as time zone. Skipping it.
mysql-1 | Warning: Unable to load ‘/usr/share/zoneinfo/leapseconds’ as time zone. Skipping it.
mysql-1 | Warning: Unable to load ‘/usr/share/zoneinfo/tzdata.zi’ as time zone. Skipping it.
mysql-1 | Warning: Unable to load ‘/usr/share/zoneinfo/zone.tab’ as time zone. Skipping it.
mysql-1 | Warning: Unable to load ‘/usr/share/zoneinfo/zone1970.tab’ as time zone. Skipping it.
mysql-1 |
mysql-1 | 2025-10-04 10:00:08+00:00 [Note] [Entrypoint]: Stopping temporary server
mysql-1 | 2025-10-04T10:00:09.103421Z 11 [System] [MY-013172] [Server] Received SHUTDOWN from user root. Shutting down mysqld (Version: 8.4.0).
mysql-1 | 2025-10-04T10:00:10.558480Z 0 [System] [MY-010910] [Server] /usr/sbin/mysqld: Shutdown complete (mysqld 8.4.0) MySQL Community Server - GPL.
mysql-1 | 2025-10-04T10:00:10.562573Z 0 [System] [MY-015016] [Server] MySQL Server - end.
mysql-1 | 2025-10-04 10:00:11+00:00 [Note] [Entrypoint]: Temporary server stopped
mysql-1 |
mysql-1 | 2025-10-04 10:00:11+00:00 [Note] [Entrypoint]: MySQL init process done. Ready for start up.
mysql-1 |
mysql-1 | 2025-10-04T10:00:11.260351Z 0 [System] [MY-015015] [Server] MySQL Server - start.
mysql-1 | 2025-10-04T10:00:12.070764Z 0 [System] [MY-010116] [Server] /usr/sbin/mysqld (mysqld 8.4.0) starting as process 1
mysql-1 | 2025-10-04T10:00:12.150849Z 1 [System] [MY-013576] [InnoDB] InnoDB initialization has started.
mysql-1 | 2025-10-04T10:00:14.153154Z 1 [System] [MY-013577] [InnoDB] InnoDB initialization has ended.
mysql-1 | 2025-10-04T10:00:15.619607Z 0 [Warning] [MY-010068] [Server] CA certificate ca.pem is self signed.
mysql-1 | 2025-10-04T10:00:15.623896Z 0 [System] [MY-013602] [Server] Channel mysql_main configured to support TLS. Encrypted connections are now supported for this channel.
mysql-1 | 2025-10-04T10:00:15.655598Z 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.
mysql-1 | 2025-10-04T10:00:15.799821Z 0 [System] [MY-010931] [Server] /usr/sbin/mysqld: ready for connections. Version: ‘8.4.0’ socket: ‘/var/run/mysqld/mysqld.sock’ port: 3306 MySQL Community Server - GPL.
mysql-1 | 2025-10-04T10:00:16.075368Z 0 [System] [MY-011323] [Server] X Plugin ready for connections. Bind-address: ‘::’ port: 33060, socket: /var/run/mysqld/mysqlx.sock
mysql-1 | 2025-10-04T10:00:25.438974Z 9 [Warning] [MY-013360] [Server] Plugin sha256_password reported: ‘‘sha256_password’ is deprecated and will be removed in a future release. Please use caching_sha2_password instead’
LMS related logs
(.venv) openedx@ubuntu:~$ tutor local logs lms
docker compose -f /home/openedx/.local/share/tutor/env/local/docker-compose.yml -f /home/openedx/.local/share/tutor/env/local/docker-compose.prod.yml --project-name tutor_local logs lms
lms-1 | [uWSGI] getting INI configuration from /openedx/uwsgi.ini
lms-1 | [uwsgi-static] added mapping for /static => /openedx/staticfiles/
lms-1 | [uwsgi-static] added mapping for /media => /openedx/media/
lms-1 | *** Starting uWSGI 2.0.24 (64bit) on [Sat Oct 4 09:59:34 2025] ***
lms-1 | compiled with version: 11.4.0 on 23 September 2025 06:51:40
lms-1 | os: Linux-6.8.0-71-generic #71-Ubuntu SMP PREEMPT_DYNAMIC Tue Jul 22 16:52:38 UTC 2025
lms-1 | nodename: e478f2056851
lms-1 | machine: x86_64
lms-1 | clock source: unix
lms-1 | detected number of CPU cores: 2
lms-1 | current working directory: /openedx/edx-platform
lms-1 | detected binary path: /openedx/venv/bin/uwsgi
lms-1 | !!! no internal routing support, rebuild with pcre support !!!
lms-1 | your memory page size is 4096 bytes
lms-1 | detected max file descriptor number: 1048576
lms-1 | building mime-types dictionary from file /etc/mime.types…1516 entry found
lms-1 | lock engine: pthread robust mutexes
lms-1 | thunder lock: enabled
lms-1 | uWSGI http bound on 0.0.0.0:8000 fd 4
lms-1 | uwsgi socket 0 bound to TCP address 127.0.0.1:46229 (port auto-assigned) fd 3
lms-1 | Python version: 3.11.8 (main, Sep 2 2025, 08:09:41) [GCC 11.4.0]
lms-1 | Python main interpreter initialized at 0x7ae09d160278
lms-1 | python threads support enabled
lms-1 | your server socket listen backlog is limited to 100 connections
lms-1 | your mercy for graceful operations on workers is 60 seconds
lms-1 | mapped 231048 bytes (225 KB) for 2 cores
lms-1 | *** Operational MODE: preforking ***
lms-1 | Traceback (most recent call last):
lms-1 | File “/openedx/venv/lib/python3.11/site-packages/django/db/backends/base/base.py”, line 289, in ensure_connection
lms-1 | self.connect()
lms-1 | File “/openedx/venv/lib/python3.11/site-packages/django/utils/asyncio.py”, line 26, in inner
lms-1 | return func(*args, **kwargs)
lms-1 | ^^^^^^^^^^^^^^^^^^^^^
lms-1 | File “/openedx/venv/lib/python3.11/site-packages/django/db/backends/base/base.py”, line 270, in connect
lms-1 | self.connection = self.get_new_connection(conn_params)
lms-1 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
lms-1 | File “/openedx/venv/lib/python3.11/site-packages/django/utils/asyncio.py”, line 26, in inner
lms-1 | return func(*args, **kwargs)
lms-1 | ^^^^^^^^^^^^^^^^^^^^^
lms-1 | File “/openedx/venv/lib/python3.11/site-packages/django/db/backends/mysql/base.py”, line 247, in get_new_connection
lms-1 | connection = Database.connect(**conn_params)
lms-1 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
lms-1 | File “/openedx/venv/lib/python3.11/site-packages/MySQLdb/_init_.py”, line 121, in Connect
lms-1 | return Connection(*args, **kwargs)
lms-1 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
lms-1 | File “/openedx/venv/lib/python3.11/site-packages/MySQLdb/connections.py”, line 200, in _init_
lms-1 | super()._init_(*args, **kwargs2)
lms-1 | MySQLdb.OperationalError: (2003, “Can’t connect to MySQL server on ‘mysql:3306’ (111)”)
lms-1 |
lms-1 | The above exception was the direct cause of the following exception:
lms-1 |
lms-1 | Traceback (most recent call last):
lms-1 | File “lms/wsgi.py”, line 21, in
lms-1 | application = get_wsgi_application()
lms-1 | ^^^^^^^^^^^^^^^^^^^^^^
lms-1 | File “/openedx/venv/lib/python3.11/site-packages/django/core/wsgi.py”, line 13, in get_wsgi_application
lms-1 | return WSGIHandler()
lms-1 | ^^^^^^^^^^^^^
lms-1 | File “/openedx/venv/lib/python3.11/site-packages/django/core/handlers/wsgi.py”, line 118, in _init_
lms-1 | self.load_middleware()
lms-1 | File “/openedx/venv/lib/python3.11/site-packages/django/core/handlers/base.py”, line 61, in load_middleware
lms-1 | mw_instance = middleware(adapted_handler)
lms-1 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
lms-1 | File “/openedx/venv/lib/python3.11/site-packages/edx_django_utils/monitoring/internal/middleware.py”, line 518, in _init_
lms-1 | if not self._is_enabled():
lms-1 | ^^^^^^^^^^^^^^^^^^
lms-1 | File “/openedx/venv/lib/python3.11/site-packages/edx_django_utils/monitoring/internal/middleware.py”, line 586, in _is_enabled
lms-1 | return waffle.switch_is_active(‘edx_django_utils.monitoring.enable_frontend_monitoring_middleware’)
lms-1 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
lms-1 | File “/openedx/venv/lib/python3.11/site-packages/waffle/_init_.py”, line 23, in switch_is_active
lms-1 | switch = get_waffle_switch_model().get(switch_name)
lms-1 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
lms-1 | File “/openedx/venv/lib/python3.11/site-packages/waffle/models.py”, line 59, in get
lms-1 | obj = cls.get_from_db(name)
lms-1 | ^^^^^^^^^^^^^^^^^^^^^
lms-1 | File “/openedx/venv/lib/python3.11/site-packages/waffle/models.py”, line 72, in get_from_db
lms-1 | return objects.get(name=name)
lms-1 | ^^^^^^^^^^^^^^^^^^^^^^
lms-1 | File “/openedx/venv/lib/python3.11/site-packages/django/db/models/manager.py”, line 87, in manager_method
lms-1 | return getattr(self.get_queryset(), name)(*args, **kwargs)
lms-1 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
lms-1 | File “/openedx/venv/lib/python3.11/site-packages/django/db/models/query.py”, line 633, in get
lms-1 | num = len(clone)
lms-1 | ^^^^^^^^^^
lms-1 | File “/openedx/venv/lib/python3.11/site-packages/django/db/models/query.py”, line 380, in _len_
lms-1 | self._fetch_all()
lms-1 | File “/openedx/venv/lib/python3.11/site-packages/django/db/models/query.py”, line 1881, in _fetch_all
lms-1 | self._result_cache = list(self._iterable_class(self))
lms-1 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
lms-1 | File “/openedx/venv/lib/python3.11/site-packages/django/db/models/query.py”, line 91, in _iter_
lms-1 | results = compiler.execute_sql(
lms-1 | ^^^^^^^^^^^^^^^^^^^^^
lms-1 | File “/openedx/venv/lib/python3.11/site-packages/django/db/models/sql/compiler.py”, line 1560, in execute_sql
lms-1 | cursor = self.connection.cursor()
lms-1 | ^^^^^^^^^^^^^^^^^^^^^^^^
lms-1 | File “/openedx/venv/lib/python3.11/site-packages/django/utils/asyncio.py”, line 26, in inner
lms-1 | return func(*args, **kwargs)
lms-1 | ^^^^^^^^^^^^^^^^^^^^^
lms-1 | File “/openedx/venv/lib/python3.11/site-packages/django/db/backends/base/base.py”, line 330, in cursor
lms-1 | return self._cursor()
lms-1 | ^^^^^^^^^^^^^^
lms-1 | File “/openedx/venv/lib/python3.11/site-packages/django/db/backends/base/base.py”, line 306, in _cursor
lms-1 | self.ensure_connection()
lms-1 | File “/openedx/venv/lib/python3.11/site-packages/django/utils/asyncio.py”, line 26, in inner
lms-1 | return func(*args, **kwargs)
lms-1 | ^^^^^^^^^^^^^^^^^^^^^
lms-1 | File “/openedx/venv/lib/python3.11/site-packages/django/db/backends/base/base.py”, line 288, in ensure_connection
lms-1 | with self.wrap_database_errors:
lms-1 | File “/openedx/venv/lib/python3.11/site-packages/django/db/utils.py”, line 91, in _exit_
lms-1 | raise dj_exc_value.with_traceback(traceback) from exc_value
lms-1 | File “/openedx/venv/lib/python3.11/site-packages/django/db/backends/base/base.py”, line 289, in ensure_connection
lms-1 | self.connect()
lms-1 | File “/openedx/venv/lib/python3.11/site-packages/django/utils/asyncio.py”, line 26, in inner
lms-1 | return func(*args, **kwargs)
lms-1 | ^^^^^^^^^^^^^^^^^^^^^
lms-1 | File “/openedx/venv/lib/python3.11/site-packages/django/db/backends/base/base.py”, line 270, in connect
lms-1 | self.connection = self.get_new_connection(conn_params)
lms-1 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
lms-1 | File “/openedx/venv/lib/python3.11/site-packages/django/utils/asyncio.py”, line 26, in inner
lms-1 | return func(*args, **kwargs)
lms-1 | ^^^^^^^^^^^^^^^^^^^^^
lms-1 | File “/openedx/venv/lib/python3.11/site-packages/django/db/backends/mysql/base.py”, line 247, in get_new_connection
lms-1 | connection = Database.connect(**conn_params)
lms-1 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
lms-1 | File “/openedx/venv/lib/python3.11/site-packages/MySQLdb/_init_.py”, line 121, in Connect
lms-1 | return Connection(*args, **kwargs)
lms-1 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
lms-1 | File “/openedx/venv/lib/python3.11/site-packages/MySQLdb/connections.py”, line 200, in _init_
lms-1 | super()._init_(*args, **kwargs2)
lms-1 | django.db.utils.OperationalError: (2003, “Can’t connect to MySQL server on ‘mysql:3306’ (111)”)
lms-1 | unable to load app 0 (mountpoint=‘’) (callable not found or import error)
lms-1 | *** no app loaded. GAME OVER ***
lms-1 | [uWSGI] getting INI configuration from /openedx/uwsgi.ini
lms-1 | [uwsgi-static] added mapping for /static => /openedx/staticfiles/
lms-1 | [uwsgi-static] added mapping for /media => /openedx/media/
lms-1 | *** Starting uWSGI 2.0.24 (64bit) on [Sat Oct 4 10:00:05 2025] ***
lms-1 | compiled with version: 11.4.0 on 23 September 2025 06:51:40
lms-1 | os: Linux-6.8.0-71-generic #71-Ubuntu SMP PREEMPT_DYNAMIC Tue Jul 22 16:52:38 UTC 2025
lms-1 | nodename: e478f2056851
lms-1 | machine: x86_64
lms-1 | clock source: unix
lms-1 | detected number of CPU cores: 2
lms-1 | current working directory: /openedx/edx-platform
lms-1 | detected binary path: /openedx/venv/bin/uwsgi
lms-1 | !!! no internal routing support, rebuild with pcre support !!!
lms-1 | your memory page size is 4096 bytes
lms-1 | detected max file descriptor number: 1048576
lms-1 | building mime-types dictionary from file /etc/mime.types…1516 entry found
lms-1 | lock engine: pthread robust mutexes
lms-1 | thunder lock: enabled
lms-1 | uWSGI http bound on 0.0.0.0:8000 fd 4
lms-1 | uwsgi socket 0 bound to TCP address 127.0.0.1:39875 (port auto-assigned) fd 3
lms-1 | Python version: 3.11.8 (main, Sep 2 2025, 08:09:41) [GCC 11.4.0]
lms-1 | Python main interpreter initialized at 0x7f174f1a3278
lms-1 | python threads support enabled
lms-1 | your server socket listen backlog is limited to 100 connections
lms-1 | your mercy for graceful operations on workers is 60 seconds
lms-1 | mapped 231048 bytes (225 KB) for 2 cores
lms-1 | *** Operational MODE: preforking ***
lms-1 | Traceback (most recent call last):
lms-1 | File “/openedx/venv/lib/python3.11/site-packages/django/db/backends/base/base.py”, line 289, in ensure_connection
lms-1 | self.connect()
lms-1 | File “/openedx/venv/lib/python3.11/site-packages/django/utils/asyncio.py”, line 26, in inner
lms-1 | return func(*args, **kwargs)
lms-1 | ^^^^^^^^^^^^^^^^^^^^^
lms-1 | File “/openedx/venv/lib/python3.11/site-packages/django/db/backends/base/base.py”, line 270, in connect
lms-1 | self.connection = self.get_new_connection(conn_params)
lms-1 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
lms-1 | File “/openedx/venv/lib/python3.11/site-packages/django/utils/asyncio.py”, line 26, in inner
lms-1 | return func(*args, **kwargs)
lms-1 | ^^^^^^^^^^^^^^^^^^^^^
lms-1 | File “/openedx/venv/lib/python3.11/site-packages/django/db/backends/mysql/base.py”, line 247, in get_new_connection
lms-1 | connection = Database.connect(**conn_params)
lms-1 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
lms-1 | File “/openedx/venv/lib/python3.11/site-packages/MySQLdb/_init_.py”, line 121, in Connect
lms-1 | return Connection(*args, **kwargs)
lms-1 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
lms-1 | File “/openedx/venv/lib/python3.11/site-packages/MySQLdb/connections.py”, line 200, in _init_
lms-1 | super()._init_(*args, **kwargs2)
lms-1 | MySQLdb.OperationalError: (1045, “Access denied for user ‘openedx’@‘172.18.0.8’ (using password: YES)”)
lms-1 |
lms-1 | The above exception was the direct cause of the following exception:
lms-1 |
lms-1 | Traceback (most recent call last):
lms-1 | File “lms/wsgi.py”, line 21, in
lms-1 | application = get_wsgi_application()
lms-1 | ^^^^^^^^^^^^^^^^^^^^^^
lms-1 | File “/openedx/venv/lib/python3.11/site-packages/django/core/wsgi.py”, line 13, in get_wsgi_application
lms-1 | return WSGIHandler()
lms-1 | ^^^^^^^^^^^^^
lms-1 | File “/openedx/venv/lib/python3.11/site-packages/django/core/handlers/wsgi.py”, line 118, in _init_
lms-1 | self.load_middleware()
lms-1 | File “/openedx/venv/lib/python3.11/site-packages/django/core/handlers/base.py”, line 61, in load_middleware
lms-1 | mw_instance = middleware(adapted_handler)
lms-1 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
lms-1 | File “/openedx/venv/lib/python3.11/site-packages/edx_django_utils/monitoring/internal/middleware.py”, line 518, in _init_
lms-1 | if not self._is_enabled():
lms-1 | ^^^^^^^^^^^^^^^^^^
lms-1 | File “/openedx/venv/lib/python3.11/site-packages/edx_django_utils/monitoring/internal/middleware.py”, line 586, in _is_enabled
lms-1 | return waffle.switch_is_active(‘edx_django_utils.monitoring.enable_frontend_monitoring_middleware’)
lms-1 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
lms-1 | File “/openedx/venv/lib/python3.11/site-packages/waffle/_init_.py”, line 23, in switch_is_active
lms-1 | switch = get_waffle_switch_model().get(switch_name)
lms-1 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
lms-1 | File “/openedx/venv/lib/python3.11/site-packages/waffle/models.py”, line 59, in get
lms-1 | obj = cls.get_from_db(name)
lms-1 | ^^^^^^^^^^^^^^^^^^^^^
lms-1 | File “/openedx/venv/lib/python3.11/site-packages/waffle/models.py”, line 72, in get_from_db
lms-1 | return objects.get(name=name)
lms-1 | ^^^^^^^^^^^^^^^^^^^^^^
lms-1 | File “/openedx/venv/lib/python3.11/site-packages/django/db/models/manager.py”, line 87, in manager_method
lms-1 | return getattr(self.get_queryset(), name)(*args, **kwargs)
lms-1 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
lms-1 | File “/openedx/venv/lib/python3.11/site-packages/django/db/models/query.py”, line 633, in get
lms-1 | num = len(clone)
lms-1 | ^^^^^^^^^^
lms-1 | File “/openedx/venv/lib/python3.11/site-packages/django/db/models/query.py”, line 380, in _len_
lms-1 | self._fetch_all()
lms-1 | File “/openedx/venv/lib/python3.11/site-packages/django/db/models/query.py”, line 1881, in _fetch_all
lms-1 | self._result_cache = list(self._iterable_class(self))
lms-1 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
lms-1 | File “/openedx/venv/lib/python3.11/site-packages/django/db/models/query.py”, line 91, in _iter_
lms-1 | results = compiler.execute_sql(
lms-1 | ^^^^^^^^^^^^^^^^^^^^^
lms-1 | File “/openedx/venv/lib/python3.11/site-packages/django/db/models/sql/compiler.py”, line 1560, in execute_sql
lms-1 | cursor = self.connection.cursor()
lms-1 | ^^^^^^^^^^^^^^^^^^^^^^^^
lms-1 | File “/openedx/venv/lib/python3.11/site-packages/django/utils/asyncio.py”, line 26, in inner
lms-1 | return func(*args, **kwargs)
lms-1 | ^^^^^^^^^^^^^^^^^^^^^
lms-1 | File “/openedx/venv/lib/python3.11/site-packages/django/db/backends/base/base.py”, line 330, in cursor
lms-1 | return self._cursor()
lms-1 | ^^^^^^^^^^^^^^
lms-1 | File “/openedx/venv/lib/python3.11/site-packages/django/db/backends/base/base.py”, line 306, in _cursor
lms-1 | self.ensure_connection()
lms-1 | File “/openedx/venv/lib/python3.11/site-packages/django/utils/asyncio.py”, line 26, in inner
lms-1 | return func(*args, **kwargs)
lms-1 | ^^^^^^^^^^^^^^^^^^^^^
lms-1 | File “/openedx/venv/lib/python3.11/site-packages/django/db/backends/base/base.py”, line 288, in ensure_connection
lms-1 | with self.wrap_database_errors:
lms-1 | File “/openedx/venv/lib/python3.11/site-packages/django/db/utils.py”, line 91, in _exit_
lms-1 | raise dj_exc_value.with_traceback(traceback) from exc_value
lms-1 | File “/openedx/venv/lib/python3.11/site-packages/django/db/backends/base/base.py”, line 289, in ensure_connection
lms-1 | self.connect()
lms-1 | File “/openedx/venv/lib/python3.11/site-packages/django/utils/asyncio.py”, line 26, in inner
lms-1 | return func(*args, **kwargs)
lms-1 | ^^^^^^^^^^^^^^^^^^^^^
lms-1 | File “/openedx/venv/lib/python3.11/site-packages/django/db/backends/base/base.py”, line 270, in connect
lms-1 | self.connection = self.get_new_connection(conn_params)
lms-1 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
lms-1 | File “/openedx/venv/lib/python3.11/site-packages/django/utils/asyncio.py”, line 26, in inner
lms-1 | return func(*args, **kwargs)
lms-1 | ^^^^^^^^^^^^^^^^^^^^^
lms-1 | File “/openedx/venv/lib/python3.11/site-packages/django/db/backends/mysql/base.py”, line 247, in get_new_connection
lms-1 | connection = Database.connect(**conn_params)
lms-1 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
lms-1 | File “/openedx/venv/lib/python3.11/site-packages/MySQLdb/_init_.py”, line 121, in Connect
lms-1 | return Connection(*args, **kwargs)
lms-1 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
lms-1 | File “/openedx/venv/lib/python3.11/site-packages/MySQLdb/connections.py”, line 200, in _init_
lms-1 | super()._init_(*args, **kwargs2)
lms-1 | django.db.utils.OperationalError: (1045, “Access denied for user ‘openedx’@‘172.18.0.8’ (using password: YES)”)
lms-1 | unable to load app 0 (mountpoint=‘’) (callable not found or import error)
lms-1 | *** no app loaded. GAME OVER ***
lms-1 | [uWSGI] getting INI configuration from /openedx/uwsgi.ini
lms-1 | [uwsgi-static] added mapping for /static => /openedx/staticfiles/
lms-1 | [uwsgi-static] added mapping for /media => /openedx/media/
lms-1 | *** Starting uWSGI 2.0.24 (64bit) on [Sat Oct 4 10:00:26 2025] ***
lms-1 | compiled with version: 11.4.0 on 23 September 2025 06:51:40
lms-1 | os: Linux-6.8.0-71-generic #71-Ubuntu SMP PREEMPT_DYNAMIC Tue Jul 22 16:52:38 UTC 2025
lms-1 | nodename: e478f2056851
lms-1 | machine: x86_64
lms-1 | clock source: unix
lms-1 | detected number of CPU cores: 2
lms-1 | current working directory: /openedx/edx-platform
lms-1 | detected binary path: /openedx/venv/bin/uwsgi
lms-1 | !!! no internal routing support, rebuild with pcre support !!!
lms-1 | your memory page size is 4096 bytes
lms-1 | detected max file descriptor number: 1048576
lms-1 | building mime-types dictionary from file /etc/mime.types…1516 entry found
lms-1 | lock engine: pthread robust mutexes
lms-1 | thunder lock: enabled
lms-1 | uWSGI http bound on 0.0.0.0:8000 fd 4
lms-1 | uwsgi socket 0 bound to TCP address 127.0.0.1:33525 (port auto-assigned) fd 3
lms-1 | Python version: 3.11.8 (main, Sep 2 2025, 08:09:41) [GCC 11.4.0]
lms-1 | Python main interpreter initialized at 0x7870032bd278
lms-1 | python threads support enabled
lms-1 | your server socket listen backlog is limited to 100 connections
lms-1 | your mercy for graceful operations on workers is 60 seconds
lms-1 | mapped 231048 bytes (225 KB) for 2 cores
lms-1 | *** Operational MODE: preforking ***
lms-1 | Traceback (most recent call last):
lms-1 | File “/openedx/venv/lib/python3.11/site-packages/django/db/backends/base/base.py”, line 289, in ensure_connection
lms-1 | self.connect()
lms-1 | File “/openedx/venv/lib/python3.11/site-packages/django/utils/asyncio.py”, line 26, in inner
lms-1 | return func(*args, **kwargs)
lms-1 | ^^^^^^^^^^^^^^^^^^^^^
lms-1 | File “/openedx/venv/lib/python3.11/site-packages/django/db/backends/base/base.py”, line 270, in connect
lms-1 | self.connection = self.get_new_connection(conn_params)
lms-1 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
lms-1 | File “/openedx/venv/lib/python3.11/site-packages/django/utils/asyncio.py”, line 26, in inner
lms-1 | return func(*args, **kwargs)
lms-1 | ^^^^^^^^^^^^^^^^^^^^^
lms-1 | File “/openedx/venv/lib/python3.11/site-packages/django/db/backends/mysql/base.py”, line 247, in get_new_connection
lms-1 | connection = Database.connect(**conn_params)
lms-1 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
lms-1 | File “/openedx/venv/lib/python3.11/site-packages/MySQLdb/_init_.py”, line 121, in Connect
lms-1 | return Connection(*args, **kwargs)
lms-1 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
lms-1 | File “/openedx/venv/lib/python3.11/site-packages/MySQLdb/connections.py”, line 200, in _init_
lms-1 | super()._init_(*args, **kwargs2)
lms-1 | MySQLdb.OperationalError: (1045, “Access denied for user ‘openedx’@‘172.18.0.8’ (using password: YES)”)
Similiar problems found and what I have tried
- As described in these posts (here and here) I removed the data folder in
$(tutor config printroot)and in addition to that removed all containers and volumes. But after running `tutor local launch` the problem persists …
Steps for easy reproduction
These are all steps after spinning up a fresh ubuntu server (on digital ocean)
- create a non-root user
-
adduser openedx -
(optional) copy the ssh-key from the root-user to the newly created user, to make it possible
to login passwordless via ssh-key -
mkdir -p /home/openedx/.ssh chmod 700 /home/openedx/.ssh cp /root/.ssh/authorized_keys /home/openedx/.ssh/authorized_keys chown -R openedx:openedx /home/openedx/.ssh chmod 600 /home/openedx/.ssh/authorized_keys -
add to sudo group (temporary)
usermod -aG sudo "openedx"
-
- docker installation (based on docker documentation)
-
# Add Docker's official GPG key: sudo apt-get update sudo apt-get install ca-certificates curl sudo install -m 0755 -d /etc/apt/keyrings sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc sudo chmod a+r /etc/apt/keyrings/docker.asc # Add the repository to Apt sources: echo \ "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \ $(. /etc/os-release && echo "${UBUNTU_CODENAME:-$VERSION_CODENAME}") stable" | \ sudo tee /etc/apt/sources.list.d/docker.list > /dev/null sudo apt-get update -
sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin -
sudo usermod -aG docker openedx
-
- Now logout and loggin as the new created user called openedx
- install python
-
sudo apt install python3 python3-pip libyaml-dev -y sudo apt install python3-venv -y python3 -m venv .venv source .venv/bin/activate -
Now install Tutor
pip install "tutor[full]==20.0.1"
-
- Now after running
tutor local launchthe website should be accessible… but it is not due the exceptions thrown by CMS and LMS (logs can be seen by running `tutor local logs cms` and are attached above this section and described in detailed at the top of this post.)