Local Development
Your day-to-day work in zap.ts: the Docker services, running several apps at once, the demo data and resetting the database.
This page is about normal work, after the first time. If you have not started zap.ts yet, read Quickstart first.
The three Docker services
Docker runs three services for you. They replace three paid cloud services while you work on your own computer.
Start them:
docker compose up -d
-d means “in the background”. You start them once. They keep running, even
after you close your terminal.
| Service | What it does | Ports |
|---|---|---|
| Postgres | The database. It stores your data. | 5432 |
| Mailpit | A fake email inbox. | 1025 to send, 8025 for the web page |
| MinIO | A file store for uploads. | 9000 for the API, 9001 for the web page |
Postgres
Postgres listens on port 5432. The user is postgres, the password is
postgres and the database is postgres.
Your data lives in a Docker volume. A volume is a folder Docker keeps for you, so your data survives a restart.
Mailpit
Your app does not send real email while you work. It sends to Mailpit on port 1025 instead.
Open localhost to read what your app sent. Every email lands there, whoever the address was.
MinIO
MinIO stores uploaded files. It speaks the same language as Cloudflare R2, so your code does not change when you move to a real cloud later.
Port 9000 is the one your code talks to. Port 9001 is a web page you can open:
localhost. Sign in with minioadmin as the user
and minioadmin as the password.
Docker also creates a bucket named zap for you. A bucket is a folder that
holds your uploaded files.
Stopping and starting
docker compose stop # pause the services, keep the data
docker compose up -d # start them again
Running several apps at once
Each app has its own command and its own port. Open one terminal window per app.
pnpm run dev:web # port 3000
pnpm run dev:marketing # port 3001
pnpm run dev:docs # port 3002
pnpm run dev:admin # port 3003
pnpm run dev:emails # port 3004
pnpm run dev:api # port 8787
The ports are all different, so nothing clashes. You can run all six together.
What the demo data contains
pnpm run db:seed fills the database with a small example company.
You get:
- One organisation, named Demo Organization, with the slug
demo. - Three users, one for each role in that organisation.
- One active subscription on the
starterplan, with three seats.
The three users are:
| Name | Role | |
|---|---|---|
owner@demo.test |
Olivia Owner | owner |
admin@demo.test |
Adam Admin | admin |
member@demo.test |
Mia Member | member |
They all share the same password: demo1234.
The owner also carries the site-wide admin role. So the same account opens
the back office on port 3003.
Running the seed again
You can run pnpm run db:seed as often as you like.
Every row it creates has a fixed id. The script deletes its own rows first, then writes them again. It never touches the rest of your data.
Run it again after a migration. A migration is a file that changes the shape of the database.
Resetting the database
Sometimes you want to start over with an empty database.
docker compose down -v
docker compose up -d
pnpm run db:migrate
pnpm run db:seed
-v deletes the volume, so it deletes every row you had. Then you start
Postgres again, create the tables again, and put the demo data back.
Looking inside the database
To see your tables and rows, run:
pnpm run db:studio
This opens Drizzle Studio. It is a web page where you read your tables, and change a row by hand when you need to.
It is useful when a test fails and you want to know what is really stored.
The other database scripts
| Script | What it does |
|---|---|
pnpm run db:generate |
Writes a new migration file after you change the schema |
pnpm run db:migrate |
Applies the migration files to the database |
pnpm run db:push |
Pushes your schema straight to the database, with no migration file |
pnpm run db:seed |
Writes the demo data |
pnpm run db:studio |
Opens Drizzle Studio |
Use db:generate and db:migrate for real work. db:push is quick, but it
leaves no file behind, so keep it for throwaway experiments.
Related
- Quickstart — the first run
- Environment — settings and keys
- Database — tables, schema and migrations
- Testing — giving a test a real database
- Project structure — what each folder holds