Projects

Services

Plug Joppa's shared services (PostgreSQL, Redis, Mailpit…) into a project: .env variables written after a diff, Laravel test database.

The Services tab (V) plugs Joppa’s services into the project: PostgreSQL, MySQL, Redis, Mailpit, Meilisearch… Its count shows how many services are linked. One click is enough: the service’s variables go into the .env, after a diff, and follow its port.

The Services tab: PostgreSQL, MySQL, Redis and Mailpit, each with its switch

Services or processes

Under the intro, the tab says it: “Services are shared by Joppa across your projects (database, cache, mail). What the project runs itself is under Processes.” (See the processes).

  • A Joppa service runs once for all your projects; each project has its own database in it. It’s created from the Services page and plugged in here.
  • A process belongs to the project: its dev servers, workers, Docker Compose containers. It’s managed in the Processes tab.

Linked services start first with “Start all”, before the project’s processes.

Plug in a service

The services block lists Joppa’s services. Use PostgreSQL (or Redis, Mailpit…) opens a diff with two choices:

  • Link and write to .env: the service’s variables are written, and kept up to date if its port changes.
  • Link without writing: Joppa remembers the link, without touching the file.

A plugged service starts right away if it was stopped, including when you accept the services guessed as a project is added. For a database, if the project’s database doesn’t exist yet, Joppa creates it: the service’s row says “Database {name}, created when plugged in”, then, once plugged, a selector switches to another database of the service; if the chosen database doesn’t exist in the service, Create creates it. The lists of databases (the service’s page, the test database) update as soon as a database is created. A project uses only one service of each kind: plugging in MySQL replaces PostgreSQL.

Stop using… does the reverse: Unlink and clean up .env restores the value from .env.example (or removes the variable), Unlink without touching .env leaves the file as is. Variables you edited by hand are kept.

Plugging writes into the .env: if the .env editor (the Environment tab) has unsaved edits, the switches are disabled (“Save or discard your .env changes first”).

Which variable names

Joppa writes under the names the project already reads: those in .env, then those in .env.example (even commented out). It recognizes many aliases (DATABASE_URL, DIRECT_URL, POSTGRES_PRISMA_URL, POSTGRES_*, PG*, MYSQL_*…) and keeps the scheme and parameters of your existing URLs.

If the project declares nothing, Joppa uses its framework’s usual names:

Service Laravel Others
Database DB_CONNECTION, DB_HOST, DB_PORT, DB_DATABASE, DB_USERNAME, DB_PASSWORD DATABASE_URL (Symfony: with ?serverVersion=…&charset=utf8)
Redis, Valkey REDIS_HOST, REDIS_PASSWORD, REDIS_PORT REDIS_URL
Mailpit MAIL_MAILER=smtp, MAIL_HOST, MAIL_PORT… Symfony MAILER_DSN · Rails SMTP_ADDRESS, SMTP_PORT · Django EMAIL_HOST, EMAIL_PORT · Node SMTP_HOST, SMTP_PORT
Meilisearch MEILISEARCH_HOST, MEILISEARCH_KEY, SCOUT_DRIVER Symfony MEILISEARCH_URL, MEILISEARCH_API_KEY
Typesense TYPESENSE_*, SCOUT_DRIVER TYPESENSE_HOST, TYPESENSE_PORT, TYPESENSE_PROTOCOL, TYPESENSE_API_KEY

The framework is recognized by its files: Laravel (artisan), Symfony, Django (manage.py), Rails, Node (package.json).

Guessed services

Joppa reads the project’s files to guess the services it needs, even without Docker Compose. It is only a hint: nothing is added or plugged in without you.

The “This project seems to use” block: PostgreSQL with pgvector and pg_trgm, Redis, Meilisearch

Service What gives it away
PostgreSQL, MySQL, MariaDB DB_CONNECTION (pgsql, mysql, mariadb), the scheme of DATABASE_URL, DB_URL, POSTGRES_URL or MYSQL_URL, Prisma’s provider, Drizzle’s dialect, the packages pg, postgres, mysql2, mariadb…
Redis, Valkey a Laravel driver set to redis (CACHE_STORE, SESSION_DRIVER, QUEUE_CONNECTION, BROADCAST_CONNECTION), REDIS_URL, VALKEY_URL, the packages predis/predis, laravel/horizon, ioredis, redis, bullmq, iovalkey
Meilisearch, Typesense SCOUT_DRIVER, MEILISEARCH_HOST, TYPESENSE_HOST…, the packages meilisearch/meilisearch-php, typesense/typesense-php, meilisearch, typesense
Mailpit a local SMTP on port 1025 (MAIL_MAILER=smtp with MAIL_PORT=1025, or SMTP_PORT=1025)

Joppa reads the .env, then .env.example for the keys the .env lacks, composer.json, the root package.json and those of apps/*, packages/* and services/*, prisma/schema.prisma and drizzle.config.*. For the database and the cache it keeps one engine: the one the .env names wins over a schema, which wins over a package. SQLite needs no service. A lone REDIS_HOST doesn’t count: every Laravel .env.example lists it.

The result shows in two places:

  • on the project page, a line “This project seems to use PostgreSQL, Redis and Meilisearch.”, with See in Services;
  • at the top of this tab, the “This project seems to use” block, which shows where each service was seen (.env.example · DB_CONNECTION=pgsql) and the engines that would do as well (Redis “or Valkey”, MySQL “or MariaDB”). Plug in PostgreSQL 18 opens the usual diff when Joppa already has a service of that engine; otherwise Add Meilisearch opens the service’s creation, then plugs it in.

PostgreSQL extensions

For PostgreSQL, Joppa also looks for the extensions the project uses:

  • CREATE EXTENSION in .sql files (Prisma, Drizzle and Supabase migrations, database/, db/…) and in migrations;
  • in Laravel migrations, Schema::ensureVectorExtensionExists() and ->vector( (pgvector), uuid_generate_v4() (uuid-ossp), gin_trgm_ops (pg_trgm);
  • Rails enable_extension "hstore", Django CreateExtension("citext"), TrigramExtension(), VectorExtension()…;
  • Prisma extensions = [pg_trgm, uuid_ossp(map: "uuid-ossp")] and the types Unsupported("vector(…)") (pgvector) or Unsupported("geometry(…)") (PostGIS);
  • the Compose image: pgvector/pgvector, postgis/postgis.

Only the extensions Joppa can provide are kept: pgvector, PostGIS, pg_trgm, uuid-ossp, pgcrypto, citext, hstore, unaccent… The PostgreSQL row lists them (“Extensions: pgvector, pg_trgm”); a CREATE EXTENSION is enough on its own to guess PostgreSQL. Add PostgreSQL opens its creation with these extensions already ticked, on the server and for every new database. When the chosen server lacks an extension that must be enabled on the server (pgvector, PostGIS…), Enable pgvector opens its settings with the extension ticked, ready to save. The row stays as long as the PostgreSQL plugged into the project lacks one of them.

A service leaves the list as soon as the project uses a service of the same kind. The cross on a row ignores that service for this project; the one on the banner, or at the top of the block, ignores them all. What the project’s Docker Compose already runs is left to the Docker Compose import.

The test database (Laravel)

The Test database block: tests on SQLite offered on PostgreSQL, with the diff of .env.testing

A Laravel project’s tests read their database from phpunit.xml and .env.testing. When the project has one, this tab shows a Test database block that says what they ask for:

  • they ask for a given database (phpunit.xml sets DB_CONNECTION=pgsql and DB_DATABASE=shop_testing, for instance, often pointing at another tool): Joppa offers that database, under that name, in one of its services of the same engine;
  • they run on SQLite while the app uses PostgreSQL, MySQL or MariaDB: Joppa offers to run them on the same engine, in a <app database>_test database;
  • nothing is set for them: they would run on the app’s own database, which RefreshDatabase empties. Joppa offers a separate <app database>_test database.

If the app and the tests both run on SQLite, there is nothing to offer and the block does not show.

The service is the one the project already uses (else the first of the right engine), and the database name can be edited. Create and link starts the service if needed, creates the database if it is missing and writes DB_CONNECTION, DB_HOST, DB_PORT, DB_DATABASE, DB_USERNAME and DB_PASSWORD. Each file has its diff (Show changes); a filled-in DB_URL is emptied, since it would win over these values.

When the files already point at a database that doesn’t exist in the service, the block says so (“The … database doesn’t exist yet in …”) and Create the database creates it, starting the service if needed.

The project has Joppa writes to
.env.testing and phpunit.xml .env.testing, and phpunit.xml only if you tick Also update phpunit.xml
.env.testing alone .env.testing
phpunit.xml alone phpunit.xml (or phpunit.xml.dist when it is the only one)

In phpunit.xml, Joppa only touches the <env name="DB_…"> tags: it changes their value, uncomments those Laravel ships commented out, and adds the missing ones at the end of <php> with the same indentation. The rest of the file stays as it is. Before the first write, each file is copied next to it (phpunit.xml.joppa-backup, .env.testing.joppa-backup), and a file changed on disk since the preview is not overwritten.

The same choice is offered when you add a Laravel project and when you create one.

getjoppa.com › support

Loading

Not going through? Write to [email protected]. Just a question: [email protected].