A Terraform provider for Dokploy

Plugin-framework provider covering projects, environments, applications,
Compose stacks, managed databases, domains, mounts, ports, redirects,
basic auth, registries, SSH keys, certificates and backup destinations,
over Dokploy's tRPC-over-REST API.

The shim package exposes the provider to other Go modules, which is how
pulumi-dokploy bridges it.
This commit is contained in:
2026-08-09 12:17:26 +03:00
commit a6d8aa8b52
160 changed files with 24260 additions and 0 deletions

View File

@@ -0,0 +1,257 @@
package provider
import (
"github.com/hashicorp/terraform-plugin-framework-jsontypes/jsontypes"
"github.com/hashicorp/terraform-plugin-framework/resource/schema"
"github.com/hashicorp/terraform-plugin-framework/types"
)
type applicationModel struct {
ID types.String `tfsdk:"id" dokploy:"applicationId,id"`
Name types.String `tfsdk:"name" dokploy:"name"`
AppName types.String `tfsdk:"app_name" dokploy:"appName"`
Description types.String `tfsdk:"description" dokploy:"description,nullable"`
EnvironmentID types.String `tfsdk:"environment_id" dokploy:"environmentId"`
ServerID types.String `tfsdk:"server_id" dokploy:"serverId,create"`
// Source
SourceType types.String `tfsdk:"source_type" dokploy:"sourceType"`
DockerImage types.String `tfsdk:"docker_image" dokploy:"dockerImage,nullable"`
Username types.String `tfsdk:"username" dokploy:"username,nullable"`
Password types.String `tfsdk:"password" dokploy:"password,nullable"`
RegistryURL types.String `tfsdk:"registry_url" dokploy:"registryUrl,nullable"`
Repository types.String `tfsdk:"repository" dokploy:"repository,nullable"`
Owner types.String `tfsdk:"owner" dokploy:"owner,nullable"`
Branch types.String `tfsdk:"branch" dokploy:"branch,nullable"`
BuildPath types.String `tfsdk:"build_path" dokploy:"buildPath,nullable"`
GithubID types.String `tfsdk:"github_id" dokploy:"githubId,nullable"`
TriggerType types.String `tfsdk:"trigger_type" dokploy:"triggerType,nullable"`
CustomGitURL types.String `tfsdk:"custom_git_url" dokploy:"customGitUrl,nullable"`
CustomGitBranch types.String `tfsdk:"custom_git_branch" dokploy:"customGitBranch,nullable"`
CustomGitPath types.String `tfsdk:"custom_git_build_path" dokploy:"customGitBuildPath,nullable"`
CustomGitSSHKey types.String `tfsdk:"custom_git_ssh_key_id" dokploy:"customGitSSHKeyId,nullable"`
GitlabID types.String `tfsdk:"gitlab_id" dokploy:"gitlabId,nullable"`
GitlabProjectID types.Int64 `tfsdk:"gitlab_project_id" dokploy:"gitlabProjectId,nullable"`
GitlabRepository types.String `tfsdk:"gitlab_repository" dokploy:"gitlabRepository,nullable"`
GitlabOwner types.String `tfsdk:"gitlab_owner" dokploy:"gitlabOwner,nullable"`
GitlabBranch types.String `tfsdk:"gitlab_branch" dokploy:"gitlabBranch,nullable"`
GitlabBuildPath types.String `tfsdk:"gitlab_build_path" dokploy:"gitlabBuildPath,nullable"`
GitlabNamespace types.String `tfsdk:"gitlab_path_namespace" dokploy:"gitlabPathNamespace,nullable"`
GiteaID types.String `tfsdk:"gitea_id" dokploy:"giteaId,nullable"`
GiteaRepository types.String `tfsdk:"gitea_repository" dokploy:"giteaRepository,nullable"`
GiteaOwner types.String `tfsdk:"gitea_owner" dokploy:"giteaOwner,nullable"`
GiteaBranch types.String `tfsdk:"gitea_branch" dokploy:"giteaBranch,nullable"`
GiteaBuildPath types.String `tfsdk:"gitea_build_path" dokploy:"giteaBuildPath,nullable"`
BitbucketID types.String `tfsdk:"bitbucket_id" dokploy:"bitbucketId,nullable"`
BitbucketRepo types.String `tfsdk:"bitbucket_repository" dokploy:"bitbucketRepository,nullable"`
BitbucketSlug types.String `tfsdk:"bitbucket_repository_slug" dokploy:"bitbucketRepositorySlug,nullable"`
BitbucketOwner types.String `tfsdk:"bitbucket_owner" dokploy:"bitbucketOwner,nullable"`
BitbucketBranch types.String `tfsdk:"bitbucket_branch" dokploy:"bitbucketBranch,nullable"`
BitbucketPath types.String `tfsdk:"bitbucket_build_path" dokploy:"bitbucketBuildPath,nullable"`
EnableSubmodules types.Bool `tfsdk:"enable_submodules" dokploy:"enableSubmodules"`
WatchPaths types.List `tfsdk:"watch_paths" dokploy:"watchPaths,nullable"`
AutoDeploy types.Bool `tfsdk:"auto_deploy" dokploy:"autoDeploy,nullable"`
// Build
BuildType types.String `tfsdk:"build_type" dokploy:"buildType"`
Dockerfile types.String `tfsdk:"dockerfile" dokploy:"dockerfile,nullable"`
DockerContextPath types.String `tfsdk:"docker_context_path" dokploy:"dockerContextPath,nullable"`
DockerBuildStage types.String `tfsdk:"docker_build_stage" dokploy:"dockerBuildStage,nullable"`
PublishDirectory types.String `tfsdk:"publish_directory" dokploy:"publishDirectory,nullable"`
IsStaticSpa types.Bool `tfsdk:"is_static_spa" dokploy:"isStaticSpa,nullable"`
HerokuVersion types.String `tfsdk:"heroku_version" dokploy:"herokuVersion,nullable"`
RailpackVersion types.String `tfsdk:"railpack_version" dokploy:"railpackVersion,nullable"`
CleanCache types.Bool `tfsdk:"clean_cache" dokploy:"cleanCache,nullable"`
// Runtime
Env types.String `tfsdk:"env" dokploy:"env,nullable"`
BuildArgs types.String `tfsdk:"build_args" dokploy:"buildArgs,nullable"`
BuildSecrets types.String `tfsdk:"build_secrets" dokploy:"buildSecrets,nullable"`
CreateEnvFile types.Bool `tfsdk:"create_env_file" dokploy:"createEnvFile"`
Command types.String `tfsdk:"command" dokploy:"command,nullable"`
Args types.List `tfsdk:"args" dokploy:"args,nullable"`
Replicas types.Int64 `tfsdk:"replicas" dokploy:"replicas"`
MemoryReserve types.String `tfsdk:"memory_reservation" dokploy:"memoryReservation,nullable"`
MemoryLimit types.String `tfsdk:"memory_limit" dokploy:"memoryLimit,nullable"`
CPUReserve types.String `tfsdk:"cpu_reservation" dokploy:"cpuReservation,nullable"`
CPULimit types.String `tfsdk:"cpu_limit" dokploy:"cpuLimit,nullable"`
Title types.String `tfsdk:"title" dokploy:"title,nullable"`
Subtitle types.String `tfsdk:"subtitle" dokploy:"subtitle,nullable"`
Enabled types.Bool `tfsdk:"enabled" dokploy:"enabled,nullable"`
RegistryID types.String `tfsdk:"registry_id" dokploy:"registryId,nullable"`
RollbackRegistryID types.String `tfsdk:"rollback_registry_id" dokploy:"rollbackRegistryId,nullable"`
BuildRegistryID types.String `tfsdk:"build_registry_id" dokploy:"buildRegistryId,nullable"`
BuildServerID types.String `tfsdk:"build_server_id" dokploy:"buildServerId,nullable"`
RollbackActive types.Bool `tfsdk:"rollback_active" dokploy:"rollbackActive,nullable"`
NetworkIDs types.List `tfsdk:"network_ids" dokploy:"networkIds"`
DetachDokployNetwork types.Bool `tfsdk:"detach_dokploy_network" dokploy:"detachDokployNetwork"`
// Docker Swarm service settings, expressed as JSON documents.
HealthCheckSwarm jsontypes.Normalized `tfsdk:"health_check_swarm" dokploy:"healthCheckSwarm,nullable"`
RestartPolicySwarm jsontypes.Normalized `tfsdk:"restart_policy_swarm" dokploy:"restartPolicySwarm,nullable"`
PlacementSwarm jsontypes.Normalized `tfsdk:"placement_swarm" dokploy:"placementSwarm,nullable"`
UpdateConfigSwarm jsontypes.Normalized `tfsdk:"update_config_swarm" dokploy:"updateConfigSwarm,nullable"`
RollbackConfigSwarm jsontypes.Normalized `tfsdk:"rollback_config_swarm" dokploy:"rollbackConfigSwarm,nullable"`
ModeSwarm jsontypes.Normalized `tfsdk:"mode_swarm" dokploy:"modeSwarm,nullable"`
LabelsSwarm jsontypes.Normalized `tfsdk:"labels_swarm" dokploy:"labelsSwarm,nullable"`
NetworkSwarm jsontypes.Normalized `tfsdk:"network_swarm" dokploy:"networkSwarm,nullable"`
EndpointSpecSwarm jsontypes.Normalized `tfsdk:"endpoint_spec_swarm" dokploy:"endpointSpecSwarm,nullable"`
UlimitsSwarm jsontypes.Normalized `tfsdk:"ulimits_swarm" dokploy:"ulimitsSwarm,nullable"`
StopGracePeriodSwarm types.Int64 `tfsdk:"stop_grace_period_swarm" dokploy:"stopGracePeriodSwarm,nullable"`
// Preview deployments
PreviewActive types.Bool `tfsdk:"is_preview_deployments_active" dokploy:"isPreviewDeploymentsActive,nullable"`
PreviewEnv types.String `tfsdk:"preview_env" dokploy:"previewEnv,nullable"`
PreviewBuildArgs types.String `tfsdk:"preview_build_args" dokploy:"previewBuildArgs,nullable"`
PreviewBuildSecrets types.String `tfsdk:"preview_build_secrets" dokploy:"previewBuildSecrets,nullable"`
PreviewWildcard types.String `tfsdk:"preview_wildcard" dokploy:"previewWildcard,nullable"`
PreviewPort types.Int64 `tfsdk:"preview_port" dokploy:"previewPort,nullable"`
PreviewHTTPS types.Bool `tfsdk:"preview_https" dokploy:"previewHttps,nullable"`
PreviewPath types.String `tfsdk:"preview_path" dokploy:"previewPath,nullable"`
PreviewCertType types.String `tfsdk:"preview_certificate_type" dokploy:"previewCertificateType,nullable"`
PreviewCertResolver types.String `tfsdk:"preview_custom_cert_resolver" dokploy:"previewCustomCertResolver,nullable"`
PreviewLimit types.Int64 `tfsdk:"preview_limit" dokploy:"previewLimit,nullable"`
PreviewLabels types.List `tfsdk:"preview_labels" dokploy:"previewLabels,nullable"`
// Computed
ApplicationStatus types.String `tfsdk:"application_status" dokploy:"applicationStatus,ro"`
CreatedAt types.String `tfsdk:"created_at" dokploy:"createdAt,ro"`
}
func applicationResource() ResourceSpec {
return ResourceSpec{
Name: "application",
CreateProc: "application.create",
ReadProc: "application.one",
UpdateProc: "application.update",
DeleteProc: "application.delete",
UpdateAfterCreate: true,
NewModel: func() any { return &applicationModel{} },
Schema: schema.Schema{
MarkdownDescription: "A Dokploy application: a single service built from a Git repository, a Docker " +
"image, or an uploaded artifact.\n\n" +
"Dokploy's `application.create` endpoint accepts only a handful of fields, so this resource creates " +
"the application and then applies the rest of the configuration through `application.update`.\n\n" +
"~> Creating this resource does **not** deploy the application. Trigger a deployment from the " +
"Dokploy UI, the CLI, or a `terraform_data` provisioner calling `application.deploy`.",
Attributes: map[string]schema.Attribute{
"id": computedID("Unique application identifier."),
"name": requiredString("Display name of the application."),
"app_name": optionalComputedReplaceString("Unique Docker service name. Generated by Dokploy when " +
"omitted. Changing it forces a new application."),
"description": optionalString("Free-form description."),
"environment_id": requiredReplaceString("Environment this application belongs to."),
"server_id": optionalReplaceString("Remote server to deploy on. Omit to use the Dokploy host " +
"itself."),
"source_type": enumString("Where the application's code or image comes from.", sourceTypes, false),
"docker_image": optionalString("Docker image reference, when `source_type` is `docker`."),
"username": optionalString("Registry username, when pulling a private image."),
"password": sensitiveString("Registry password, when pulling a private image.", false),
"registry_url": optionalString("Registry URL, when pulling a private image."),
"repository": optionalString("GitHub repository name."),
"owner": optionalString("GitHub repository owner."),
"branch": optionalString("GitHub branch to build."),
"build_path": optionalComputedString("Path within the GitHub repository to build from."),
"github_id": optionalString("ID of the configured GitHub provider connection."),
"trigger_type": enumString("What triggers an automatic GitHub deployment.", triggerTypes, false),
"custom_git_url": optionalString("Git remote URL, when `source_type` is `git`."),
"custom_git_branch": optionalString("Branch to build for a custom Git remote."),
"custom_git_build_path": optionalString("Path within a custom Git repository to build from."),
"custom_git_ssh_key_id": optionalString("SSH key used to clone a private custom Git remote."),
"gitlab_id": optionalString("ID of the configured GitLab provider connection."),
"gitlab_project_id": schema.Int64Attribute{Optional: true, MarkdownDescription: "Numeric GitLab project ID."},
"gitlab_repository": optionalString("GitLab repository name."),
"gitlab_owner": optionalString("GitLab repository owner."),
"gitlab_branch": optionalString("GitLab branch to build."),
"gitlab_build_path": optionalComputedString("Path within the GitLab repository to build from."),
"gitlab_path_namespace": optionalString("Full GitLab namespace path."),
"gitea_id": optionalString("ID of the configured Gitea provider connection."),
"gitea_repository": optionalString("Gitea repository name."),
"gitea_owner": optionalString("Gitea repository owner."),
"gitea_branch": optionalString("Gitea branch to build."),
"gitea_build_path": optionalComputedString("Path within the Gitea repository to build from."),
"bitbucket_id": optionalString("ID of the configured Bitbucket provider connection."),
"bitbucket_repository": optionalString("Bitbucket repository name."),
"bitbucket_repository_slug": optionalString("Bitbucket repository slug."),
"bitbucket_owner": optionalString("Bitbucket repository owner."),
"bitbucket_branch": optionalString("Bitbucket branch to build."),
"bitbucket_build_path": optionalComputedString("Path within the Bitbucket repository to build from."),
"enable_submodules": optionalComputedBool("Clone Git submodules when checking out the repository."),
"watch_paths": optionalComputedStringList("Glob patterns that limit which changed paths trigger " +
"an automatic deployment."),
"auto_deploy": optionalComputedBool("Deploy automatically when the configured trigger fires."),
"build_type": enumString("How the application is built.", buildTypes, false),
"dockerfile": optionalComputedString("Path to the Dockerfile, when `build_type` is `dockerfile`."),
"docker_context_path": optionalString("Docker build context path."),
"docker_build_stage": optionalString("Target stage for a multi-stage Docker build."),
"publish_directory": optionalString("Directory served when `build_type` is `static`."),
"is_static_spa": optionalComputedBool("Serve a static build as a single-page application."),
"heroku_version": optionalComputedString("Heroku buildpack stack version."),
"railpack_version": optionalComputedString("Railpack version."),
"clean_cache": optionalComputedBool("Discard the build cache on the next deployment."),
"env": optionalString("Runtime environment variables in `KEY=value` format, one per line."),
"build_args": optionalString("Docker build arguments in `KEY=value` format, one per line."),
"build_secrets": sensitiveString("Docker build secrets in `KEY=value` format, one per line.", false),
"create_env_file": optionalComputedBool("Write the environment variables to a `.env` file in the " +
"container."),
"command": optionalString("Override the container entrypoint command."),
"args": optionalComputedStringList("Arguments appended to the container command."),
"replicas": optionalComputedInt("Number of replicas to run."),
"memory_reservation": optionalString("Soft memory reservation, for example `256m`."),
"memory_limit": optionalString("Hard memory limit, for example `512m`."),
"cpu_reservation": optionalString("Soft CPU reservation, for example `0.5`."),
"cpu_limit": optionalString("Hard CPU limit, for example `1`."),
"title": optionalString("Display title shown in the Dokploy UI."),
"subtitle": optionalString("Display subtitle shown in the Dokploy UI."),
"enabled": optionalComputedBool("Whether the application is enabled."),
"registry_id": optionalString("Registry used to push the built image."),
"rollback_registry_id": optionalString("Registry used to store rollback images."),
"build_registry_id": optionalString("Registry used by a dedicated build server."),
"build_server_id": optionalString("Server that performs builds, when separate from the deploy server."),
"rollback_active": optionalComputedBool("Keep previous images so deployments can be rolled back."),
"network_ids": optionalComputedStringList("IDs of additional Docker networks to attach."),
"detach_dokploy_network": optionalComputedBool("Detach the service from the shared `dokploy-network`."),
"health_check_swarm": optionalJSON("Docker Swarm health check configuration, as a JSON object."),
"restart_policy_swarm": optionalJSON("Docker Swarm restart policy, as a JSON object."),
"placement_swarm": optionalJSON("Docker Swarm placement constraints, as a JSON object."),
"update_config_swarm": optionalJSON("Docker Swarm rolling update configuration, as a JSON object."),
"rollback_config_swarm": optionalJSON("Docker Swarm rollback configuration, as a JSON object."),
"mode_swarm": optionalJSON("Docker Swarm service mode, as a JSON object."),
"labels_swarm": optionalJSON("Docker Swarm service labels, as a JSON object."),
"network_swarm": optionalJSON("Docker Swarm network attachments, as a JSON array."),
"endpoint_spec_swarm": optionalJSON("Docker Swarm endpoint specification, as a JSON object."),
"ulimits_swarm": optionalJSON("Docker Swarm ulimits, as a JSON object."),
"stop_grace_period_swarm": schema.Int64Attribute{Optional: true, MarkdownDescription: "Grace period in nanoseconds before a container is killed."},
"is_preview_deployments_active": optionalComputedBool("Build a preview deployment for each pull request."),
"preview_env": optionalString("Environment variables applied to preview deployments."),
"preview_build_args": optionalString("Build arguments applied to preview deployments."),
"preview_build_secrets": sensitiveString("Build secrets applied to preview deployments.", false),
"preview_wildcard": optionalString("Wildcard domain used to expose preview deployments."),
"preview_port": optionalComputedInt("Container port exposed by preview deployments."),
"preview_https": optionalComputedBool("Serve preview deployments over HTTPS."),
"preview_path": optionalComputedString("Base path for preview deployments."),
"preview_certificate_type": enumString("Certificate strategy for preview deployments.", certificateTypes, false),
"preview_custom_cert_resolver": optionalString("Traefik certificate resolver for preview deployments."),
"preview_limit": optionalComputedInt("Maximum number of concurrent preview deployments."),
"preview_labels": optionalComputedStringList("Pull request labels that opt into preview deployments."),
"application_status": computedString("Current status reported by Dokploy: `idle`, `running`, `done` or `error`."),
"created_at": computedString("RFC 3339 timestamp of when the application was created."),
},
},
}
}