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:
200
examples/complete/main.tf
Normal file
200
examples/complete/main.tf
Normal file
@@ -0,0 +1,200 @@
|
||||
# A complete Dokploy environment: a project, a staging environment, a public
|
||||
# web service with a database and a cache behind it, and a Compose stack.
|
||||
#
|
||||
# export DOKPLOY_HOST=https://dokploy.example.com
|
||||
# export DOKPLOY_API_KEY=...
|
||||
# terraform init && terraform apply
|
||||
|
||||
terraform {
|
||||
required_version = ">= 1.5"
|
||||
required_providers {
|
||||
dokploy = {
|
||||
source = "maxvojtkov/dokploy"
|
||||
version = ">= 0.1"
|
||||
}
|
||||
random = {
|
||||
source = "hashicorp/random"
|
||||
version = ">= 3.6"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
provider "dokploy" {
|
||||
# host and api_key are read from DOKPLOY_HOST and DOKPLOY_API_KEY.
|
||||
}
|
||||
|
||||
# ------------------------------------------------------------------- structure
|
||||
|
||||
resource "dokploy_project" "shop" {
|
||||
name = "shop"
|
||||
description = "Storefront and its backing services"
|
||||
|
||||
# Shared by every service in the project.
|
||||
env = "TZ=Europe/Bucharest"
|
||||
}
|
||||
|
||||
# Dokploy creates a default "production" environment with the project; add a
|
||||
# second one for staging.
|
||||
resource "dokploy_environment" "staging" {
|
||||
name = "staging"
|
||||
description = "Pre-production"
|
||||
project_id = dokploy_project.shop.id
|
||||
|
||||
env = "LOG_LEVEL=debug"
|
||||
}
|
||||
|
||||
# -------------------------------------------------------------------- secrets
|
||||
|
||||
resource "random_password" "postgres" {
|
||||
length = 32
|
||||
special = false
|
||||
}
|
||||
|
||||
resource "random_password" "redis" {
|
||||
length = 32
|
||||
special = false
|
||||
}
|
||||
|
||||
# ------------------------------------------------------------------- datastores
|
||||
|
||||
resource "dokploy_postgres" "shop" {
|
||||
name = "shop-db"
|
||||
environment_id = dokploy_project.shop.default_environment_id
|
||||
|
||||
docker_image = "postgres:16-alpine"
|
||||
database_name = "shop"
|
||||
database_user = "shop"
|
||||
database_password = random_password.postgres.result
|
||||
|
||||
memory_limit = "1g"
|
||||
cpu_limit = "1"
|
||||
memory_reservation = "256m"
|
||||
}
|
||||
|
||||
resource "dokploy_redis" "sessions" {
|
||||
name = "shop-cache"
|
||||
environment_id = dokploy_project.shop.default_environment_id
|
||||
|
||||
docker_image = "redis:7-alpine"
|
||||
database_password = random_password.redis.result
|
||||
|
||||
memory_limit = "256m"
|
||||
}
|
||||
|
||||
# --------------------------------------------------------------- the web service
|
||||
|
||||
module "storefront" {
|
||||
source = "../../modules/web-service"
|
||||
|
||||
name = "storefront"
|
||||
description = "Public storefront"
|
||||
environment_id = dokploy_project.shop.default_environment_id
|
||||
|
||||
service_source = {
|
||||
type = "github"
|
||||
github_id = var.github_provider_id
|
||||
owner = "acme"
|
||||
repository = "storefront"
|
||||
branch = "main"
|
||||
}
|
||||
|
||||
build_type = "nixpacks"
|
||||
auto_deploy = true
|
||||
replicas = 2
|
||||
|
||||
# Dokploy resolves service names on the shared Docker network, so the
|
||||
# database is reachable by its generated app_name.
|
||||
env = join("\n", [
|
||||
"DATABASE_URL=postgresql://shop:${random_password.postgres.result}@${dokploy_postgres.shop.app_name}:5432/shop",
|
||||
"REDIS_URL=redis://:${random_password.redis.result}@${dokploy_redis.sessions.app_name}:6379",
|
||||
"NODE_ENV=production",
|
||||
])
|
||||
|
||||
resources = {
|
||||
memory_limit = "1g"
|
||||
cpu_limit = "1"
|
||||
}
|
||||
|
||||
domains = [
|
||||
{
|
||||
host = "shop.example.com"
|
||||
port = 3000
|
||||
},
|
||||
]
|
||||
|
||||
redirects = [
|
||||
{
|
||||
regex = "^https://www\\.shop\\.example\\.com/(.*)"
|
||||
replacement = "https://shop.example.com/$${1}"
|
||||
permanent = true
|
||||
},
|
||||
]
|
||||
|
||||
mounts = [
|
||||
{
|
||||
mount_path = "/app/uploads"
|
||||
type = "volume"
|
||||
volume_name = "storefront-uploads"
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
# -------------------------------------------- an internal tool behind basic auth
|
||||
|
||||
module "admin" {
|
||||
source = "../../modules/web-service"
|
||||
|
||||
name = "admin"
|
||||
environment_id = dokploy_environment.staging.id
|
||||
|
||||
service_source = {
|
||||
type = "docker"
|
||||
image = "traefik/whoami:latest"
|
||||
}
|
||||
|
||||
domains = [
|
||||
{
|
||||
host = "admin.staging.example.com"
|
||||
port = 80
|
||||
},
|
||||
]
|
||||
|
||||
basic_auth = {
|
||||
username = "ops"
|
||||
password = var.admin_password
|
||||
}
|
||||
}
|
||||
|
||||
# --------------------------------------------------------------- a compose stack
|
||||
|
||||
resource "dokploy_compose" "observability" {
|
||||
name = "observability"
|
||||
environment_id = dokploy_project.shop.default_environment_id
|
||||
compose_type = "docker-compose"
|
||||
source_type = "raw"
|
||||
|
||||
# Preserve volumes if this stack is ever destroyed.
|
||||
delete_volumes = false
|
||||
|
||||
compose_file = <<-YAML
|
||||
services:
|
||||
uptime:
|
||||
image: louislam/uptime-kuma:1
|
||||
volumes:
|
||||
- uptime-data:/app/data
|
||||
restart: unless-stopped
|
||||
|
||||
volumes:
|
||||
uptime-data:
|
||||
YAML
|
||||
}
|
||||
|
||||
resource "dokploy_domain" "observability" {
|
||||
compose_id = dokploy_compose.observability.id
|
||||
domain_type = "compose"
|
||||
service_name = "uptime"
|
||||
host = "status.example.com"
|
||||
port = 3001
|
||||
https = true
|
||||
certificate_type = "letsencrypt"
|
||||
}
|
||||
19
examples/complete/outputs.tf
Normal file
19
examples/complete/outputs.tf
Normal file
@@ -0,0 +1,19 @@
|
||||
output "project_id" {
|
||||
description = "Identifier of the shop project."
|
||||
value = dokploy_project.shop.id
|
||||
}
|
||||
|
||||
output "production_environment_id" {
|
||||
description = "Default production environment created alongside the project."
|
||||
value = dokploy_project.shop.default_environment_id
|
||||
}
|
||||
|
||||
output "storefront_urls" {
|
||||
description = "Public URLs the storefront answers on."
|
||||
value = module.storefront.urls
|
||||
}
|
||||
|
||||
output "postgres_host" {
|
||||
description = "In-cluster hostname of the database, for other services to connect to."
|
||||
value = dokploy_postgres.shop.app_name
|
||||
}
|
||||
14
examples/complete/variables.tf
Normal file
14
examples/complete/variables.tf
Normal file
@@ -0,0 +1,14 @@
|
||||
variable "github_provider_id" {
|
||||
description = <<-DESC
|
||||
ID of the GitHub connection configured in Dokploy under
|
||||
Settings -> Git Providers. Find it with:
|
||||
curl -H "x-api-key: $DOKPLOY_API_KEY" "$DOKPLOY_HOST/api/github.githubProviders"
|
||||
DESC
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "admin_password" {
|
||||
description = "Basic auth password for the staging admin tool."
|
||||
type = string
|
||||
sensitive = true
|
||||
}
|
||||
Reference in New Issue
Block a user