Bridge terraform-provider-dokploy into a Pulumi provider
18 resources and 5 data sources mapped into the dokploy:index module, with SDKs generated for TypeScript, Python, Go and .NET.
This commit is contained in:
206
sdk/python/README.md
generated
Normal file
206
sdk/python/README.md
generated
Normal file
@@ -0,0 +1,206 @@
|
||||
# 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).
|
||||
Reference in New Issue
Block a user