How to Set Up a PostgreSQL Database for a Claude Code App

Vibesies Team | 2026-05-09 | guides

If you’re building a serious app with Claude Code, sooner or later you’ll need a database. For most projects, the right answer is PostgreSQL. This guide walks through how to set up a PostgreSQL database for a Claude Code app on Linux, with enough detail to avoid the usual traps: weak permissions, bad connection strings, messy migrations, and backups that only exist in theory.

This is written for people who already know their way around a shell and want a practical setup they can trust in production. If you’re hosting in a sandboxed Linux environment like Vibesies, the same principles apply: keep credentials isolated, make backups automatic, and let your agent do the repetitive parts without turning your app into a science project.

Why PostgreSQL is usually the right choice for Claude Code apps

Claude Code can help you build with almost any storage layer, but PostgreSQL tends to be the safest default for real apps. It handles relational data well, supports JSON when you need flexibility, and scales from a side project to a production system without forcing a rewrite.

It’s a good fit if your app needs any of the following:

  • User accounts and authentication
  • Orders, subscriptions, or billing records
  • Content management with relationships
  • Event logs, audit trails, or activity feeds
  • Searchable metadata with a mix of structured and semi-structured data

If your app is truly static, you may not need a database yet. But once you’re storing anything that must survive restarts and scale beyond a single file, PostgreSQL is usually the cleanest option.

How to set up a PostgreSQL database for a Claude Code app

Here’s the setup I recommend for most Linux-hosted apps:

1. Install PostgreSQL

On Ubuntu or Debian:

sudo apt update
sudo apt install postgresql postgresql-contrib

Confirm it’s running:

sudo systemctl status postgresql

On a managed environment, PostgreSQL may already be available. In that case, skip the install step and focus on creating a dedicated database and user.

2. Create a dedicated database and user

Do not use the default postgres superuser for your app. Create a separate user with only the permissions it needs.

sudo -u postgres psql

Then inside the PostgreSQL prompt:

CREATE DATABASE myapp;
CREATE USER myapp_user WITH ENCRYPTED PASSWORD 'use-a-strong-password';
GRANT ALL PRIVILEGES ON DATABASE myapp TO myapp_user;

If your app has a migration tool that needs schema ownership, you may also want to make the app user the owner of the database:

ALTER DATABASE myapp OWNER TO myapp_user;

That keeps migrations clean and avoids permission errors later.

3. Store the connection string in an environment variable

Use a single database URL rather than hardcoding values in your app:

DATABASE_URL=postgresql://myapp_user:password@127.0.0.1:5432/myapp

For local development, this might live in a .env file. In production, put it in your process manager, secret store, or platform-level environment config. The important thing is that it stays out of git.

4. Test the connection before wiring up the app

Check that PostgreSQL is reachable with the same credentials your app will use:

psql "$DATABASE_URL"

If that works, your app should be able to connect too. If it doesn’t, fix the database credentials before you start debugging your app code. You’ll save time.

5. Hook up migrations

Most Claude Code apps will need migrations as soon as the schema changes. Use whatever migration tool matches your stack:

  • Flask / Python: Alembic or Flask-Migrate
  • Django: built-in migrations
  • Node.js: Prisma, Knex, or your ORM’s migration tool

The main rule: migrations should be versioned, repeatable, and committed to your repo. Claude Code can generate them, but you should still review them before applying changes to production.

Common PostgreSQL setup mistakes with AI-built apps

Claude Code is good at generating application logic, but database setup is where small omissions become production problems. These are the mistakes I see most often.

Using a superuser for the app

This is the classic “works on my machine” shortcut. It’s also a security problem. Give your application only the permissions it needs.

Hardcoding credentials in source files

Once secrets are in code, they tend to spread. They get copied into examples, test files, and deployment scripts. Use environment variables and rotate credentials if you suspect they were exposed.

Ignoring connection pooling

Small apps can get away with a direct connection. As traffic grows, you may need pooling through PgBouncer or a managed equivalent. Without it, you can hit connection limits long before your server is actually busy.

Letting Claude Code generate schema changes without review

AI can draft the migration, but you should still check:

  • Whether columns allow NULL correctly
  • Whether indexes match real query patterns
  • Whether foreign keys are appropriate
  • Whether a migration might lock a large table for too long

Skipping backups because the project is “still early”

Early-stage apps are often the easiest to back up and the hardest to recover from if you haven’t set anything up. Make backups part of the initial deployment, not a later cleanup task.

A practical schema checklist for Claude Code projects

If you’re asking Claude Code to design tables, this checklist helps keep the output sane:

  • Start with entities, not columns. Define the objects your app stores first.
  • Normalize where it matters. Don’t duplicate user data across tables unless you have a reason.
  • Add timestamps everywhere. Use created_at and updated_at consistently.
  • Index query-heavy fields. Especially foreign keys, status columns, and lookup keys.
  • Use constraints. Enforce uniqueness and required relationships in the database, not just the app layer.
  • Prefer explicit naming. Tables like user_profiles and invoice_items are easier to maintain than generic names like data or records.

If you want Claude Code to help design the schema, ask it to produce three things: the tables, the relationships, and the migration steps. That gives you a better review surface than asking for “the database code” and hoping it gets the structure right.

How to back up PostgreSQL safely

A good PostgreSQL setup is not just about creating tables. You also need a recovery plan.

For a first pass, use pg_dump for logical backups:

pg_dump "$DATABASE_URL" > backup.sql

For larger databases, compressed custom-format dumps are usually better:

pg_dump -Fc "$DATABASE_URL" -f backup.dump

Then automate the backup and store it somewhere separate from the server. A backup on the same disk as the database is not much help if the disk dies.

At minimum, verify that you can restore the backup:

pg_restore -d myapp_restored backup.dump

If you’re using a platform with built-in backups, like a managed Linux hosting setup, still test the restore process. Backups only count if they can be restored under pressure.

Local development versus production

It’s fine to start with SQLite or a local PostgreSQL instance during development, but production should match the same storage engine and as much of the same schema behavior as possible.

Here’s a simple rule:

  • Development: quick setup, disposable data, frequent schema changes
  • Staging: production-like config, seeded test data, realistic migrations
  • Production: locked-down credentials, backups, monitoring, and restore tests

If Claude Code is building features in all three environments, keep the database URL and migrations consistent so you don’t discover differences only after deployment.

When to consider a managed database

Running PostgreSQL yourself is fine for many projects, especially if you want full control. But a managed database can be worth it when you need:

  • Automated backups and point-in-time recovery
  • Built-in high availability
  • Easy scaling without managing the OS
  • Less operational work for a small team

The tradeoff is cost and less control over the server environment. For developers who want to stay close to the Linux stack and keep the whole app in one place, self-hosting can still make sense. That’s especially true in a sandboxed setup where the app, agent, and database are easy to reason about together.

Quick setup checklist

Before you ship, verify these items:

  • PostgreSQL is installed and running
  • Your app has its own database and non-root user
  • The database URL is stored as a secret or environment variable
  • Migrations are versioned and tested
  • Indexes exist for common queries
  • Backups run automatically
  • You’ve tested one restore
  • Production credentials are different from development credentials

Final thoughts

Setting up PostgreSQL is one of those tasks that looks boring until it saves your project. If you’re building with Claude Code, taking the time to create a clean database setup will pay off every time you add a feature, change a schema, or recover from a bad deploy.

The basic formula is simple: use a dedicated database user, store credentials safely, wire up migrations, and make backups real instead of aspirational. If you keep those pieces in place, how to set up a PostgreSQL database for a Claude Code app becomes less of a one-time task and more of a repeatable part of your deployment process.

For teams building on Linux with an agent in the loop, that kind of discipline matters more than flashy tooling. It’s what keeps the app stable when the code changes fast.

Back to Blog
["postgresql", "claude code", "linux hosting", "database setup", "migrations", "backups"]