# pulumi-dokploy A Pulumi provider for [Dokploy](https://dokploy.com): projects, environments, applications, Compose stacks, managed databases, domains, mounts, ports, redirects, basic auth, registries, SSH keys, certificates and backup destinations. This is a *bridged* provider. All of the behaviour lives in [`terraform-provider-dokploy`](https://github.com/maxvojtkov/terraform-provider-dokploy); [`pulumi-terraform-bridge`](https://github.com/pulumi/pulumi-terraform-bridge) turns it into a Pulumi package with typed SDKs for TypeScript, Python, Go and .NET. The two providers stay in lockstep — a resource added upstream shows up here after a `make tfgen`. ```ts import * as dokploy from "@maxvojtkov/pulumi-dokploy"; const shop = new dokploy.Project("shop", { name: "shop" }); const db = new dokploy.Postgres("db", { name: "shop-db", environmentId: shop.defaultEnvironmentId, dockerImage: "postgres:16-alpine", databaseName: "shop", databaseUser: "shop", databasePassword: dbPassword, }); const api = new dokploy.Application("api", { name: "api", environmentId: shop.defaultEnvironmentId, sourceType: "docker", dockerImage: "ghcr.io/acme/api:1.4.0", env: pulumi.interpolate`DATABASE_URL=postgresql://shop:${dbPassword}@${db.appName}:5432/shop`, }); new dokploy.Domain("api", { applicationId: api.id, domainType: "application", host: "api.example.com", port: 3000, https: true, certificateType: "letsencrypt", }); ``` ## Contents - [Installing](#installing) - [Configuration](#configuration) - [Resources and data sources](#resources-and-data-sources) - [Differences from the Terraform provider](#differences-from-the-terraform-provider) - [Examples](#examples) - [Development](#development) - [Releasing](#releasing) ## Installing The SDKs are published per language; the plugin binary is resolved automatically from this repository's GitHub releases. ```bash # TypeScript / JavaScript npm install @maxvojtkov/pulumi-dokploy # Python pip install pulumi_dokploy # Go go get github.com/maxvojtkov/pulumi-dokploy/sdk/go/dokploy # .NET dotnet add package Maxvojtkov.Dokploy ``` Before the first release, build and install it locally instead: ```bash make install VERSION=0.1.0 ``` That drops `pulumi-resource-dokploy` into the local plugin cache, so `pulumi up` finds it without a network fetch. ### Do I need the static SDK? Not necessarily. Pulumi can consume the Terraform provider directly, with no build step and no published SDK: ```bash pulumi package add terraform-provider maxvojtkov/dokploy ``` That generates a local SDK on the spot and is the fastest way to try things. Use this repository when you want a *versioned, published* package — stable tokens across releases, real package-manager installs, and SDKs your teammates can depend on without a codegen step. ## Configuration | Setting | Environment variable | Required | Description | | ---------------------- | ------------------------- | -------- | --------------------------------------------------------------------------- | | `dokploy:host` | `DOKPLOY_HOST` | yes | Base URL of the instance, e.g. `https://dokploy.example.com`. Trailing `/api` optional. | | `dokploy:apiKey` | `DOKPLOY_API_KEY` | yes | Token from *Settings → Profile → API/CLI*. Always treated as a secret. | | `dokploy:timeoutSeconds` | `DOKPLOY_TIMEOUT_SECONDS` | no | Per-request timeout. Defaults to `60`. | | `dokploy:insecureSkipVerify` | — | no | Skip TLS verification. Only for self-signed certificates. | ```bash pulumi config set dokploy:host https://dokploy.example.com pulumi config set --secret dokploy:apiKey "$DOKPLOY_API_KEY" ``` ## Resources and data sources | Group | Resources | | ------------ | ------------------------------------------------------------------------- | | Structure | `Project`, `Environment` | | Services | `Application`, `Compose` | | Databases | `Postgres`, `MySql`, `MariaDb`, `Mongo`, `Redis` | | Networking | `Domain`, `Mount`, `Port`, `Redirect`, `Security` | | Account | `Registry`, `SshKey`, `Certificate`, `Destination` | Data sources: `getProject`, `getProjects`, `getEnvironment`, `getApplication`, `getServers`. ## Differences from the Terraform provider Everything is a mechanical translation of the Terraform provider, with three Pulumi conventions applied on top: - **Attribute names are camelCase.** `environment_id` → `environmentId`, `default_environment_id` → `defaultEnvironmentId`, and so on. - **`name` is auto-generated when you omit it.** Pulumi appends a random suffix to the logical resource name, the same way the AWS provider does. Pass `name` explicitly whenever the Dokploy-side name matters to you. - **The `web-service` Terraform module has no direct equivalent.** Write it as a [ComponentResource](https://www.pulumi.com/docs/concepts/resources/components/) instead — see [`examples/typescript/webService.ts`](examples/typescript/webService.ts), which is a port of that module. The [known API quirks](https://github.com/maxvojtkov/terraform-provider-dokploy#known-api-quirks) documented upstream apply here unchanged, because it is the same code doing the work. ## Examples - [`examples/typescript`](examples/typescript) — a full environment: project, staging environment, Postgres, Redis, a GitHub-built web service behind a domain, a basic-auth-protected internal tool, and a Compose stack. - [`examples/python`](examples/python) — a small project, database and app. ## Development Requirements: Go 1.25+, Node 20+, Python 3.9+, .NET 8+, and `pulumi`. ```bash make tfgen # regenerate schema.json and bridge-metadata.json make provider # build the plugin binary into bin/ make build_sdks # regenerate all four SDKs make install # install the plugin into the local Pulumi plugin cache make lint test ``` `provider/resources.go` is the whole mapping layer: Terraform type names to Pulumi tokens, and Terraform provider configuration to Pulumi configuration. Adding an upstream resource means adding one line there and re-running `make tfgen build_sdks`. ### The upstream dependency `provider/go.mod` currently carries: ``` replace github.com/maxvojtkov/terraform-provider-dokploy => ../../dokploy-teraform ``` so the two repositories can be developed side by side. CI reproduces that layout by checking the upstream provider out as a sibling directory. Once `terraform-provider-dokploy` is tagged on GitHub, drop the `replace` and pin a real version instead: ```bash cd provider && go mod edit -dropreplace github.com/maxvojtkov/terraform-provider-dokploy \ && go get github.com/maxvojtkov/terraform-provider-dokploy@v0.1.0 ``` The upstream provider exposes itself through its `shim` package (`shim.NewProvider(version)`), because `internal/provider` is not importable from outside that module. ## Releasing Tag the repository and the `release` workflow does the rest: ```bash git tag v0.1.0 && git push origin v0.1.0 ``` It publishes plugin binaries to a GitHub release via GoReleaser, pushes the npm / PyPI / NuGet packages, and commits and tags the Go SDK as `sdk/v0.1.0`. The workflow needs three repository secrets: `NPM_TOKEN`, `PYPI_API_TOKEN` and `NUGET_PUBLISH_KEY`. ## License [MPL-2.0](LICENSE).