feat: add pterodactyl

This commit is contained in:
Yuris Cakranegara
2025-06-08 14:40:56 +10:00
parent 8872662212
commit b912065015
5 changed files with 312 additions and 3 deletions

View File

@@ -0,0 +1,18 @@
# Pterodactyl Panel Environment Settings
# Database Configuration
MYSQL_PASSWORD=secure_database_password_here
MYSQL_ROOT_PASSWORD=secure_root_password_here
MYSQL_DATABASE=pterodactyl
MYSQL_USER=pterodactyl
# Panel Configuration
APP_URL=https://panel.yourdomain.com
APP_TIMEZONE=Australia/Brisbane
APP_SERVICE_AUTHOR=email@example.com
APP_CORS_ALLOWED_ORIGINS=https://panel.yourdomain.com
TRUSTED_PROXIES="*" # Set this to your proxy IP
# Optional: Let's Encrypt Settings
# Uncomment and set to your email to use Let's Encrypt
# LE_EMAIL=admin@yourdomain.com

View File

@@ -0,0 +1,163 @@
terraform {
required_providers {
dotenv = {
source = "germanbrew/dotenv"
}
}
}
module "smtp" {
source = "../../../00-globals/smtp"
}
variable "image_tag" {
description = "The tag for the Pterodactyl Panel container image"
type = string
default = "latest"
}
variable "volume_path" {
description = "Base directory for volumes"
type = string
}
variable "networks" {
description = "List of networks to which the container should be attached"
type = list(string)
default = []
}
locals {
container_name = "pterodactyl-panel"
database_name = "pterodactyl-db"
cache_name = "pterodactyl-cache"
panel_image = "ghcr.io/pterodactyl/panel"
database_image = "mariadb"
cache_image = "redis"
panel_tag = var.image_tag != "" ? var.image_tag : "latest"
database_tag = "10.5"
cache_tag = "alpine"
monitoring = true
env_file = "${path.module}/.env"
# Volume paths
panel_volumes = [
{
host_path = "${var.volume_path}/var"
container_path = "/app/var"
read_only = false
},
{
host_path = "${var.volume_path}/nginx"
container_path = "/etc/nginx/http.d"
read_only = false
},
{
host_path = "${var.volume_path}/certs"
container_path = "/etc/letsencrypt"
read_only = false
},
{
host_path = "${var.volume_path}/logs"
container_path = "/app/storage/logs"
read_only = false
}
]
database_volumes = [
{
host_path = "${var.volume_path}/database"
container_path = "/var/lib/mysql"
read_only = false
}
]
# Environment variables
panel_env_vars = {
APP_URL = provider::dotenv::get_by_key("APP_URL", local.env_file)
APP_TIMEZONE = provider::dotenv::get_by_key("APP_TIMEZONE", local.env_file)
APP_SERVICE_AUTHOR = provider::dotenv::get_by_key("APP_SERVICE_AUTHOR", local.env_file)
APP_CORS_ALLOWED_ORIGINS = provider::dotenv::get_by_key("APP_CORS_ALLOWED_ORIGINS", local.env_file)
TRUSTED_PROXIES = provider::dotenv::get_by_key("TRUSTED_PROXIES", local.env_file)
MAIL_FROM = module.smtp.mail_from
MAIL_DRIVER = "smtp"
MAIL_HOST = module.smtp.mail_host
MAIL_PORT = module.smtp.mail_port
MAIL_USERNAME = module.smtp.mail_username
MAIL_PASSWORD = module.smtp.mail_password
MAIL_ENCRYPTION = "false"
DB_PASSWORD = provider::dotenv::get_by_key("MYSQL_PASSWORD", local.env_file)
APP_ENV = "production"
APP_ENVIRONMENT_ONLY = "false"
CACHE_DRIVER = "redis"
SESSION_DRIVER = "redis"
QUEUE_DRIVER = "redis"
REDIS_HOST = local.cache_name
DB_HOST = local.database_name
DB_PORT = "3306"
DB_DATABASE = provider::dotenv::get_by_key("MYSQL_DATABASE", local.env_file)
DB_USERNAME = provider::dotenv::get_by_key("MYSQL_USER", local.env_file)
}
database_env_vars = {
MYSQL_PASSWORD = provider::dotenv::get_by_key("MYSQL_PASSWORD", local.env_file)
MYSQL_ROOT_PASSWORD = provider::dotenv::get_by_key("MYSQL_ROOT_PASSWORD", local.env_file)
MYSQL_DATABASE = provider::dotenv::get_by_key("MYSQL_DATABASE", local.env_file)
MYSQL_USER = provider::dotenv::get_by_key("MYSQL_USER", local.env_file)
}
}
# Create a dedicated network for Pterodactyl
module "pterodactyl_network" {
source = "../../../01-networking/docker-network"
name = "ptero-panel"
driver = "bridge"
subnet = "172.20.0.0/16"
attachable = true
}
# Database container
module "database" {
source = "../../../10-services-generic/docker-service"
container_name = local.database_name
image = local.database_image
tag = local.database_tag
volumes = local.database_volumes
env_vars = local.database_env_vars
networks = concat([module.pterodactyl_network.name], var.networks)
command = ["--default-authentication-plugin=mysql_native_password"]
monitoring = local.monitoring
}
# Cache container
module "cache" {
source = "../../../10-services-generic/docker-service"
container_name = local.cache_name
image = local.cache_image
tag = local.cache_tag
networks = concat([module.pterodactyl_network.name], var.networks)
monitoring = local.monitoring
}
# Panel container
module "panel" {
source = "../../../10-services-generic/docker-service"
container_name = local.container_name
image = local.panel_image
tag = local.panel_tag
volumes = local.panel_volumes
env_vars = local.panel_env_vars
networks = concat([module.pterodactyl_network.name], var.networks)
monitoring = local.monitoring
depends_on = [module.database, module.cache]
}
output "service_definition" {
description = "General service definition with optional ingress configuration"
value = {
name = local.container_name
primary_port = 80
endpoint = "http://${local.container_name}:80"
subdomains = ["gameservers"]
}
}

View File

@@ -0,0 +1,115 @@
terraform {
required_providers {
dotenv = {
source = "germanbrew/dotenv"
}
}
}
variable "image_tag" {
description = "The tag for the Pterodactyl Wings container image"
type = string
default = "v1.11.3"
}
variable "volume_path" {
description = "Base directory for volumes"
type = string
}
variable "networks" {
description = "List of networks to which the container should be attached"
type = list(string)
default = []
}
locals {
container_name = "pterodactyl-wings"
image = "ghcr.io/pterodactyl/wings"
image_tag = var.image_tag != "" ? var.image_tag : "v1.11.3"
monitoring = false
env_file = "${path.module}/.env"
subdomains = ["wings"]
# Volumes configuration
volumes = [
{
host_path = "/var/run/docker.sock"
container_path = "/var/run/docker.sock"
read_only = false
},
{
host_path = "/var/lib/docker/containers/"
container_path = "/var/lib/docker/containers/"
read_only = false
},
{
host_path = "/etc/ssl/certs"
container_path = "/etc/ssl/certs"
read_only = true
},
{
host_path = "${var.volume_path}/etc"
container_path = "/etc/pterodactyl/"
read_only = false
},
{
host_path = "${var.volume_path}/var/lib"
container_path = "/var/lib/pterodactyl/"
read_only = false
},
{
host_path = "${var.volume_path}/var/log"
container_path = "/var/log/pterodactyl/"
read_only = false
},
{
host_path = "${var.volume_path}/tmp"
container_path = "/tmp/pterodactyl/"
read_only = false
},
]
# Environment variables
env_vars = {
TZ = "Australia/Brisbane"
WINGS_UID = 988
WINGS_GID = 988
WINGS_USERNAME = "pterodactyl"
}
}
# Create a custom Docker network for wings
module "wings_network" {
source = "../../../01-networking/docker-network"
name = "ptero-wings"
driver = "bridge"
attachable = true
subnet = "172.32.0.0/16"
options = {
"com.docker.network.bridge.name" = "ptero-wings"
}
}
module "wings" {
source = "../../../10-services-generic/docker-service"
container_name = local.container_name
image = local.image
tag = local.image_tag
volumes = local.volumes
env_vars = local.env_vars
networks = concat([module.wings_network.name], var.networks)
monitoring = local.monitoring
privileged = true
}
output "service_definition" {
description = "General service definition with optional ingress configuration"
value = {
name = local.container_name
primary_port = 443
endpoint = "http://${local.container_name}:443"
subdomains = local.subdomains
}
}

View File

@@ -1,5 +1,5 @@
locals { locals {
module_dir = "../modules" module_dir = "../modules"
volume_host = module.system_globals.volume_host volume_host = module.system_globals.volume_host
} }
@@ -40,4 +40,15 @@ module "ntfy" {
volume_path = "${local.volume_host}/ntfy" volume_path = "${local.volume_host}/ntfy"
networks = [module.homelab_docker_network.name] networks = [module.homelab_docker_network.name]
} }
module "pterodactyl_panel" {
source = "${local.module_dir}/20-services-apps/pterodactyl/panel"
volume_path = "${local.volume_host}/pterodactyl/panel"
networks = [module.homelab_docker_network.name]
}
module "pterodactyl_wings" {
source = "${local.module_dir}/20-services-apps/pterodactyl/wings"
volume_path = "${local.volume_host}/pterodactyl/wings"
networks = [module.homelab_docker_network.name]
}

View File

@@ -7,7 +7,9 @@ output "service_definitions" {
module.actualbudget.service_definition, module.actualbudget.service_definition,
module.emulatorjs.service_definition, module.emulatorjs.service_definition,
module.linkwarden.service_definition, module.linkwarden.service_definition,
module.ntfy.service_definition module.ntfy.service_definition,
module.pterodactyl_wings.service_definition,
module.pterodactyl_panel.service_definition
] ]
} }