130 lines
3.6 KiB
Markdown
130 lines
3.6 KiB
Markdown
# Recovering Immich Admin Access via PostgreSQL
|
|
|
|
> Companion for the `immich-server` skill. Covers the "locked out of admin" scenario — looking up user info, resetting passwords, and understanding how API keys are stored. Assumes you have shell access to the Docker host where Immich runs.
|
|
|
|
## Prerequisites
|
|
|
|
- Shell access to the machine running Immich Docker containers
|
|
- The `immich_postgres` container is running
|
|
- The DB credentials from `/opt/immich/.env` (or wherever your compose lives)
|
|
|
|
## Find the Immich PostgreSQL Table Structure
|
|
|
|
The `user` table (note: lowercase, not `users`) stores everything:
|
|
|
|
```bash
|
|
docker exec immich_postgres psql -U postgres -d immich -c "\dt"
|
|
```
|
|
|
|
Full list of tables (61+ as of Immich v2.7.x):
|
|
|
|
```
|
|
activity, album, album_asset, album_user, api_key, asset, asset_exif, asset_face,
|
|
asset_file, asset_job_status, asset_metadata, asset_ocr, face_search, library,
|
|
memory, person, session, shared_link, smart_search, stack, tag, tag_asset,
|
|
user, user_metadata, workflow, ...
|
|
```
|
|
|
|
## Find Your Admin Email
|
|
|
|
```bash
|
|
docker exec immich_postgres psql -U postgres -d immich -c \
|
|
"SELECT id, email, name, \"isAdmin\", \"oauthId\" FROM \"user\";"
|
|
```
|
|
|
|
Output:
|
|
```
|
|
id | email | name | isAdmin
|
|
--------------------+---------------------------+------+---------
|
|
523cab1b-... | you@gmail.com | You | t
|
|
4defcb72-... | partner@gmail.com | Name | f
|
|
```
|
|
|
|
- `isAdmin = t` = admin account
|
|
- `isAdmin = f` = user account / partner share
|
|
|
|
## Reset an Admin Password
|
|
|
|
If you don't know the password and can't log in:
|
|
|
|
**Step 1 — Install bcrypt on the host:**
|
|
|
|
```bash
|
|
sudo apt install -y python3-bcrypt
|
|
```
|
|
|
|
**Step 2 — Generate a bcrypt hash for your new password:**
|
|
|
|
```bash
|
|
HASH=$(python3 -c "
|
|
import bcrypt
|
|
# Use 'admin123' or whatever you want
|
|
pw_hash = bcrypt.hashpw(b'admin123', bcrypt.gensalt(rounds=10))
|
|
print(pw_hash.decode())
|
|
")
|
|
```
|
|
|
|
**Step 3 — Update the password in the database:**
|
|
|
|
```bash
|
|
docker exec immich_postgres psql -U postgres -d immich -c \
|
|
"UPDATE \"user\" SET \"password\"='$HASH' WHERE email='you@gmail.com';"
|
|
```
|
|
|
|
**Step 4 — Log in** with the new password at `http://192.168.x.x:2283`.
|
|
|
|
> ⚠️ The Immich server may cache the old session — refresh the login page or use a private browser window.
|
|
|
|
## API Keys: Storage & Recovery
|
|
|
|
**API keys are stored hashed (PBKDF2-SHA256) — you CANNOT recover the raw key from the DB.**
|
|
|
|
### List all API keys (who owns what)
|
|
|
|
```bash
|
|
docker exec immich_postgres psql -U postgres -d immich -c \
|
|
"SELECT ak.id, ak.name, u.name as owner, \"userId\" FROM \"api_key\" ak LEFT JOIN \"user\" u ON ak.\"userId\" = u.id;"
|
|
```
|
|
|
|
The `key` column stores the hash — no way to reverse it. If you lost the raw key, you must:
|
|
|
|
1. Log in to Immich web UI as admin
|
|
2. Go to **Settings → API Keys**
|
|
3. Delete the old key and create a new one
|
|
|
|
### If you can't log in at all
|
|
|
|
Reset the admin password (above), then use the web UI to create a new API key.
|
|
|
|
## Finding the DB Credentials
|
|
|
|
Immich stores them in the compose directory:
|
|
|
|
```bash
|
|
cat /opt/immich/.env
|
|
```
|
|
|
|
Expected vars:
|
|
```
|
|
DB_USERNAME=postgres
|
|
DB_PASSWORD=...
|
|
DB_DATABASE_NAME=immich
|
|
```
|
|
|
|
If the .env file path differs, find it:
|
|
```bash
|
|
find / -name "docker-compose.yml" -path "*immich*" 2>/dev/null
|
|
```
|
|
Then check the same directory for the .env file.
|
|
|
|
## Test DB Connection Directly
|
|
|
|
```bash
|
|
# Simple auth test (no password prompt):
|
|
docker exec immich_postgres psql -U postgres -d immich -c "SELECT 1 as connected;"
|
|
|
|
# If that fails with authentication error, try with password:
|
|
docker exec -e PGPASSWORD=your_db_password immich_postgres psql \
|
|
-U postgres -d immich -c "SELECT 1 as connected;"
|
|
```
|