diff --git a/modules/20-services-apps/portainer/README.md b/modules/20-services-apps/portainer/README.md new file mode 100644 index 0000000..881b118 --- /dev/null +++ b/modules/20-services-apps/portainer/README.md @@ -0,0 +1,78 @@ +# Portainer Module + +This module deploys [Portainer](https://www.portainer.io/), a lightweight management UI that allows you to easily manage your different Docker environments. + +## Overview + +The Portainer module: + +- Deploys one Docker container: `portainer`. +- Mounts the Docker socket to allow Portainer to manage the Docker environment. +- Persists Portainer data to a volume on the host. +- Provides a service definition for integration with networking modules. + +## Usage + +```hcl +module "portainer" { + source = "./modules/20-services-apps/portainer" + volume_path = "/path/to/volumes/portainer" + networks = ["homelab-network"] +} +``` + +## Variables + +| Variable | Description | +| ------------- | ---------------------------------------------------------------- | +| `image_tag` | Tag of the Portainer image to use | +| `volume_path` | Host path for Portainer data volume | +| `networks` | List of additional networks to which Portainer should be attached | + +## Outputs + +| Output | Description | +| -------------------- | ---------------------------------------------------------- | +| `service_definition` | Service definition for integration with networking modules | + +## Service Definition + +This module outputs a service definition that is used by the networking modules to expose the service. + +```hcl +{ + name = "portainer" + primary_port = 9000 + endpoint = "http://portainer:9000" + subdomains = ["portainer"] + publish_via = "reverse_proxy" +} +``` + +## Data Persistence + +Portainer stores its data in a single volume: + +1. Portainer data: `/data` in the container, mapped to `${volume_path}/data` on the host. + +It also mounts the Docker socket from `/var/run/docker.sock` on the host to `/var/run/docker.sock` in the container to manage Docker. + +## Example Integration in Main Configuration + +```hcl +module "portainer" { + source = "./modules/20-services-apps/portainer" + volume_path = "${module.system_globals.volume_host}/portainer" + networks = [module.services.homelab_docker_network_name] +} + +# The service definition is automatically included in the services output +module "services" { + source = "./modules/services" + # ... + service_definitions = [ + module.portainer.service_definition, + # Other service definitions + ] +} +``` diff --git a/modules/20-services-apps/portainer/main.tf b/modules/20-services-apps/portainer/main.tf new file mode 100644 index 0000000..b1c4b70 --- /dev/null +++ b/modules/20-services-apps/portainer/main.tf @@ -0,0 +1,67 @@ + +variable "image_tag" { + description = "The tag for the portainer 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 = "portainer" + image = "portainer/portainer-ce" + tag = var.image_tag + monitoring = true + internal_port = 9000 + exposed_port = 9000 + + # Define volumes + volumes = [ + { + host_path = "/var/run/docker.sock" + container_path = "/var/run/docker.sock" + read_only = false + }, + { + host_path = "${var.volume_path}/data" + container_path = "/data" + read_only = false + } + ] +} + +# Create the portainer container +module "portainer" { + source = "../../10-services-generic/docker-service" + container_name = local.container_name + image = local.image + tag = local.tag + volumes = local.volumes + networks = var.networks + monitoring = local.monitoring + ports = [ + { + internal = local.internal_port + external = local.exposed_port + protocol = "tcp" + }, + ] +} + +output "service_definition" { + description = "General service definition with optional ingress configuration" + value = { + name = local.container_name + primary_port = local.internal_port + endpoint = "http://${local.container_name}:${local.internal_port}" + } +} diff --git a/services/main.tf b/services/main.tf old mode 100644 new mode 100755 index 4ec6c6b..110fde0 --- a/services/main.tf +++ b/services/main.tf @@ -77,6 +77,12 @@ module "ntfy" { networks = [module.homelab_docker_network.name] } +module "portainer" { + source = "${local.module_dir}/20-services-apps/portainer" + volume_path = "${local.volume_host}/portainer" + 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" diff --git a/services/outputs.tf b/services/outputs.tf old mode 100644 new mode 100755 index d03bac2..a4d6ffc --- a/services/outputs.tf +++ b/services/outputs.tf @@ -15,6 +15,7 @@ output "service_definitions" { module.n8n.n8n_mcp_service_definition, module.nocodb.service_definition, module.ntfy.service_definition, + module.portainer.service_definition, module.pterodactyl_wings.service_definition, module.pterodactyl_panel.service_definition, module.searxng.service_definition