Skip to main content

plain.dev

A single command that runs everything you need for local development.

Plain dev command example

Overview

The plain dev command starts everything you need for local development with a single command:

plain dev

This will:

  • Run preflight checks
  • Execute pending migrations
  • Start your development server with auto-reload
  • Build and watch CSS with Tailwind (if installed)
  • Start required services (like databases)
  • Run any custom processes you've defined

Commands

plain dev

The plain dev command does several things:

  • Sets PLAIN_CSRF_TRUSTED_ORIGINS to localhost by default
  • Runs plain preflight to check for any issues
  • Executes any pending model migrations
  • Starts gunicorn with --reload
  • Serves HTTPS on port 8443 by default (uses the next free port if 8443 is taken and no port is specified)
  • Runs plain tailwind build --watch, if plain.tailwind is installed
  • Any custom process defined in pyproject.toml at tool.plain.dev.run
  • Necessary services (ex. Postgres) defined in pyproject.toml at tool.plain.dev.services

Services

Use services to define databases or other processes that your app needs to be functional. The services will be started automatically in plain dev, but also in plain pre-commit (so preflight and tests have a database).

Ultimately, how you run your development database is up to you. But a recommended starting point is to use Docker:

# pyproject.toml
[tool.plain.dev.services]
postgres = {cmd = "docker run --name app-postgres --rm -p 54321:5432 -v $(pwd)/.plain/dev/pgdata:/var/lib/postgresql/data -e POSTGRES_PASSWORD=postgres postgres:15 postgres"}

Custom processes

Unlike services, custom processes are only run during plain dev. This is a good place to run something like ngrok or a Plain job worker, which you might need to use your local site, but don't need running for executing tests, for example.

# pyproject.toml
[tool.plain.dev.run]
    ngrok = {command = "ngrok http $PORT"}

plain dev services

Starts your services by themselves. Logs are stored in .plain/dev/logs/services/.

plain dev logs

Show output from recent plain dev runs.

Logs are stored in .plain/dev/logs/run/.

plain dev logs        # print last log
plain dev logs -f     # follow the latest log
plain dev logs --pid 1234
plain dev logs --path

plain dev backups

Manage local database backups. Requires plain.postgres.

A backup is automatically created when plain dev detects pending migrations, so you can easily restore your database if a migration changes something unexpectedly.

plain dev backups list              # List all backups
plain dev backups list --branch     # Filter to current branch
plain dev backups create            # Create a manual backup
plain dev backups create my-backup  # Create with a specific name
plain dev backups restore --latest  # Restore the most recent backup
plain dev backups restore my-backup # Restore a specific backup
plain dev backups delete my-backup  # Delete a specific backup
plain dev backups clear             # Delete all backups

Backups are stored in .plain/backups/ and automatically pruned to the 20 most recent per branch.

plain pre-commit

A built-in pre-commit hook that you can install with plain pre-commit --install.

Runs:

  • uv lock --check, if using uv
  • plain check (custom commands, code linting, preflight, migrations, tests)
  • plain assets compile

Custom commands can be defined in pyproject.toml at tool.plain.check.run and will run as part of plain check:

[tool.plain.check.run]
my-check = {cmd = "echo 'running my check'"}

.env files

plain.dev loads .env files for any plain command run on the dev machine. Production deployments should set environment variables through your platform — Plain does not load .env files when plain.dev isn't installed.

Files are read in this order (highest precedence first — the first file to define a key wins):

File Committed? When loaded
.env.{PLAIN_ENV}.local No If PLAIN_ENV is set
.env.local No Always, except when PLAIN_ENV=test
.env.{PLAIN_ENV} Yes If PLAIN_ENV is set
.env Yes Always

Add .env.local and .env.*.local to your .gitignore.

PLAIN_ENV is set automatically by the CLI: plain dev → dev, plain test → test. Other commands leave PLAIN_ENV unset (only .env.local and .env load). Export PLAIN_ENV yourself to override.

Under PLAIN_ENV=test, .env.local is skipped (matches Next.js and Rails dotenv) so test runs stay deterministic and personal credentials don't leak into the suite. plain test sets PLAIN_ENV=test for you; the pytest plugin also sets it when pytest is invoked directly — and opportunistically loads .env.test* if plain.dev is installed.

Settings

Setting Default Env var
DEV_REQUESTS_IGNORE_PATHS ["/favicon.ico"] -
DEV_REQUESTS_MAX 50 -

See default_settings.py for more details.

FAQs

How do I stop the development server?

You can stop the development server by pressing Ctrl+C in the terminal, or by running plain dev --stop if it was started in the background.

Can I run the server on a different port?

Yes, use the --port or -p option: plain dev --port 8000. If you don't specify a port, it will use 8443 or the next available port.

How do I run the server in the background?

Use plain dev --start to run the server in the background. You can then use plain dev --stop to stop it.

What's the difference between services and custom processes?

Services are processes that your app needs to function (like a database). They run during plain dev and also during plain pre-commit. Custom processes only run during plain dev and are typically for development conveniences like ngrok or a job worker.

Why am I seeing deprecation warnings?

The development server is configured to show DeprecationWarning and PendingDeprecationWarning messages so you can catch deprecated code before it breaks in future versions. You can override this by setting your own PYTHONWARNINGS environment variable.

Installation

Install the plain.dev package from PyPI:

uv add plain.dev --dev

Note: The plain.dev package does not need to be added to INSTALLED_PACKAGES.

Metadata

Release files for plain.dev 0.63.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for plain.dev 0.63.1
File Size Uploaded
plain_dev-0.63.1.tar.gz 42.8 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for plain.dev 0.63.1
File Interpreter ABI Platform
plain_dev-0.63.1-py3-none-any.whl Python 3 none any Details

Total release size: 93.2 kB

Release files / plain_dev-0.63.1.tar.gz

Download URL plain_dev-0.63.1.tar.gz
Size 42.8 kB
Tags Source
SHA-256 checksum
How to use checksums
5db74ac4e5b7b75096f75ee83978e209243c1e70e05a82b56d3c92d749209aba
BLAKE2b-256 checksum
How to use checksums
0abd1934f00c31cb70cce606db03cc5d33cc281693f70ef17d69b0d1122d9c03
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.11.19 {"installer":{"name":"uv","version":"0.11.19","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / plain_dev-0.63.1-py3-none-any.whl

Download URL plain_dev-0.63.1-py3-none-any.whl
Size 50.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
d8de26f45bff408410d2efaea252eb191c41aef68901798dd30a57c119c3498b
BLAKE2b-256 checksum
How to use checksums
c14913c1e755967a98849bc63534b310b807ca211a9e825b3962ed751bc1d655
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.11.19 {"installer":{"name":"uv","version":"0.11.19","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release history Release notifications | RSS feed

0.70.0

2 release files

0.69.1

2 release files

0.69.0

2 release files

0.66.1

2 release files

0.65.0

2 release files

0.64.0

2 release files

0.63.2

2 release files

This release

0.63.1 This release

2 release files

0.63.0

2 release files

0.62.0

2 release files

0.61.0

2 release files

0.60.3

2 release files

0.60.2

2 release files

0.60.1

2 release files

0.60.0

2 release files

0.59.2

2 release files

0.59.1

2 release files

0.59.0

2 release files

0.58.4

2 release files

0.58.3

2 release files

0.58.2

2 release files

0.56.0

2 release files

0.55.1

2 release files

0.55.0

2 release files

0.54.2

2 release files

0.54.1

2 release files

0.54.0

2 release files

0.53.0

2 release files

0.52.0

2 release files

0.51.0

2 release files

0.50.0

2 release files

0.49.1

2 release files

0.47.1

2 release files

0.47.0

2 release files

0.46.0

2 release files

0.44.0

2 release files

0.43.1

2 release files

0.43.0

2 release files

0.42.0

2 release files

0.41.0

2 release files

0.40.0

2 release files

0.39.0

2 release files

0.38.0

2 release files

0.37.0

2 release files

0.36.0

2 release files

0.35.0

2 release files

0.34.0

2 release files

0.33.2

2 release files

0.33.1

2 release files

0.33.0

2 release files

0.32.1

2 release files

0.32.0

2 release files

0.30.1

2 release files

0.29.2

2 release files

0.29.1

2 release files

0.29.0

2 release files

0.28.0

2 release files

0.26.1

2 release files

0.26.0

2 release files

0.25.0

2 release files

0.22.1

2 release files

0.22.0

2 release files

0.21.0

2 release files

0.20.2

2 release files

0.20.1

2 release files

0.20.0

2 release files

0.19.3

2 release files

0.19.2

2 release files

0.16.0

2 release files

0.15.0

2 release files

0.14.2

2 release files

0.14.1

2 release files

0.14.0

2 release files

0.13.0

2 release files

0.11.0

2 release files

0.10.0

2 release files

0.9.0

2 release files

0.8.3

2 release files

0.8.2

2 release files

0.8.1

2 release files

0.8.0

2 release files

0.7.6

2 release files

0.7.5

2 release files

0.7.4

2 release files

0.7.3

2 release files

0.7.2

2 release files

0.7.1

2 release files

0.7.0

2 release files

0.6.0

2 release files

0.5.0

2 release files

0.4.0

2 release files

0.3.0

2 release files

0.2.0

2 release files

0.1.0

2 release files

0.0.1

2 release files

0.0.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page