Skip to content

Getting started ​

Duploy runs your code on our nodes. You describe the project in one file, duploy.toml, at the root of your repository; Duploy builds it, rolls it out and keeps it running. There are no servers to install.

1. Install the CLI ​

bash
curl -fsSL https://panel.duploy.dev/cli/install.sh | sh

The script installs duploy and registers shell completion for your shell. Options go in as environment variables:

VariableEffect
DUPLOY_VERSIONInstall a specific version instead of the latest
DUPLOY_INSTALL_DIRInstall somewhere other than ~/.local/bin
DUPLOY_NO_COMPLETIONS=1Skip shell completion

Completion is dynamic: pressing Tab after -p, logs, db or tunnel offers the real names of your projects, services and databases.

2. Sign in ​

bash
duploy login        # opens the panel in your browser to approve the device
duploy whoami
duploy use acme     # pick an org; `duploy use acme/shop` picks a project too

duploy login --no-browser prints the URL instead of opening it. In CI, use an access token instead of a login: see CI and automation.

3. Create a project and connect the repository ​

Create a project in the panel and connect its GitHub repository. From then on every push to the linked branch is picked up: Duploy reads duploy.toml, rebuilds the services whose files changed and deploys them.

Link your working copy to the project so the CLI knows where you are:

bash
cd ~/code/shop
duploy link shop    # writes a .duploy file; `duploy unlink` removes it

The CLI resolves the project in this order: -o/-p flags, then the nearest .duploy file, then duploy use.

4. Write duploy.toml ​

A web service built from the repository's Dockerfile, plus a Postgres database:

toml
version = 1

[services.web]
source = { path = ".", dockerfile = "Dockerfile" }
port = 8080
domains = [{ host = "shop.example.com" }]
health = { http = "/healthz" }

[services.web.env]
DATABASE_URL = { from_database = "db" }
SESSION_KEY = { secret = true }

[databases.db]
engine = "postgres"
version = "18"
backup = { schedule = "0 3 * * *", retain = 7 }
  • port is where your app listens inside the container. It also reaches the app as $PORT.
  • from_database injects the connection URL of the managed database; the password never appears in the file.
  • secret = true declares a secret. The value is written separately and is never shown again.

The full key list is in the duploy.toml reference.

5. Set secrets and deploy ​

bash
duploy secret set web SESSION_KEY=$(openssl rand -hex 32)
git add duploy.toml && git commit -m "deploy on duploy" && git push

The push starts a build and then a deploy. To follow along, or to trigger one by hand:

bash
duploy deploy web          # streams the log until the deploy finishes
duploy services            # status, replicas, last build
duploy logs web -f         # the container log

6. Point DNS at Duploy ​

Your domain gets a certificate from Let's Encrypt as soon as its DNS points at Duploy. duploy project ingress shows what to point it at. See Domains and TLS.

Next ​

Duploy — our nodes, your file.