--- since: 1.1.1 --- # 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 section below is split. --- ## 1. Diagnostic order When signup/login is broken, check in this order — each layer's errors look different and point to a different fix: 1. **DNS resolution** (`socket.gaierror` / `Temporary failure in name resolution`) → wrong hostname in `DATABASE_URL`. 2. **Password auth** (`InvalidPasswordError`) → role/DB password mismatch. 3. **Missing schema** (`UndefinedTableError: relation "user_identity" does not exist`) → migrations never ran against this database. 4. **App-level 500s after DB looks healthy** → check DjangoPlay's own logs, not AuthX's. 5. **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) ```bash 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) ```bash 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 cat ``` --- ## 3. 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:** ```bash # 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 # fix to the correct host per the table above, then restart: sudo systemctl restart authx-identity.service # prod docker compose up --build -d # local ``` --- ## 4. 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:** ```bash # prod sudo -u postgres psql -h 127.0.0.1 -U authx -d authx # local docker compose exec db psql -U authx -d authx ``` If 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):** ```bash sudo -u postgres psql -c "ALTER ROLE authx WITH PASSWORD '';" ``` If the password contains `' \` \` $` or backslashes, don't pass it inline with `-c` — write it to a `.sql` file and run with `psql -f` so the shell doesn't mangle it. **Fix — local (Docker, throwaway data):** ```bash # 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 '';" ``` **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`:** ```bash set -a; source /opt/djangoplay/.dplay/.authx; set +a /opt/djangoplay/app/djangoplay-web/.venv/bin/authx-migrate upgrade ``` `authx-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:** ```bash sudo -u postgres psql -d authx -c "\dt" # prod docker compose exec db psql -U authx -d authx -c "\dt" # local ``` **If `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: ```bash set -a; source ; set +a authx-migrate upgrade ``` from 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.): ```bash 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 locally ``` Look 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` |