Cannot deploy EDX to AWS EKS

Hi guys,

I tried to deployed EDX via tutor to AWS EKS but I have the errors from the LMS, CMS pods.

Could you please help me looking on it?

➜ kubectl get pods -n=openedx
NAME READY STATUS RESTARTS AGE
caddy-ddc79dd5b-rggvg 1/1 Running 0 23d
cms-68fcf44757-vgpm5 0/1 Error 6476 (5m20s ago) 23d
cms-worker-848f9db986-5sgsh 1/1 Running 0 23d
lms-7bc78d9877-tb67n 0/1 CrashLoopBackOff 6502 (2m6s ago) 23d
lms-worker-65c67668f5-6sdnm 1/1 Running 0 23d
meilisearch-666586ccb6-cztrw 1/1 Running 0 23d
mfe-677697cff8-mjtgc 1/1 Running 0 23d
minio-6958b448bc-m7hgt 1/1 Running 0 23d
mongodb-cb86586bc-b9nvh 1/1 Running 0 23d
mysql-64b4b7449c-7dh6c 1/1 Running 0 23d
redis-74f5ddb96-mftfk 1/1 Running 0 23d
smtp-5896895cb5-7djdz 1/1 Running 0 23d

Errors logs1:

kubectl -n=openedx logs lms-7bc78d9877-tb67n
[uWSGI] getting INI configuration from /openedx/uwsgi.ini
[uwsgi-static] added mapping for /static => /openedx/staticfiles/
[uwsgi-static] added mapping for /media => /openedx/media/
*** Starting uWSGI 2.0.24 (64bit) on [Thu Dec 11 02:23:48 2025] ***
compiled with version: 11.4.0 on 07 October 2025 13:06:02
os: Linux-6.12.53-69.119.amzn2023.x86_64 #1 SMP PREEMPT_DYNAMIC Tue Oct 21 22:19:00 UTC 2025
nodename: lms-7bc78d9877-tb67n
machine: x86_64
clock source: unix
detected number of CPU cores: 2
current working directory: /openedx/edx-platform
detected binary path: /openedx/venv/bin/uwsgi
!!! no internal routing support, rebuild with pcre support !!!
your memory page size is 4096 bytes
detected max file descriptor number: 65536
building mime-types dictionary from file /etc/mime.types…1516 entry found
lock engine: pthread robust mutexes
thunder lock: enabled
uWSGI http bound on 0.0.0.0:8000 fd 4
uwsgi socket 0 bound to TCP address 127.0.0.1:45877 (port auto-assigned) fd 3
Python version: 3.11.8 (main, Oct 2 2025, 08:22:41) [GCC 11.4.0]
Python main interpreter initialized at 0x7f3099330278
python threads support enabled
your server socket listen backlog is limited to 100 connections
your mercy for graceful operations on workers is 60 seconds
mapped 231048 bytes (225 KB) for 2 cores
*** Operational MODE: preforking ***
Traceback (most recent call last):
File “/openedx/venv/lib/python3.11/site-packages/django/db/backends/utils.py”, line 89, in _execute
return self.cursor.execute(sql, params)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File “/openedx/venv/lib/python3.11/site-packages/django/db/backends/mysql/base.py”, line 75, in execute
return self.cursor.execute(query, args)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File “/openedx/venv/lib/python3.11/site-packages/MySQLdb/cursors.py”, line 179, in execute
res = self._query(mogrified_query)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File “/openedx/venv/lib/python3.11/site-packages/MySQLdb/cursors.py”, line 330, in _query
db.query(q)
File “/openedx/venv/lib/python3.11/site-packages/MySQLdb/connections.py”, line 280, in query
_mysql.connection.query(self, query)
MySQLdb.ProgrammingError: (1146, “Table ‘openedx.waffle_switch’ doesn’t exist”)

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
File “lms/wsgi.py”, line 21, in
application = get_wsgi_application()
^^^^^^^^^^^^^^^^^^^^^^
File “/openedx/venv/lib/python3.11/site-packages/django/core/wsgi.py”, line 13, in get_wsgi_application
return WSGIHandler()
^^^^^^^^^^^^^
File “/openedx/venv/lib/python3.11/site-packages/django/core/handlers/wsgi.py”, line 118, in init
self.load_middleware()
File “/openedx/venv/lib/python3.11/site-packages/django/core/handlers/base.py”, line 61, in load_middleware
mw_instance = middleware(adapted_handler)
^^^^^^^^^^^^^^^^^^^^^^^^^^^
File “/openedx/venv/lib/python3.11/site-packages/edx_django_utils/monitoring/internal/middleware.py”, line 518, in init
if not self._is_enabled():
^^^^^^^^^^^^^^^^^^
File “/openedx/venv/lib/python3.11/site-packages/edx_django_utils/monitoring/internal/middleware.py”, line 586, in _is_enabled
return waffle.switch_is_active(‘edx_django_utils.monitoring.enable_frontend_monitoring_middleware’)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File “/openedx/venv/lib/python3.11/site-packages/waffle/init.py”, line 23, in switch_is_active
switch = get_waffle_switch_model().get(switch_name)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File “/openedx/venv/lib/python3.11/site-packages/waffle/models.py”, line 59, in get
obj = cls.get_from_db(name)
^^^^^^^^^^^^^^^^^^^^^
File “/openedx/venv/lib/python3.11/site-packages/waffle/models.py”, line 72, in get_from_db
return objects.get(name=name)
^^^^^^^^^^^^^^^^^^^^^^
File “/openedx/venv/lib/python3.11/site-packages/django/db/models/manager.py”, line 87, in manager_method
return getattr(self.get_queryset(), name)(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File “/openedx/venv/lib/python3.11/site-packages/django/db/models/query.py”, line 633, in get
num = len(clone)
^^^^^^^^^^
File “/openedx/venv/lib/python3.11/site-packages/django/db/models/query.py”, line 380, in len
self._fetch_all()
File “/openedx/venv/lib/python3.11/site-packages/django/db/models/query.py”, line 1881, in _fetch_all
self._result_cache = list(self._iterable_class(self))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File “/openedx/venv/lib/python3.11/site-packages/django/db/models/query.py”, line 91, in iter
results = compiler.execute_sql(
^^^^^^^^^^^^^^^^^^^^^
File “/openedx/venv/lib/python3.11/site-packages/django/db/models/sql/compiler.py”, line 1562, in execute_sql
cursor.execute(sql, params)
File “/openedx/venv/lib/python3.11/site-packages/django/db/backends/utils.py”, line 67, in execute
return self._execute_with_wrappers(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File “/openedx/venv/lib/python3.11/site-packages/django/db/backends/utils.py”, line 80, in _execute_with_wrappers
return executor(sql, params, many, context)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File “/openedx/venv/lib/python3.11/site-packages/django/db/backends/utils.py”, line 84, in _execute
with self.db.wrap_database_errors:
File “/openedx/venv/lib/python3.11/site-packages/django/db/utils.py”, line 91, in exit
raise dj_exc_value.with_traceback(traceback) from exc_value
File “/openedx/venv/lib/python3.11/site-packages/django/db/backends/utils.py”, line 89, in _execute
return self.cursor.execute(sql, params)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File “/openedx/venv/lib/python3.11/site-packages/django/db/backends/mysql/base.py”, line 75, in execute
return self.cursor.execute(query, args)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File “/openedx/venv/lib/python3.11/site-packages/MySQLdb/cursors.py”, line 179, in execute
res = self._query(mogrified_query)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File “/openedx/venv/lib/python3.11/site-packages/MySQLdb/cursors.py”, line 330, in _query
db.query(q)
File “/openedx/venv/lib/python3.11/site-packages/MySQLdb/connections.py”, line 280, in query
_mysql.connection.query(self, query)
django.db.utils.ProgrammingError: (1146, “Table ‘openedx.waffle_switch’ doesn’t exist”)
unable to load app 0 (mountpoint=‘’) (callable not found or import error)
*** no app loaded. GAME OVER ***

Error logs 2:
kubectl -n=openedx logs lms-7bc78d9877-tb67n
[uWSGI] getting INI configuration from /openedx/uwsgi.ini
[uwsgi-static] added mapping for /static => /openedx/staticfiles/
[uwsgi-static] added mapping for /media => /openedx/media/
*** Starting uWSGI 2.0.24 (64bit) on [Thu Dec 11 02:23:48 2025] ***
compiled with version: 11.4.0 on 07 October 2025 13:06:02
os: Linux-6.12.53-69.119.amzn2023.x86_64 #1 SMP PREEMPT_DYNAMIC Tue Oct 21 22:19:00 UTC 2025
nodename: lms-7bc78d9877-tb67n
machine: x86_64
clock source: unix
detected number of CPU cores: 2
current working directory: /openedx/edx-platform
detected binary path: /openedx/venv/bin/uwsgi
!!! no internal routing support, rebuild with pcre support !!!
your memory page size is 4096 bytes
detected max file descriptor number: 65536
building mime-types dictionary from file /etc/mime.types…1516 entry found
lock engine: pthread robust mutexes
thunder lock: enabled
uWSGI http bound on 0.0.0.0:8000 fd 4
uwsgi socket 0 bound to TCP address 127.0.0.1:45877 (port auto-assigned) fd 3
Python version: 3.11.8 (main, Oct 2 2025, 08:22:41) [GCC 11.4.0]
Python main interpreter initialized at 0x7f3099330278
python threads support enabled
your server socket listen backlog is limited to 100 connections
your mercy for graceful operations on workers is 60 seconds
mapped 231048 bytes (225 KB) for 2 cores
*** Operational MODE: preforking ***
Traceback (most recent call last):
File “/openedx/venv/lib/python3.11/site-packages/django/db/backends/utils.py”, line 89, in _execute
return self.cursor.execute(sql, params)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File “/openedx/venv/lib/python3.11/site-packages/django/db/backends/mysql/base.py”, line 75, in execute
return self.cursor.execute(query, args)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File “/openedx/venv/lib/python3.11/site-packages/MySQLdb/cursors.py”, line 179, in execute
res = self._query(mogrified_query)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File “/openedx/venv/lib/python3.11/site-packages/MySQLdb/cursors.py”, line 330, in _query
db.query(q)
File “/openedx/venv/lib/python3.11/site-packages/MySQLdb/connections.py”, line 280, in query
_mysql.connection.query(self, query)
MySQLdb.ProgrammingError: (1146, “Table ‘openedx.waffle_switch’ doesn’t exist”)

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
File “lms/wsgi.py”, line 21, in
application = get_wsgi_application()
^^^^^^^^^^^^^^^^^^^^^^
File “/openedx/venv/lib/python3.11/site-packages/django/core/wsgi.py”, line 13, in get_wsgi_application
return WSGIHandler()
^^^^^^^^^^^^^
File “/openedx/venv/lib/python3.11/site-packages/django/core/handlers/wsgi.py”, line 118, in init
self.load_middleware()
File “/openedx/venv/lib/python3.11/site-packages/django/core/handlers/base.py”, line 61, in load_middleware
mw_instance = middleware(adapted_handler)
^^^^^^^^^^^^^^^^^^^^^^^^^^^
File “/openedx/venv/lib/python3.11/site-packages/edx_django_utils/monitoring/internal/middleware.py”, line 518, in init
if not self._is_enabled():
^^^^^^^^^^^^^^^^^^
File “/openedx/venv/lib/python3.11/site-packages/edx_django_utils/monitoring/internal/middleware.py”, line 586, in _is_enabled
return waffle.switch_is_active(‘edx_django_utils.monitoring.enable_frontend_monitoring_middleware’)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File “/openedx/venv/lib/python3.11/site-packages/waffle/init.py”, line 23, in switch_is_active
switch = get_waffle_switch_model().get(switch_name)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File “/openedx/venv/lib/python3.11/site-packages/waffle/models.py”, line 59, in get
obj = cls.get_from_db(name)
^^^^^^^^^^^^^^^^^^^^^
File “/openedx/venv/lib/python3.11/site-packages/waffle/models.py”, line 72, in get_from_db
return objects.get(name=name)
^^^^^^^^^^^^^^^^^^^^^^
File “/openedx/venv/lib/python3.11/site-packages/django/db/models/manager.py”, line 87, in manager_method
return getattr(self.get_queryset(), name)(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File “/openedx/venv/lib/python3.11/site-packages/django/db/models/query.py”, line 633, in get
num = len(clone)
^^^^^^^^^^
File “/openedx/venv/lib/python3.11/site-packages/django/db/models/query.py”, line 380, in len
self._fetch_all()
File “/openedx/venv/lib/python3.11/site-packages/django/db/models/query.py”, line 1881, in _fetch_all
self._result_cache = list(self._iterable_class(self))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File “/openedx/venv/lib/python3.11/site-packages/django/db/models/query.py”, line 91, in iter
results = compiler.execute_sql(
^^^^^^^^^^^^^^^^^^^^^
File “/openedx/venv/lib/python3.11/site-packages/django/db/models/sql/compiler.py”, line 1562, in execute_sql
cursor.execute(sql, params)
File “/openedx/venv/lib/python3.11/site-packages/django/db/backends/utils.py”, line 67, in execute
return self._execute_with_wrappers(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File “/openedx/venv/lib/python3.11/site-packages/django/db/backends/utils.py”, line 80, in _execute_with_wrappers
return executor(sql, params, many, context)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File “/openedx/venv/lib/python3.11/site-packages/django/db/backends/utils.py”, line 84, in _execute
with self.db.wrap_database_errors:
File “/openedx/venv/lib/python3.11/site-packages/django/db/utils.py”, line 91, in exit
raise dj_exc_value.with_traceback(traceback) from exc_value
File “/openedx/venv/lib/python3.11/site-packages/django/db/backends/utils.py”, line 89, in _execute
return self.cursor.execute(sql, params)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File “/openedx/venv/lib/python3.11/site-packages/django/db/backends/mysql/base.py”, line 75, in execute
return self.cursor.execute(query, args)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File “/openedx/venv/lib/python3.11/site-packages/MySQLdb/cursors.py”, line 179, in execute
res = self._query(mogrified_query)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File “/openedx/venv/lib/python3.11/site-packages/MySQLdb/cursors.py”, line 330, in _query
db.query(q)
File “/openedx/venv/lib/python3.11/site-packages/MySQLdb/connections.py”, line 280, in query
_mysql.connection.query(self, query)
django.db.utils.ProgrammingError: (1146, “Table ‘openedx.waffle_switch’ doesn’t exist”)
unable to load app 0 (mountpoint=‘’) (callable not found or import error)
*** no app loaded. GAME OVER ***

Thank you so much.

I appreciated your help.

❯ tutor --version
tutor, version 20.0.2

It seems like the database tables are missing. Probably the database is empty because no migrations have run yet. Try running tutor k8s launch and make sure it completes successfully.

1 Like