core: run debugpy within worker process so it's DAP-attachable again (#23401)

This commit is contained in:
Alexander Tereshkin
2026-06-25 17:10:52 +03:00
committed by GitHub
parent e69c9d9d6a
commit c69a159130
5 changed files with 18 additions and 8 deletions

2
.vscode/launch.json vendored
View File

@@ -23,7 +23,7 @@
"request": "attach", "request": "attach",
"connect": { "connect": {
"host": "localhost", "host": "localhost",
"port": 9901 "port": 9902
}, },
"pathMappings": [ "pathMappings": [
{ {

View File

@@ -5,7 +5,7 @@ from authentik.lib.config import CONFIG
LOGGER = get_logger() LOGGER = get_logger()
def start_debug_server(**kwargs) -> bool: def start_debug_server(port_offset: int = 0, **kwargs) -> bool:
"""Attempt to start a debugpy server in the current process. """Attempt to start a debugpy server in the current process.
Returns true if the server was started successfully, otherwise false""" Returns true if the server was started successfully, otherwise false"""
if not CONFIG.get_bool("debug") and not CONFIG.get_bool("debugger"): if not CONFIG.get_bool("debug") and not CONFIG.get_bool("debugger"):
@@ -21,8 +21,9 @@ def start_debug_server(**kwargs) -> bool:
listen: str = CONFIG.get("listen.debug_py", "127.0.0.1:9901") listen: str = CONFIG.get("listen.debug_py", "127.0.0.1:9901")
host, _, port = listen.rpartition(":") host, _, port = listen.rpartition(":")
port = int(port) + port_offset
try: try:
debugpy.listen((host, int(port)), **kwargs) # nosec debugpy.listen((host, port), **kwargs) # nosec
except RuntimeError: except RuntimeError:
LOGGER.warning("Could not start debug server. Continuing without") LOGGER.warning("Could not start debug server. Continuing without")
return False return False

View File

@@ -13,6 +13,7 @@ from dramatiq import Worker, get_broker
from structlog.stdlib import get_logger from structlog.stdlib import get_logger
from authentik.lib.config import CONFIG from authentik.lib.config import CONFIG
from authentik.lib.debug import start_debug_server
LOGGER = get_logger() LOGGER = get_logger()
INITIAL_WORKER_ID = 1000 INITIAL_WORKER_ID = 1000
@@ -147,6 +148,8 @@ if __name__ == "__main__":
django.setup() django.setup()
start_debug_server(port_offset=worker_id - INITIAL_WORKER_ID + 1)
if worker_id == INITIAL_WORKER_ID: if worker_id == INITIAL_WORKER_ID:
from lifecycle.migrate import run_migrations from lifecycle.migrate import run_migrations

View File

@@ -22,7 +22,12 @@ Note that due to the Python debugger for VS Code, when a Python file in authenti
#### Debug the server or the worker #### Debug the server or the worker
Whichever process is first started listens on port `9901`. Additional processes started after that will then try to listen on the same port, which will fail, and will simply not start the debugger in that case. The server and each worker process run their own debug server on a distinct port, derived from the base port set by `AUTHENTIK_LISTEN__DEBUG_PY` (`9901` by default):
- The **server** (Gunicorn) listens on the base port (`9901`).
- The **worker** runs as one or more processes, controlled by `AUTHENTIK_WORKER__PROCESSES` (defaults to `1`). Each worker process listens on the base port plus an offset, starting at `9902` for the first process, `9903` for the second, and so on.
In VS Code, use the **Debug: Attach Server Core** launch configuration to attach to the server and **Debug: Attach Worker** to attach to the first worker process. To debug additional worker processes, duplicate the worker configuration and change its port to match (`9903`, `9904`, …).
#### Debugging in containers #### Debugging in containers
@@ -30,13 +35,14 @@ When debugging an authentik instance running in containers, there are some addit
A local clone of the authentik repository is required to set breakpoints in the code. The locally checked out repository must be on the same version/commit as the authentik version running in the containers. To check out version 2024.12.3, for example, run `git checkout version/2024.12.3`. A local clone of the authentik repository is required to set breakpoints in the code. The locally checked out repository must be on the same version/commit as the authentik version running in the containers. To check out version 2024.12.3, for example, run `git checkout version/2024.12.3`.
The debug port needs to be accessible on the local machine. By default, this is port 9901. Additionally, the container being debugged must be started as `root`, because additional dependencies need to be installed on startup. The debug port needs to be accessible on the local machine. By default, this is port 9901 for the server; the worker uses `9902` and up (one port per worker process). Additionally, the container being debugged must be started as `root`, because additional dependencies need to be installed on startup.
When running in Docker Compose, a file `compose.override.yml` can be created next to the authentik `compose.yml` file to expose the port, change the user, and enable debug mode. When running in Docker Compose, a file `compose.override.yml` can be created next to the authentik `compose.yml` file to expose the port, change the user, and enable debug mode.
```yaml ```yaml
services: services:
# Replace `server` with `worker` to debug the worker container. # To debug the worker container instead, use the `worker` service and map
# its worker ports (`9902` and up) rather than `9901`.
server: server:
user: root user: root
healthcheck: healthcheck:

View File

@@ -386,9 +386,9 @@ Defaults to `0.0.0.0:9900`.
##### `AUTHENTIK_LISTEN__DEBUG_PY` ##### `AUTHENTIK_LISTEN__DEBUG_PY`
Listening address:port for Python debugging server, see [Debugging](../../developer-docs/setup/debugging.md). Base listening address:port for the Python debugging server, see [Debugging](../../developer-docs/setup/debugging.md).
Applies to the Server and the Worker. Applies to the Server and the Worker. The Server listens on this exact port; each Worker process listens on a successive port (`9902`, `9903`, …).
Defaults to `0.0.0.0:9901`. Defaults to `0.0.0.0:9901`.