Files
terraform-provider-dokploy/examples/complete/main.tf
Max Vojtkov a6d8aa8b52 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.
2026-08-09 12:17:26 +03:00

201 lines
4.7 KiB
HCL

# 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"
}