Вопрос или проблема
Я следовал документации для установки pgAdmin4 в серверном режиме на системе Debian 12. Я использовал nginx
и gunicorn
. nginx
был установлен из репозиториев Debian. Остальная часть была настроена в виртуальном окружении под ~/postgresql-env
. Я даже создал службу systemd
:
[Unit]
Description=pgAdmin4 service
After=network.target
[Service]
User=root
Group=root
Environment="PATH=/home/gin/postgresql-env/bin"
ExecStart=/home/gin/postgresql-env/bin/gunicorn --bind unix:/tmp/pgadmin4.sock --workers=1 --threads=25 --chdir /home/gin/postgresql-env/lib/python3.11/site-packages/pgadmin4 pgAdmin4:app
[Install]
WantedBy=multi-user.target
Из службы можно также увидеть, как я запускаю приложение pgAdmin4 с помощью gunicorn
изнутри виртуального окружения Python. Здесь я размышляю, следует ли мне изменить User
и Group
, так как все (var
директории, связанные с pgAdmin, а также само виртуальное окружение Python в /home/gin/postgresql-env
являются chown
-ed пользователем gin
, которым я вошел в систему (не в базу данных PostgreSQL!).
config_local.py
(находится в /home/gin/postgresql-env/lib/python3.11/site-packages/pgadmin4/config_local.py
) содержит следующее:
LOG_FILE = '/var/log/pgadmin4/pgadmin4.log'
SQLITE_PATH = '/var/lib/pgadmin4/pgadmin4.db'
SESSION_DB_PATH = '/var/lib/pgadmin4/sessions'
STORAGE_DIR = '/var/lib/pgadmin4/storage'
SERVER_MODE = True
Я запустил setup.py setup-db
и ввел несуществующий email просто для того, чтобы иметь что-то для входа. В моем случае имя пользователя [email protected]
с очень простым паролем.
Я отредактировал default
конфигурацию nginx
в /etc/nginx/sites-available/default
следующим образом:
server {
listen 80 default_server;
listen [::]:80 default_server;
root /var/www/html;
# Добавьте index.php в список, если вы используете PHP
index index.html index.htm index.nginx-debian.html;
server_name _;
location / {
# Сначала попытаться обслужить запрос как файл, затем
# как каталог, затем вернуть 404.
try_files $uri $uri/ =404;
}
location /pgadmin4/ {
include proxy_params;
proxy_pass http://unix:/tmp/pgadmin4.sock;
proxy_set_header X-Script-Name /pgadmin4;
}
}
nginx
работает, так как я вижу страницу Добро пожаловать! на обычном HTTP-порту.
Когда я пытаюсь зайти в pgAdmin в моем браузере по адресу http://<some-host>/pgadmin4
, я вижу страницу входа. Там я ввожу [email protected]
с соответствующим паролем.
Ошибки не возникает. Я перенаправляюсь на http://<some-host>/pgadmin4/browser/
, который Firefox отображает как JSON:
{
"success":0,
"errormsg":"'user_management.index'",
"info":"",
"result":null,
"data":null
}
Проверка /var/log/pgadmin4/pgadmin4.log
показывает следующее:
2025-01-09 13:57:09,359: ERROR pgadmin: 'user_management.index'
Traceback (most recent call last):
File "/home/gin/postgresql-env/lib/python3.11/site-packages/flask/app.py", line 1517, in full_dispatch_request
rv = self.dispatch_request()
^^^^^^^^^^^^^^^^^^^^^^^
File "/home/gin/postgresql-env/lib/python3.11/site-packages/flask/app.py", line 1503, in dispatch_request
return self.ensure_sync(self.view_functions[rule.endpoint])(**req.view_args)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/gin/postgresql-env/lib/python3.11/site-packages/flask_login/utils.py", line 290, in decorated_view
return current_app.ensure_sync(func)(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/gin/postgresql-env/lib/python3.11/site-packages/pgadmin4/pgadmin/authenticate/mfa/utils.py", line 304, in inner
return mfa_enabled(
^^^^^^^^^^^^
File "/home/gin/postgresql-env/lib/python3.11/site-packages/pgadmin4/pgadmin/authenticate/mfa/utils.py", line 169, in mfa_enabled
return execute_if_enabled()
^^^^^^^^^^^^^^^^^^^^
File "/home/gin/postgresql-env/lib/python3.11/site-packages/pgadmin4/pgadmin/authenticate/mfa/utils.py", line 301, in if_else_func_inner
return _func(first, second)
^^^^^^^^^^^^^^^^^^^^
File "/home/gin/postgresql-env/lib/python3.11/site-packages/pgadmin4/pgadmin/authenticate/mfa/utils.py", line 242, in mfa_session_authenticated
return authenticated() if session.get('mfa_authenticated', False) is True \
^^^^^^^^^^^^^^^
File "/home/gin/postgresql-env/lib/python3.11/site-packages/pgadmin4/pgadmin/authenticate/mfa/utils.py", line 297, in execute_func
return wrapped(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/gin/postgresql-env/lib/python3.11/site-packages/pgadmin4/pgadmin/browser/__init__.py", line 712, in index
response = Response(render_template(
^^^^^^^^^^^^^^^^
File "/home/gin/postgresql-env/lib/python3.11/site-packages/flask/templating.py", line 154, in render_template
return _render(
^^^^^^^^
File "/home/gin/postgresql-env/lib/python3.11/site-packages/flask/templating.py", line 128, in _render
rv = template.render(context)
^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/gin/postgresql-env/lib/python3.11/site-packages/jinja2/environment.py", line 1295, in render
self.environment.handle_exception()
File "/home/gin/postgresql-env/lib/python3.11/site-packages/jinja2/environment.py", line 942, in handle_exception
raise rewrite_traceback_stack(source=source)
File "/home/gin/postgresql-env/lib/python3.11/site-packages/pgadmin4/pgadmin/browser/templates/browser/index.html", line 6, in top-level template code
{% import 'browser/macros/static_user_icon.macro' as IMG with context %}
^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/gin/postgresql-env/lib/python3.11/site-packages/pgadmin4/pgadmin/templates/base.html", line 55, in top-level template code
'pgadmin.user_management.current_user': "{{ url_for('user_management.index') }}" + "current_user",
^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/gin/postgresql-env/lib/python3.11/site-packages/flask/helpers.py", line 309, in url_for
appctx.app.inject_url_defaults(endpoint, values)
File "/home/gin/postgresql-env/lib/python3.11/site-packages/flask/app.py", line 1812, in inject_url_defaults
func(endpoint, values)
File "/home/gin/postgresql-env/lib/python3.11/site-packages/pgadmin4/pgadmin/__init__.py", line 842, in add_internal_version
urls = [url for url in app.url_map.iter_rules(endpoint)]
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/gin/postgresql-env/lib/python3.11/site-packages/werkzeug/routing.py", line 1531, in iter_rules
return iter(self._rules_by_endpoint[endpoint])
~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^
KeyError: 'user_management.index'
Я пробовал ввести другого несуществующего пользователя, просто чтобы проверить, не является ли это более общей проблемой, но ошибка в таком случае валидная, а именно
2025-01-09 13:56:02,819: ERROR pgadmin: 'NoneType' object is not subscriptable
что происходит при попытке получить несуществующего пользователя, когда возвращаемый объект равен None
, что приводит к исключению в коде pgAdmin после попытки доступа к чему-то в нем.
Я очень мало знаком с nginx
и gunicorn
. Я также никогда не запускал pgAdmin в серверном режиме. У меня есть специальная виртуальная машина на сервере, где я хотел бы настроить базу данных PostgreSQL.
Если вам нужна дополнительная информация, дайте знать в комментариях, и я постараюсь ее предоставить.
Ответ или решение
При возникновении ошибки 'user_management.index'
при посещении страницы pgAdmin после входа в систему, важно учесть несколько аспектов вашей установки, которые могут влиять на работоспособность приложения.
Теория
Ошибка KeyError: 'user_management.index'
указывает на проблему с маршрутизатором URL в Flask, который использует pgAdmin4, когда он не может найти определенный URL-адрес или конечную точку. Возможной причиной является неправильно сконфигурированное приложение или ошибка в определении путей и конечных точек.
Пример
Ошибка может быть вызвана несколькими факторами:
-
Некорректная конфигурация nginx или gunicorn: Неверные настройки могут привести к тому, что запросы не будут правильно обрабатываться и перенаправляться.
-
Проблемы с правами доступа: Указанные вами пути и файлы должны быть доступны пользователю, под которым запускается сервис.
-
Ошибки в самом pgAdmin4: Ошибка в скриптах или конфигурациях pgAdmin также может привести к проблеме с нахождением нужной конечной точки.
Применение
-
Проверьте права доступа. Убедитесь, что все каталоги и файлы, которые используется pgAdmin, доступны для пользователя
gin
, который указан в конфиге сервиса systemd. Возможно, потребуется изменитьUser
иGroup
в конфиге сервиса наgin
. -
Убедитесь в правильности пути и параметров. Присмотритесь к вашему конфигу nginx:
- Убедитесь, что
proxy_pass
корректно перенаправляет запросы в gunicorn. Проверьте путь доpgadmin4.sock
. Убедитесь, что этот сокет создается и на него есть доступ у Nginx.
- Убедитесь, что
-
Проверьте конфигурацию pgAdmin4. Определите, правильно ли прописаны пути в
config_local.py
(например,SQLITE_PATH
,LOG_FILE
). -
Логи и диагностика. Изучите логи
/var/log/pgadmin4/pgadmin4.log
и логи Nginx для получения дополнительных подсказок о причине ошибки. Убедитесь, что в логах gunicorn нет ошибок при запуске приложения. -
Обновление и зависимости. Убедитесь, что вы используете актуальные версии всех компонентов: pgAdmin4, Python, Flask и связанные библиотеки. Проверьте, что все зависимости установлены корректно в виртуальной среде.
-
Отладка и тестирование. Попробуйте временно изменить конфигурацию так, чтобы pgAdmin запускался на другом порту HTTP, минуя Nginx, чтобы удостовериться в корректности работы приложения на уровне WSGI.
Если после выполнения всех вышеперечисленных шагов проблема не решается, рассмотрите возможность обращения в сообщество поддержки pgAdmin для предоставления более детальной информации о вашей конфигурации и последующей помощи.