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
|
||||
}
|
||||
}
|
||||
@@ -41,3 +41,14 @@ module "ntfy" {
|
||||
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.emulatorjs.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