feat: add pterodactyl
This commit is contained in:
18
modules/20-services-apps/pterodactyl/panel/.env.example
Normal file
18
modules/20-services-apps/pterodactyl/panel/.env.example
Normal 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
|
||||||
163
modules/20-services-apps/pterodactyl/panel/main.tf
Normal file
163
modules/20-services-apps/pterodactyl/panel/main.tf
Normal 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"]
|
||||||
|
}
|
||||||
|
}
|
||||||
115
modules/20-services-apps/pterodactyl/wings/main.tf
Normal file
115
modules/20-services-apps/pterodactyl/wings/main.tf
Normal 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
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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]
|
||||||
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user