11ai supabase environment
Version baseline: Supabase CLI v2, supabase-js v2, and the current CLI local Postgres 17 line. Inspect the linked project, installed client patch, CLI patch, and remote Postgres version before changing configuration or migrations.
The most consequential thing to establish is which database a command will reach: the local Docker stack or the linked remote project. Several CLI commands quietly target the remote one, so confirm the link before anything that writes. Keep this pass read-only.
Inspect the CLI and project
supabase --version
docker info --format '{{.ServerVersion}}' 2>/dev/null || echo "docker unavailable"
ls -la supabase/
cat supabase/config.toml 2>/dev/null | head -30
The local stack runs in Docker, so an unavailable daemon makes every local command fail with an error that does not mention Docker. Check it first.
A supabase/ directory with a config.toml means the project is initialized. Its project_id is the local identifier, not the remote reference.
Establish the link and the target
supabase projects list
cat supabase/.temp/project-ref 2>/dev/null || echo "not linked"
supabase migration list
supabase migration list --linked
This is the important step. supabase link stores a project reference, and once it exists, db push, db diff --linked, functions deploy, and secrets set act on that remote project. A developer expecting local behaviour can migrate production with one command.
supabase migration list shows local versus remote applied state side by side, which is how a drift between the two is spotted before a push.
Never assume the linked project is a development one. Read its name and reference from supabase projects list and confirm it against what the user expects.
Check the local stack
supabase status
docker ps --filter 'name=supabase' --format '{{.Names}}\t{{.Status}}'
supabase status prints the local API URL, database URL, Studio URL, and the local anon and service role keys. Those local keys are fixed development values, not secrets — but treat the output as sensitive by habit, because the same command shape prints real values in other contexts.
If the stack is not running, say so rather than starting it. Starting Docker containers is a state change belonging to 11ai-operator-supabase-setup.
Check what the application reads
ls -la .env .env.local .env.example 2>/dev/null
grep -o '^[A-Z_]*' .env.local 2>/dev/null | sort
grep -c 'SUPABASE_SERVICE_ROLE_KEY\|SUPABASE_SECRET_KEY' .env.local 2>/dev/null
grep -rn 'SERVICE_ROLE\|SUPABASE_SECRET' --include='*.ts' --include='*.tsx' src/ app/ 2>/dev/null | head
List variable names, never values. A single cat .env.local prints a service role key into this transcript, and that key bypasses every row level security policy in the project.
The last command is a real check worth running every time: a service role key referenced anywhere reachable by the browser — a client component, a public config, a NEXT_PUBLIC_ variable — exposes the entire database. Report it as a finding immediately.
Interpretation
Cannot connect to the Docker daemon— the local stack cannot run. This is a Docker problem, not a Supabase one.Cannot find project refor a command asking for--project-ref— the directory is not linked. Local commands still work; remote ones do not.- Local and remote migration lists differing — drift. Someone applied a change through Studio or by hand. Resolve it before pushing, or
db pushwill fail or overwrite. supabase startsucceeding but the application failing to connect — the application is reading remote keys while the stack is local, or the reverse. Compare the URL in the environment file againstsupabase status.- An anon key rejected with a permission error — that is usually row level security working as intended, not a key problem. Hand off to
11ai-operator-supabase-rls. - A
NEXT_PUBLIC_prefix on a service role key — the key is in the browser bundle. Treat it as compromised and rotate it.
Report
State the CLI version, whether Docker is available, whether the directory is initialized and linked, the linked project reference and name, the local stack status with its URLs, the variable names the application reads on each side, and the local versus remote migration state. Report values only as set or unset. Flag any service role key reachable from client code as an exposure. End with the smallest next safe step, and hand off to 11ai-operator-supabase-setup if the project is not initialized or to 11ai-operator-supabase-troubleshooting if something is already failing.