doc: added BYO image for DigitalOcean
This commit is contained in:
@@ -10,6 +10,62 @@ This Terraform project automates the deployment of Fleet Device Management (Flee
|
||||
* **DNS** — Domain and CNAME record for Fleet
|
||||
* **Database Firewalls** — Restricts database and cache access to the App Platform app only
|
||||
|
||||
## Using Your Own Image
|
||||
|
||||
By default, the module deploys the official `fleetdm/fleet` image from Docker Hub. To deploy your own image (e.g., a custom Fleet build), set `image_tag` in `fleet_config` to a full image reference:
|
||||
|
||||
### Docker Hub (public)
|
||||
|
||||
```hcl
|
||||
fleet_config = {
|
||||
image_tag = "your-org/your-fleet:v1.0.0"
|
||||
# ...
|
||||
}
|
||||
```
|
||||
|
||||
### Docker Hub (private)
|
||||
|
||||
```hcl
|
||||
fleet_config = {
|
||||
image_tag = "your-org/your-fleet:v1.0.0"
|
||||
image_registry_credentials = "your-username:your-access-token" # Don't commit this!
|
||||
# ...
|
||||
}
|
||||
```
|
||||
|
||||
Pass the credentials at deploy time instead of committing them:
|
||||
|
||||
```bash
|
||||
terraform apply -var-file="fleet-10.tfvars" \
|
||||
-var="fleet_config={image_tag:\"your-org/your-fleet:v1.0.0\",image_registry_credentials:\"$DOCKERHUB_USER:$DOCKERHUB_TOKEN\",instance_size_slug:\"basic-xs\",instance_count:1,debug_logging:false,exec_migration:true}"
|
||||
```
|
||||
|
||||
### DigitalOcean Container Registry (DOCR)
|
||||
|
||||
Push your image to DOCR first:
|
||||
|
||||
```bash
|
||||
# One-time: create a registry and log in
|
||||
doctl registry create my-registry
|
||||
doctl registry login
|
||||
|
||||
# Build, tag, and push your image
|
||||
docker build -t registry.digitalocean.com/my-registry/fleet:v1.0.0 .
|
||||
docker push registry.digitalocean.com/my-registry/fleet:v1.0.0
|
||||
```
|
||||
|
||||
Then reference it:
|
||||
|
||||
```hcl
|
||||
fleet_config = {
|
||||
image_tag = "registry.digitalocean.com/my-registry/fleet:v1.0.0"
|
||||
image_deploy_on_push = true # Optional: redeploy automatically on every push
|
||||
# ...
|
||||
}
|
||||
```
|
||||
|
||||
The module detects the registry automatically from the `image_tag` prefix — anything starting with `registry.digitalocean.com/` uses DOCR, everything else uses Docker Hub. The migration job uses the same image.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
1. **Terraform:** Version `~> 1.11`. Install from [terraform.io](https://www.terraform.io/downloads.html).
|
||||
|
||||
@@ -4,6 +4,22 @@ resource "random_password" "private_key" {
|
||||
}
|
||||
|
||||
locals {
|
||||
# --------------------------------------------------------------------------
|
||||
# Image parsing — supports Docker Hub and DigitalOcean Container Registry
|
||||
#
|
||||
# Accepted formats for var.fleet_config.image_tag:
|
||||
# "fleetdm/fleet:v4.90.0" → Docker Hub (official)
|
||||
# "your-org/your-image:v1.0.0" → Docker Hub (custom)
|
||||
# "registry.digitalocean.com/<registry>/<repo>:tag" → DOCR
|
||||
# --------------------------------------------------------------------------
|
||||
image_tag_parts = split(":", var.fleet_config.image_tag)
|
||||
image_name_part = local.image_tag_parts[0]
|
||||
image_tag_part = length(local.image_tag_parts) > 1 ? local.image_tag_parts[length(local.image_tag_parts) - 1] : "latest"
|
||||
image_segments = split("/", local.image_name_part)
|
||||
image_is_docr = local.image_segments[0] == "registry.digitalocean.com"
|
||||
image_repository = local.image_segments[length(local.image_segments) - 1]
|
||||
image_dh_registry = join("/", slice(local.image_segments, 0, length(local.image_segments) - 1))
|
||||
|
||||
base_env_vars = {
|
||||
FLEET_MYSQL_PROTOCOL = "tcp"
|
||||
FLEET_MYSQL_ADDRESS = "${local.mysql_host}:${local.mysql_port}"
|
||||
@@ -60,10 +76,19 @@ resource "digitalocean_app" "fleet" {
|
||||
http_port = 8080
|
||||
|
||||
image {
|
||||
registry_type = "DOCKER_HUB"
|
||||
registry = "fleetdm"
|
||||
repository = "fleet"
|
||||
tag = trimprefix(var.fleet_config.image_tag, "fleetdm/fleet:")
|
||||
registry_type = local.image_is_docr ? "DOCR" : "DOCKER_HUB"
|
||||
registry = local.image_is_docr ? null : local.image_dh_registry
|
||||
repository = local.image_repository
|
||||
tag = local.image_tag_part
|
||||
registry_credentials = var.fleet_config.image_registry_credentials
|
||||
|
||||
# Auto-deploy on push is only supported for DOCR
|
||||
dynamic "deploy_on_push" {
|
||||
for_each = local.image_is_docr && var.fleet_config.image_deploy_on_push ? [1] : []
|
||||
content {
|
||||
enabled = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
health_check {
|
||||
@@ -107,10 +132,11 @@ resource "digitalocean_app" "fleet" {
|
||||
instance_size_slug = var.fleet_config.instance_size_slug
|
||||
|
||||
image {
|
||||
registry_type = "DOCKER_HUB"
|
||||
registry = "fleetdm"
|
||||
repository = "fleet"
|
||||
tag = trimprefix(var.fleet_config.image_tag, "fleetdm/fleet:")
|
||||
registry_type = local.image_is_docr ? "DOCR" : "DOCKER_HUB"
|
||||
registry = local.image_is_docr ? null : local.image_dh_registry
|
||||
repository = local.image_repository
|
||||
tag = local.image_tag_part
|
||||
registry_credentials = var.fleet_config.image_registry_credentials
|
||||
}
|
||||
|
||||
run_command = "fleet prepare db --no-prompt=true"
|
||||
|
||||
@@ -24,15 +24,17 @@ variable "vpc_config" {
|
||||
}
|
||||
|
||||
variable "fleet_config" {
|
||||
description = "Configuration for the Fleet application deployment."
|
||||
description = "Configuration for the Fleet application deployment. image_tag accepts full image references from Docker Hub or DOCR."
|
||||
type = object({
|
||||
image_tag = string
|
||||
instance_size_slug = string
|
||||
instance_count = number
|
||||
license_key = optional(string)
|
||||
debug_logging = bool
|
||||
exec_migration = bool
|
||||
extra_env_vars = optional(map(string))
|
||||
image_tag = string
|
||||
image_registry_credentials = optional(string)
|
||||
image_deploy_on_push = optional(bool, false)
|
||||
instance_size_slug = string
|
||||
instance_count = number
|
||||
license_key = optional(string)
|
||||
debug_logging = bool
|
||||
exec_migration = bool
|
||||
extra_env_vars = optional(map(string))
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -27,7 +27,13 @@
|
||||
# App Platform — smallest possible instance
|
||||
# ----------------------------------------------------------------------------
|
||||
fleet_config = {
|
||||
# Image — use the official Fleet image or your own:
|
||||
# Official: "fleetdm/fleet:v4.90.0"
|
||||
# Custom Docker Hub: "your-org/your-fleet:v1.0.0"
|
||||
# DigitalOcean DOCR: "registry.digitalocean.com/your-registry/fleet:v1.0.0"
|
||||
image_tag = "fleetdm/fleet:v4.90.0"
|
||||
# image_registry_credentials = "your-username:your-token" # private Docker Hub
|
||||
# image_deploy_on_push = true # DOCR only
|
||||
instance_size_slug = "basic-xxs" # $5/mo — 512 MiB, 1 shared vCPU
|
||||
instance_count = 1
|
||||
debug_logging = false
|
||||
|
||||
@@ -27,7 +27,18 @@
|
||||
# $10/month — plenty for 10 devices
|
||||
# ----------------------------------------------------------------------------
|
||||
fleet_config = {
|
||||
image_tag = "fleetdm/fleet:v4.90.0"
|
||||
# Image — use the official Fleet image or your own:
|
||||
# Official: "fleetdm/fleet:v4.90.0"
|
||||
# Custom Docker Hub: "your-org/your-fleet:v1.0.0"
|
||||
# DigitalOcean DOCR: "registry.digitalocean.com/your-registry/fleet:v1.0.0"
|
||||
image_tag = "fleetdm/fleet:v4.90.0"
|
||||
|
||||
# For private Docker Hub repos:
|
||||
# image_registry_credentials = "your-username:your-token"
|
||||
|
||||
# For DOCR: auto-deploy when you push a new image
|
||||
# image_deploy_on_push = true
|
||||
|
||||
instance_size_slug = "basic-xs" # 1 GiB RAM, $10/mo
|
||||
instance_count = 1
|
||||
debug_logging = false
|
||||
|
||||
@@ -20,7 +20,13 @@
|
||||
# App Platform — same as default, but without Redis env vars
|
||||
# ----------------------------------------------------------------------------
|
||||
fleet_config = {
|
||||
# Image — use the official Fleet image or your own:
|
||||
# Official: "fleetdm/fleet:v4.90.0"
|
||||
# Custom Docker Hub: "your-org/your-fleet:v1.0.0"
|
||||
# DigitalOcean DOCR: "registry.digitalocean.com/your-registry/fleet:v1.0.0"
|
||||
image_tag = "fleetdm/fleet:v4.90.0"
|
||||
# image_registry_credentials = "your-username:your-token" # private Docker Hub
|
||||
# image_deploy_on_push = true # DOCR only
|
||||
instance_size_slug = "apps-s-1vcpu-1gb" # $12/mo
|
||||
instance_count = 1
|
||||
debug_logging = false
|
||||
|
||||
@@ -28,15 +28,27 @@ variable "vpc_config" {
|
||||
}
|
||||
|
||||
variable "fleet_config" {
|
||||
description = "Configuration for the Fleet application deployment on App Platform."
|
||||
description = <<-EOT
|
||||
Configuration for the Fleet application deployment on App Platform.
|
||||
|
||||
image_tag accepts a full image reference:
|
||||
- Docker Hub: "fleetdm/fleet:v4.90.0" (default, official image)
|
||||
- Docker Hub custom: "your-org/your-image:v1.0.0"
|
||||
- DOCR: "registry.digitalocean.com/your-registry/your-image:v1.0.0"
|
||||
|
||||
image_registry_credentials: "username:token" for private Docker Hub repos.
|
||||
image_deploy_on_push: auto-deploy when a new image is pushed (DOCR only).
|
||||
EOT
|
||||
type = object({
|
||||
image_tag = string
|
||||
instance_size_slug = string
|
||||
instance_count = number
|
||||
license_key = optional(string)
|
||||
debug_logging = bool
|
||||
exec_migration = bool
|
||||
extra_env_vars = optional(map(string))
|
||||
image_tag = string
|
||||
image_registry_credentials = optional(string)
|
||||
image_deploy_on_push = optional(bool, false)
|
||||
instance_size_slug = string
|
||||
instance_count = number
|
||||
license_key = optional(string)
|
||||
debug_logging = bool
|
||||
exec_migration = bool
|
||||
extra_env_vars = optional(map(string))
|
||||
})
|
||||
default = {
|
||||
image_tag = "fleetdm/fleet:v4.90.0"
|
||||
|
||||
Reference in New Issue
Block a user