Skip to content

Deployment

Choose where state lives

Pick between a managed database and a volume for a service's state, provision it, and know what happens to the data on a deploy.

A container’s own filesystem is temporary: anything a service writes there is gone the moment the container is replaced, on a restart, a new deployment or a rollback. Anything that has to outlive a deploy belongs in a database Lessly runs for you or on a volume you attach to the service.

Where each action lives:

SurfaceDatabase and volume actions
Product AppBoth kinds of database are created from the environment canvas, under Add service → Databases. A managed service’s side panel carries Overview, Connect, Backups, Logs and Settings. Managed Postgres lives on the product-level Databases page, which sits outside the environments in the navigation, with Databases and Backups tabs per instance and Resize and Delete on the instance itself. A volume’s Detach volume and Delete volume are on its own side panel — but creating and resizing a volume is tool-only: the Product App carries no screen for it.
CLIEvery action on this page: the CLI renders the same operation catalog as MCP. Run it from your own terminal.
MCPEvery action on this page. Tool names are linked per section.
RESTEvery action on this page, under /deployment/…. Browse the endpoints.

Choose the place

Where state livesWhat it isReach for it when
Managed service in an environmentPostgreSQL, MySQL, Redis or MongoDB running next to your services in the same environment. Created in seconds, no setup beyond a name and a size. (Recommended) over a volume for anything that is a database.You want storage a service can reach immediately, scoped to one environment.
Managed PostgresA dedicated Postgres instance that belongs to the product rather than to one environment. Carries automated backups with point-in-time recovery, and can be resized to more CPU and RAM. (Recommended) over a volume for anything that is a database.You want one instance behind several environments, or you need point-in-time recovery.
VolumeA persistent disk you attach to one service and mount at a path of your choosing.The state is not a database: uploaded files, a search index, a cache you would rather not rebuild.

The two managed options are equals — you pick one per database, by what you want from it. A volume is not a third database: it costs a short gap in service on every deploy, restart and rollback, which neither managed option does.

Provision a managed service in an environment

  1. On the environment canvas, open Add service → Databases and choose the engine. Give it a name; a slug is derived from it — lowercase letters, digits and dashes, starting with a letter. The slug must be unique within the environment, and it is also the hostname your services use to reach the database.
  2. Accept the defaults or change them: the engine version, storage (5 GiB by default, from 1 to 1024 GiB), and, for PostgreSQL, MySQL and MongoDB, the name of the initial database (app by default).
  3. Wait for it. Creation is asynchronous — the database moves through provisioning to ready. If it cannot come up it lands in provisioning_failed with the error kept on the record, and you can retry provisioning without recreating it.
  4. Wire a service to it by referring to the connection variables it publishes, as ${{<slug>.<KEY>}} — for example ${{cache.URL}} for a Redis database whose slug is cache. Nothing is injected automatically.
  5. Redeploy the service, so the reference is resolved into the release.

Through the Lessly MCP server: deployment_managed_service_provision, deployment_managed_service_list and deployment_managed_service_types. Token scope: a key with write access to the environment’s databases.

Engines and versions

EngineVersionsDefault
PostgreSQL15, 16, 1716
MySQL8.0, 8.48.4
Redis7, 87
MongoDB7, 88

What each engine publishes

EngineKeys
PostgreSQLHOST, PORT, USER, PASSWORD, DATABASE, URL, DATABASE_URL, PGHOST, PGPORT, PGUSER, PGPASSWORD, PGDATABASE
MySQLHOST, PORT, USER, PASSWORD, DATABASE, URL, DATABASE_URL, MYSQL_HOST, MYSQL_PORT, MYSQL_USER, MYSQL_PASSWORD, MYSQL_DATABASE, MYSQL_URL
RedisHOST, PORT, PASSWORD, URL
MongoDBHOST, PORT, USER, PASSWORD, DATABASE, URL, MONGODB_URI

The database’s page lists every key with the exact reference to copy and marks which ones are secret. The aliases carry the same values as the plain keys; they exist because many libraries read a particular name. Anything holding a password or a full connection string is a secret and is treated as one wherever variables are shown — see Set variables and secrets.

Every engine requires authentication, and the credentials are generated for you. The database is reachable only from services in the same environment, over the private network — it has no public address.

Statuses and what they allow

The full set is provisioning, provisioning_failed, ready, stopping, stopped, starting, resizing, backing_up, restoring and deleting. Actions are accepted only from the status that makes sense for them: you cannot resize a database that is restoring, and stop applies only to a database that is ready.

ActionRequiresWhat it does
ResizereadyGrows the storage. Increase only — shrinking is not supported.
StopreadyShuts the database down, keeping its storage and its credentials. Costs no compute; nothing can connect, so stop the services that use it first.
StartstoppedBrings it back with the same data.
DeleteRemoves the database and its storage.

MCP: deployment_managed_service_resize, deployment_managed_service_stop, deployment_managed_service_start, deployment_managed_service_delete.

Backups and restore

  • On the schedule: every ready database is backed up daily at 03:00 UTC.
  • On demand: you can take a backup at any time while the database is ready. It runs online — the database keeps serving.
  • Retention is 7 days for everything, manual backups included. There is no keep-forever option. If a snapshot has to outlive that window — before a migration, say — export the data yourself.

The backup list shows each snapshot with the time it was taken and whether it is ready to restore from. The last backup timestamp is written only once a snapshot is confirmed ready, so it can lag the real last backup by up to a day; an empty value means “none recorded yet”, not “no backups”.

You restore in place, choosing one snapshot from the list. The database must be ready or stopped to start, and moves through restoring back to ready. Restoring replaces the current contents of the database with the contents of the snapshot — take a fresh backup first if the current data still matters.

MCP: deployment_managed_service_backup, deployment_managed_service_backup_list, deployment_managed_service_restore, deployment_managed_service_connect_info.

Provision Managed Postgres

Managed Postgres is a dedicated Postgres instance provisioned for your product. A product can have several instances, and each instance holds several logical databases that you attach to services in any of the product’s environments. You manage them on the product-level Databases page, which sits outside the environments in the navigation — an instance list, with Databases and Backups tabs per instance.

  1. Create an instance with a label of your own, a Postgres major version — 16, 17 or 18, defaulting to 18 — and a tier. Creating the first Managed Postgres database from the canvas provisions a default instance for you if the product has none yet.
  2. Create a logical database on the instance, with an optional label. Its actual database and role names are generated. It is created independently of any service.
  3. Attach the database to a service. Both the instance and the database must be ready first.
  4. Redeploy the service. Attaching injects DATABASE_URL, PGHOST, PGPORT, PGUSER, PGPASSWORD and PGDATABASE into it as secret service-level variables, which behave like any other secret variable.
Tier
db-custom-1-3840the default
db-custom-2-7680
db-custom-4-15360
  • An instance can be resized to another tier later, and deleted once it holds no databases — the delete is refused while any database or attachment is still on it.
  • One database can be attached to several services at once.
  • Detaching removes exactly the six injected variables again, and deleting a database detaches it from every service first.
  • Passwords are never returned by Lessly — not in the instance view, not in the database view. The connection string reaches your service as a secret variable and nowhere else.

MCP: deployment_cloud_sql_instance_create, deployment_cloud_sql_instance_resize, deployment_cloud_sql_database_create, deployment_cloud_sql_database_attach, deployment_cloud_sql_database_detach.

Backups, restore and observations

What holds
Automatic backupsEvery night, with point-in-time recovery. 7 days of backups and transaction logs are kept.
On-demand backupsAvailable at any time; the instance stays available while one runs.
The Backups tabLists the backup runs with their type, start and end times and outcome, read live from the instance.
RestorePicks one of those runs and restores the instance in place.
Backup and recovery settingsReported together with the time that answer was last read back from the instance. A blank value means the setting has not been observed yet — it never means “disabled”.

A Managed Postgres restore is destructive over the whole instance — every database on it. The dialog asks you to type the instance label to confirm, and the instance is unavailable while it runs, which takes several minutes.

MCP: deployment_cloud_sql_instance_backup, deployment_cloud_sql_instance_backup_list, deployment_cloud_sql_instance_restore.

Create a volume

A volume belongs to one environment and is mounted into one service at a path of your choosing. What the service writes there stays there across restarts, deploys and rollbacks. Creating a volume is tool-only by design: the Product App carries no screen for it.

  1. Give it a name of up to 80 characters. A slug is derived from it, and you can set the slug yourself.
  2. Set the size in GB, from 1 to 1024.
  3. Set the mount path — an absolute path inside the container, for example /var/lib/data. This is where the volume appears to your code.
  4. Name the service to attach it to. It must live in the same environment as the volume.
  5. Deploy the service. The mount takes effect on its next deployment.

Creation is the only point at which a volume is bound to a service. A volume created without one stays unattached, and the way to give a service a volume later is to create another one.

The volume starts in provisioning and becomes ready. If provisioning fails it lands in failed with the reason kept on the volume, and a volume attached to nothing shows as detached. Volumes appear on the environment canvas, both as their own node and on the card of the service they are mounted into, which lists the mount path and size.

MCP: deployment_volume_create, deployment_volume_list, deployment_volume_get.

What a volume costs you on every deploy

The serviceHow it is deployed
Without volumesThe new release starts alongside the old one and traffic switches over once the new one is healthy. No gap in service.
With a volume mountedOnly one container can hold the disk at a time, so the old container is stopped first and the new one started afterwards. The service is briefly unavailable on every deploy, restart and rollback.

That is the trade for persistence. If a service must never have a gap, keep its state in a managed database and leave the service without a volume.

The data itself is unaffected. A new deployment gets the same disk with the same contents at the same path; the volume outlives the container, the release and the rollback.

Resizing, detaching and deleting

ActionRule
ResizeTool-only by design as well. A volume can be grown at any time, up to the same 1024 GB ceiling. It cannot be shrunk — a size smaller than the current one is refused. Growing does not move or rewrite the data.
DetachSeparates the volume from its service; the data is preserved and the volume goes to detached. The service loses the mount on its next deployment. This is one-way — a detached volume cannot be attached to another service afterwards.
DeleteDestroys the volume and everything on it, permanently and with no backup taken. Refused while the volume is still attached, so detach first. The confirmation asks you to type the volume’s slug.

Because a volume is bound to its service when it is created, detach it only when you are done with it or about to delete it.

MCP: deployment_volume_resize, deployment_volume_detach, deployment_volume_delete.

Next steps

Was this page helpful?
Esc

Start typing to search the docs.

navigateselect