18 resources and 5 data sources mapped into the dokploy:index module, with SDKs generated for TypeScript, Python, Go and .NET.
7.6 KiB
pulumi-dokploy
A Pulumi provider for Dokploy: 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;
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.
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
- Configuration
- Resources and data sources
- Differences from the Terraform provider
- Examples
- Development
- Releasing
Installing
The SDKs are published per language; the plugin binary is resolved automatically from this repository's GitHub releases.
# 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:
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:
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. |
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. nameis auto-generated when you omit it. Pulumi appends a random suffix to the logical resource name, the same way the AWS provider does. Passnameexplicitly whenever the Dokploy-side name matters to you.- The
web-serviceTerraform module has no direct equivalent. Write it as a ComponentResource instead — seeexamples/typescript/webService.ts, which is a port of that module.
The known API quirks documented upstream apply here unchanged, because it is the same code doing the work.
Examples
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— a small project, database and app.
Development
Requirements: Go 1.25+, Node 20+, Python 3.9+, .NET 8+, and pulumi.
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:
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:
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.