Files
pulumi-dokploy/sdk/python

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

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_idenvironmentId, default_environment_iddefaultEnvironmentId, 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 instead — see examples/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.

License

MPL-2.0.