Cover what Dokploy v0.30 added
Six new resources, all backed by endpoints that did not exist before v0.30.0
and verified end-to-end against a live v0.30.2 instance:
dokploy_network Docker networks, now first-class. Services attach
through network_ids, which is what deprecates
Compose's isolated_deployment upstream.
dokploy_dns_provider Cloudflare or Route53, so adding a domain creates
its DNS record.
dokploy_vault_provider Env values resolved from HashiCorp Vault, Infisical,
AWS, Doppler, Azure or Scaleway at deploy time, so
the secret never lands in Dokploy or in state.
dokploy_schedule Cron jobs in a container, a stack, or on a server.
dokploy_volume_backup Scheduled backups of a named volume — the companion
to a mount that persists.
dokploy_libsql The sixth managed database engine.
libsql.create is the strictest endpoint in the API: eleven keys required to
be present, several only meaningfully null, no generated service name, and it
returns `true` rather than the row. CreateDefaults and ListIDs absorb all
three so the resource behaves like every other database.
Also filled the gaps a field-by-field diff against the live schema turned up:
domain gains `enabled` (the v0.30.0 park-a-domain toggle), compose gains
create_env_file, icon and service_networks, application gains icon and
preview_require_collaborator_permissions, and mounts accept libsql.
DNS and vault credentials are masked by Dokploy on read, so `config` is
tagged noread and keeps the configured value, as the basic-auth password
already does.
This commit is contained in:
@@ -0,0 +1,153 @@
|
||||
# Features introduced in Dokploy v0.30.0: Docker networks, vault-backed
|
||||
# environment variables, scheduled jobs, and a volume that actually persists.
|
||||
|
||||
terraform {
|
||||
required_providers {
|
||||
dokploy = {
|
||||
source = "maxvojtkov/dokploy"
|
||||
version = "~> 0.2.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
provider "dokploy" {
|
||||
# host and api_key come from DOKPLOY_HOST and DOKPLOY_API_KEY
|
||||
}
|
||||
|
||||
variable "vault_token" {
|
||||
type = string
|
||||
sensitive = true
|
||||
}
|
||||
|
||||
resource "dokploy_project" "shop" {
|
||||
name = "shop"
|
||||
description = "Storefront and its backing services"
|
||||
}
|
||||
|
||||
# --------------------------------------------------------------- Networking
|
||||
|
||||
# A private overlay network. Only the services attached to it can reach each
|
||||
# other over it — the database never becomes reachable from unrelated
|
||||
# services that merely share the default dokploy-network.
|
||||
resource "dokploy_network" "backend" {
|
||||
name = "shop-backend"
|
||||
driver = "overlay"
|
||||
attachable = true
|
||||
internal = false
|
||||
}
|
||||
|
||||
# ------------------------------------------------------------------ Secrets
|
||||
|
||||
# Environment values are resolved from Vault when the deployment runs, so
|
||||
# rotating a secret takes effect on the next deploy with no Terraform change
|
||||
# and no secret in Terraform state.
|
||||
resource "dokploy_vault_provider" "prod" {
|
||||
name = "production-vault"
|
||||
|
||||
config = jsonencode({
|
||||
providerType = "hashicorp"
|
||||
url = "https://vault.example.com"
|
||||
token = var.vault_token
|
||||
mount = "secret"
|
||||
})
|
||||
|
||||
assignments = jsonencode([])
|
||||
}
|
||||
|
||||
# ---------------------------------------------------------------- Services
|
||||
|
||||
resource "dokploy_postgres" "db" {
|
||||
name = "shop-db"
|
||||
environment_id = dokploy_project.shop.default_environment_id
|
||||
docker_image = "postgres:16-alpine"
|
||||
database_name = "shop"
|
||||
database_user = "shop"
|
||||
database_password = "set-me-from-a-variable"
|
||||
|
||||
network_ids = [dokploy_network.backend.id]
|
||||
}
|
||||
|
||||
resource "dokploy_application" "api" {
|
||||
name = "api"
|
||||
environment_id = dokploy_project.shop.default_environment_id
|
||||
source_type = "docker"
|
||||
docker_image = "ghcr.io/acme/api:1.4.0"
|
||||
|
||||
network_ids = [dokploy_network.backend.id]
|
||||
|
||||
# Resolved from the vault provider above at deploy time.
|
||||
env = <<-EOT
|
||||
DATABASE_URL=postgresql://shop:$${{vault.production.db_password}}@${dokploy_postgres.db.app_name}:5432/shop
|
||||
STRIPE_KEY=$${{vault.production.stripe_key}}
|
||||
EOT
|
||||
}
|
||||
|
||||
# -------------------------------------------------------- Persistent volume
|
||||
|
||||
# volume_name is what makes this persist. Without it Dokploy hands Docker an
|
||||
# empty source and every deploy gets a fresh anonymous volume — the provider
|
||||
# rejects that at plan time.
|
||||
resource "dokploy_mount" "uploads" {
|
||||
type = "volume"
|
||||
volume_name = "shop-uploads"
|
||||
mount_path = "/app/uploads"
|
||||
service_type = "application"
|
||||
service_id = dokploy_application.api.id
|
||||
}
|
||||
|
||||
resource "dokploy_destination" "backups" {
|
||||
name = "s3-backups"
|
||||
provider_name = "s3"
|
||||
access_key = "set-me"
|
||||
secret_access_key = "set-me"
|
||||
bucket = "shop-backups"
|
||||
region = "eu-central-1"
|
||||
endpoint = "https://s3.eu-central-1.amazonaws.com"
|
||||
}
|
||||
|
||||
# The named volume is only durable if it also leaves the host.
|
||||
resource "dokploy_volume_backup" "uploads" {
|
||||
name = "uploads-nightly"
|
||||
volume_name = dokploy_mount.uploads.volume_name
|
||||
prefix = "shop/uploads/"
|
||||
cron_expression = "0 4 * * *"
|
||||
destination_id = dokploy_destination.backups.id
|
||||
|
||||
service_type = "application"
|
||||
application_id = dokploy_application.api.id
|
||||
|
||||
keep_latest_count = 14
|
||||
}
|
||||
|
||||
# ---------------------------------------------------------------- Schedules
|
||||
|
||||
resource "dokploy_schedule" "prune_sessions" {
|
||||
name = "prune-sessions"
|
||||
description = "Drop expired sessions every night"
|
||||
schedule_type = "application"
|
||||
application_id = dokploy_application.api.id
|
||||
cron_expression = "0 2 * * *"
|
||||
command = "node scripts/prune-sessions.js"
|
||||
timezone = "Europe/Berlin"
|
||||
}
|
||||
|
||||
# --------------------------------------------------------------------- DNS
|
||||
|
||||
resource "dokploy_dns_provider" "cloudflare" {
|
||||
name = "cloudflare"
|
||||
config = jsonencode({
|
||||
providerType = "cloudflare"
|
||||
apiToken = "set-me-from-a-variable"
|
||||
})
|
||||
}
|
||||
|
||||
resource "dokploy_domain" "api" {
|
||||
application_id = dokploy_application.api.id
|
||||
host = "api.example.com"
|
||||
port = 3000
|
||||
https = true
|
||||
certificate_type = "letsencrypt"
|
||||
|
||||
# A domain can be parked without losing its configuration.
|
||||
enabled = true
|
||||
}
|
||||
Reference in New Issue
Block a user