DjangoPlay + AuthX Troubleshooting
Covers signup/auth failures across the AuthX identity service, its Postgres database. Local runs via DockerCompose; production runs via systemd (no Docker). Commands differ accordingly — each secti...
On this page ▾
- 1. Diagnostic order
- 2. Service status & logs
- Local (Docker Compose)
- Production (systemd)
- 3. DNS resolution failure (socket.gaierror)
- 4. Password authentication failure (InvalidPasswordError)
- 5. Missing schema (UndefinedTableError: relation "user_identity" does not exist)
- 6. App-level signup failure after AuthX/DB look healthy
- 7. Quick reference — command differences at a glance
1. Diagnostic order
When signup/login is broken, check in this order — each layer's errors look different and point to a different fix:
- DNS resolution (
socket.gaierror/Temporary failure in name resolution) → wrong hostname inDATABASE_URL. - Password auth (
InvalidPasswordError) → role/DB password mismatch. - Missing schema (
UndefinedTableError: relation "user_identity" does not exist) → migrations never ran against this database. - App-level 500s after DB looks healthy → check DjangoPlay's own logs, not AuthX's.
- Wrong domain in a generated link (404 on a real path) →
SITE_URL/ subdomain config, not a service crash.
2. Service status & logs
Local (Docker Compose)
docker compose ps
docker compose logs authx -f
docker compose logs db -f
docker compose exec authx sh -c 'env | grep DATABASE_URL'Production (systemd)
sudo systemctl status djangoplay djangoplay-celery.service authx-identity.service --no-pager -l
sudo journalctl -u authx-identity.service --since "15 min ago" --no-pager -o cat
sudo journalctl -u djangoplay.service --since "15 min ago" --no-pager -o cat3. DNS resolution failure (socket.gaierror)
Symptom: asyncpg.exceptions traceback ending in
socket.gaierror: [Errno -3] Temporary failure in name resolution.
Cause: the host in DATABASE_URL / DATABASE_URL_SYNC doesn't resolve
in this environment. The correct hostname is different between the two
environments — this is the single biggest source of confusion:
| Environment | Correct host | Why |
|---|---|---|
| Prod (systemd, bare metal) | 127.0.0.1 |
Postgres runs locally via systemd; there's no Docker network to resolve a service name against. |
Local (Docker Compose), from the authx container |
db |
Docker Compose's internal DNS resolves service names between sibling containers. 127.0.0.1 inside a container means itself, not the db container. |
Local, from your host shell (e.g. running authx-migrate directly, outside Docker) |
127.0.0.1, port from the db service's host-mapped port (e.g. 5433, per docker-compose.yml's ports:) — not the container-internal 5432. |
You're not inside the Docker network here. |
Fix:
# check current value
sudo cat /opt/djangoplay/.dplay/.authx | grep DATABASE_URL # prod
cat .env | grep DATABASE_URL # local
# confirm it resolves (prod) — empty output = confirmed broken
getent hosts <hostname>
# fix to the correct host per the table above, then restart:
sudo systemctl restart authx-identity.service # prod
docker compose up --build -d # local4. Password authentication failure (InvalidPasswordError)
Symptom: asyncpg.exceptions.InvalidPasswordError: password authentication failed for user "authx".
Cause: whatever password is stored in Postgres for the authx role
doesn't match what's in DATABASE_URL. This is not the same as the
password "looking correct" in a config file — only a live connection test
confirms it.
Isolate it — test the password directly, independent of the app:
# prod
sudo -u postgres psql -h 127.0.0.1 -U authx -d authx
# local
docker compose exec db psql -U authx -d authxIf this fails with the password you believe is correct, Postgres itself needs updating — a visual match against a config file is not sufficient proof.
Fix — prod (persistent role, reset in place):
sudo -u postgres psql -c "ALTER ROLE authx WITH PASSWORD '<exact password from .authx>';"If the password contains ' \ ` $or backslashes, don't pass it inline with-c— write it to a.sqlfile and run withpsql -f` so the shell
doesn't mangle it.
Fix — local (Docker, throwaway data):
# fastest: wipe and reinit from .env's POSTGRES_PASSWORD
docker compose down -v
docker compose up --build -d
# OR, without losing data:
docker compose exec db psql -U authx -d authx -c "ALTER ROLE authx WITH PASSWORD '<matches .env>';"Common trap (local only): Postgres init scripts (which apply
POSTGRES_PASSWORD) only run once, on first creation of an empty data
volume. Editing .env after the authx_postgres_data volume already
exists does nothing until the volume is recreated (down -v) or the
role is altered manually.
Common trap (either environment): running psql with no -h/-p
flags may silently connect to an unrelated local Postgres instance (e.g. a
different local database, or a native install on your machine) instead of
the one you're trying to test. Always be explicit: -h 127.0.0.1 and the
correct port.
5. Missing schema (UndefinedTableError: relation "user_identity" does not exist)
Symptom: password/connection succeeds, but queries fail with
relation "user_identity" does not exist (or refresh_token).
Cause: migrations have never been applied to this database.
Fix — prod / anywhere installed via pip install authx-identity:
set -a; source /opt/djangoplay/.dplay/.authx; set +a
/opt/djangoplay/app/djangoplay-web/.venv/bin/authx-migrate upgradeauthx-migrate ships inside the installed package (as of 1.1.1) — no
source checkout of the AuthX repo is needed. It reads DATABASE_URL_SYNC
from the environment, so the env vars must be loaded into the shell
first — authx-migrate does not know about .authx or .env by name,
it just reads os.environ (or a file literally named .env in the current
directory).
Fix — local (Docker): migrations already run automatically as part of
the authx service's startup command (alembic upgrade head && uvicorn ... in docker-compose.yml). If tables are still missing after a
successful docker compose up, check docker compose logs authx for a
migration error rather than assuming it needs to be run manually.
Verify tables exist:
sudo -u postgres psql -d authx -c "\dt" # prod
docker compose exec db psql -U authx -d authx -c "\dt" # localIf authx-migrate itself fails with a Pydantic ValidationError
listing every field as "Field required": the env vars weren't loaded
into the shell before running the command. This is unrelated to Docker —
it happens identically on bare metal. Always run:
set -a; source <path-to-your-env-file>; set +a
authx-migrate upgradefrom a shell where that file actually exists, before invoking the command.
6. App-level signup failure after AuthX/DB look healthy
Check DjangoPlay's own logs, not AuthX's — the request may be failing somewhere else in the chain (rate limiting, DB write on the Django side, etc.):
sudo journalctl -u djangoplay.service --since "15 min ago" --no-pager -o cat | grep manual_signup # prod
docker compose logs djangoplay -f # if djangoplay itself runs in Docker locallyLook for users.views.ui.manual_signup log lines — Manual signup failed unexpectedly with no further detail means the actual exception is in the
authx-identity logs (section 2), not here.
7. Quick reference — command differences at a glance
| Task | Local (Docker Compose) | Production (systemd) |
|---|---|---|
| View service logs | docker compose logs authx -f |
sudo journalctl -u authx-identity.service -f |
| Restart AuthX | docker compose up --build -d |
sudo systemctl restart authx-identity.service |
Correct DB host in DATABASE_URL |
db (Compose service name) |
127.0.0.1 |
| Connect to Postgres directly | docker compose exec db psql -U authx -d authx |
sudo -u postgres psql -h 127.0.0.1 -U authx -d authx |
| Reset a stuck/mismatched password | docker compose down -v && docker compose up --build -d (wipes local volume) |
sudo -u postgres psql -c "ALTER ROLE authx WITH PASSWORD '...';" |
| Run migrations | Automatic on container start (alembic upgrade head in the compose command) |
authx-migrate upgrade (after sourcing .authx into the shell) |
| Load env vars into a shell for manual commands | Not usually needed — env_file: .env is loaded automatically for containers |
set -a; source /opt/djangoplay/.dplay/.authx; set +a |