diff --git a/modules/20-services-apps/calibre/README.md b/modules/20-services-apps/calibre/README.md new file mode 100644 index 0000000..e218986 --- /dev/null +++ b/modules/20-services-apps/calibre/README.md @@ -0,0 +1,102 @@ +# Calibre Module + +This module deploys [Calibre Web Automated](https://hub.docker.com/r/crocodilestick/calibre-web-automated), a web app for browsing, reading, and managing eBooks, as a Docker container in the homelab environment. + +## Overview + +The Calibre module: + +- Deploys a Docker container: + - `calibre-web-automated`: The main Calibre Web application with automation features +- Creates a dedicated Docker network (`calibre-network`) for container communication +- Persists data to volumes on the host +- Provides service definition for integration with networking modules + +## Usage + +```hcl +module "calibre" { + source = "./modules/20-services-apps/calibre" + volume_path = "/path/to/volumes" + networks = ["homelab-network"] + user_id = "1000" + group_id = "1000" + timezone = "UTC" +} +``` + +## Variables + +| Variable | Description | Type | Default | +| ------------- | --------------------------------------------------------------- | -------------- | ---------- | +| `image_tag` | Tag of the Calibre Web image to use | `string` | `"latest"` | +| `volume_path` | Host path for Calibre data volumes | `string` | - | +| `networks` | List of additional networks to which Calibre should be attached | `list(string)` | `[]` | +| `user_id` | User ID for container permissions | `string` | `"1000"` | +| `group_id` | Group ID for container permissions | `string` | `"1000"` | +| `timezone` | Timezone for the container | `string` | `"UTC"` | + +## 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 = "calibre-web-automated" + primary_port = 8083 + endpoint = "http://calibre-web-automated:8083" + subdomains = ["calibre"] + publish_via = "reverse_proxy" + proxied = false +} +``` + +## Docker Mods + +This module includes the Calibre Docker mod to add Calibre functionality to the container: +- `lscr.io/linuxserver/mods:universal-calibre-v7.16.0` + +## Data Persistence + +Calibre stores its data in three main volumes: + +1. Configuration data: `/config` in the container, mapped to `${volume_path}/config` on the host +2. Book ingest directory: `/cwa-book-ingest` in the container, mapped to `${volume_path}/ingest` on the host +3. Calibre library: `/calibre-library` in the container, mapped to `${volume_path}/library` on the host + +## Networking + +The Calibre container is attached to any additional networks specified in the `networks` variable, allowing it to communicate with other services in the homelab. + +## Integration with Networking Modules + +This service is configured to be exposed through the Caddy reverse proxy, set by `publish_via = "reverse_proxy"`. + +## Example Integration in Main Configuration + +```hcl +module "calibre" { + source = "./modules/20-services-apps/calibre" + volume_path = module.system_globals.volume_host + networks = [module.services.homelab_docker_network_name] + user_id = module.system_globals.user_id + group_id = module.system_globals.group_id + timezone = module.system_globals.timezone +} + +# The service definition is automatically included in the services output +module "services" { + source = "./modules/services" + # ... + service_definitions = [ + module.calibre.service_definition, + # Other service definitions + ] +} +``` diff --git a/modules/20-services-apps/calibre/main.tf b/modules/20-services-apps/calibre/main.tf new file mode 100644 index 0000000..5dfb224 --- /dev/null +++ b/modules/20-services-apps/calibre/main.tf @@ -0,0 +1,104 @@ +terraform { + required_providers { + dotenv = { + source = "germanbrew/dotenv" + } + } +} + +variable "image_tag" { + description = "The tag for the Calibre Web 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 = [] +} + +variable "user_id" { + description = "User ID for container permissions" + type = string + default = "1000" +} + +variable "group_id" { + description = "Group ID for container permissions" + type = string + default = "1000" +} + +variable "timezone" { + description = "Timezone for the container" + type = string + default = "UTC" +} + +locals { + container_name = "calibre-web-automated" + calibre_image = "crocodilestick/calibre-web-automated" + calibre_tag = var.image_tag + monitoring = true + env_file = "${path.module}/.env" + calibre_internal_port = 8083 + docker_mods = "lscr.io/linuxserver/mods:universal-calibre-v7.16.0" + + # Define volumes + calibre_volumes = [ + { + host_path = "${var.volume_path}/config" + container_path = "/config" + read_only = false + }, + { + host_path = "${var.volume_path}/ingest" + container_path = "/cwa-book-ingest" + read_only = false + }, + { + host_path = "${var.volume_path}/library" + container_path = "/calibre-library" + read_only = false + } + ] + + # Environment variables for Calibre Web + calibre_env_vars = { + PUID = var.user_id + PGID = var.group_id + TZ = var.timezone + DOCKER_MODS = local.docker_mods + } +} + +# Create the Calibre Web container +module "calibre" { + source = "../../10-services-generic/docker-service" + container_name = local.container_name + image = local.calibre_image + tag = local.calibre_tag + volumes = local.calibre_volumes + env_vars = local.calibre_env_vars + networks = concat(var.networks) + monitoring = local.monitoring + restart_policy = "always" +} + +output "service_definition" { + description = "General service definition with optional ingress configuration" + value = { + name = local.container_name + primary_port = local.calibre_internal_port + endpoint = "http://${local.container_name}:${local.calibre_internal_port}" + subdomains = ["calibre"] + publish_via = "reverse_proxy" + proxied = false + } +} diff --git a/services/main.tf b/services/main.tf index 64b2399..b29c729 100644 --- a/services/main.tf +++ b/services/main.tf @@ -30,6 +30,12 @@ module "affine" { networks = [module.homelab_docker_network.name] } +module "calibre" { + source = "${local.module_dir}/20-services-apps/calibre" + volume_path = "${local.volume_host}/calibre" + networks = [module.homelab_docker_network.name] +} + module "emulatorjs" { source = "${local.module_dir}/20-services-apps/emulatorjs" volume_path = "${local.volume_host}/emulatorjs" diff --git a/services/outputs.tf b/services/outputs.tf index b24e26a..20b3f6e 100644 --- a/services/outputs.tf +++ b/services/outputs.tf @@ -6,6 +6,7 @@ output "service_definitions" { value = [ module.actualbudget.service_definition, module.affine.service_definition, + module.calibre.service_definition, module.emulatorjs.service_definition, module.linkwarden.service_definition, module.ntfy.service_definition,