Files
code-tools/tf/services.tf

343 lines
8.7 KiB
HCL

# =============================================================================
# Service Containers - Database and Development Services
# PostgreSQL, Redis, Qdrant, Docker Registry
# =============================================================================
# =============================================================================
# PostgreSQL Database Service
# =============================================================================
# PostgreSQL data volume for persistence
resource "docker_volume" "postgres_data" {
count = data.coder_parameter.enable_services.value ? 1 : 0
name = "postgres-data-${local.workspace_id}"
labels {
label = "coder.service"
value = "postgres"
}
labels {
label = "coder.workspace_id"
value = local.workspace_id
}
}
# PostgreSQL container
resource "docker_container" "postgres" {
count = data.coder_parameter.enable_services.value ? 1 : 0
image = "postgres:${var.postgres_version}-alpine"
name = "postgres-${local.workspace_id}"
# Resource limits for better isolation
memory = 2048 * 1024 * 1024 # 2GB
cpu_shares = 512 # Medium priority
# PostgreSQL configuration
env = [
"POSTGRES_DB=postgres",
"POSTGRES_USER=postgres",
"POSTGRES_PASSWORD=${var.postgres_password}",
"POSTGRES_INITDB_ARGS=--auth-local=trust --auth-host=md5",
"POSTGRES_SHARED_PRELOAD_LIBRARIES=pg_stat_statements",
"POSTGRES_MAX_CONNECTIONS=${var.postgres_max_connections}"
]
# Network configuration - internal only, accessible via Coder port forwarding
networks_advanced {
name = docker_network.workspace.name
}
# Data persistence
volumes {
volume_name = docker_volume.postgres_data[0].name
container_path = "/var/lib/postgresql/data"
}
# Health check with proper timing for database startup
healthcheck {
test = ["CMD-SHELL", "pg_isready -U postgres"]
interval = "15s"
timeout = "5s"
retries = 5
start_period = "30s" # Give PostgreSQL time to initialize
}
restart = "unless-stopped"
labels {
label = "coder.service"
value = "postgres"
}
labels {
label = "coder.workspace_id"
value = local.workspace_id
}
}
# =============================================================================
# Redis Cache Service
# =============================================================================
# Redis data volume for persistence
resource "docker_volume" "redis_data" {
count = data.coder_parameter.enable_services.value ? 1 : 0
name = "redis-data-${local.workspace_id}"
labels {
label = "coder.service"
value = "redis"
}
labels {
label = "coder.workspace_id"
value = local.workspace_id
}
}
# Redis container
resource "docker_container" "redis" {
count = data.coder_parameter.enable_services.value ? 1 : 0
image = "redis:${var.redis_version}-alpine"
name = "redis-${local.workspace_id}"
# Resource limits for better isolation
memory = 1024 * 1024 * 1024 # 1GB
cpu_shares = 256 # Lower priority
# Redis configuration with authentication
command = [
"redis-server",
"--requirepass", var.redis_password,
"--appendonly", "yes",
"--appendfsync", "everysec",
"--maxmemory", var.redis_max_memory,
"--maxmemory-policy", "allkeys-lru"
]
networks_advanced {
name = docker_network.workspace.name
}
# Data persistence
volumes {
volume_name = docker_volume.redis_data[0].name
container_path = "/data"
}
# Health check with authentication and proper timing
healthcheck {
test = ["CMD", "redis-cli", "-a", var.redis_password, "ping"]
interval = "15s"
timeout = "3s"
retries = 5
start_period = "10s" # Redis starts quickly
}
restart = "unless-stopped"
labels {
label = "coder.service"
value = "redis"
}
labels {
label = "coder.workspace_id"
value = local.workspace_id
}
}
# =============================================================================
# Qdrant Vector Database Service
# =============================================================================
# Qdrant data volume for persistence
resource "docker_volume" "qdrant_data" {
count = data.coder_parameter.enable_services.value ? 1 : 0
name = "qdrant-data-${local.workspace_id}"
labels {
label = "coder.service"
value = "qdrant"
}
labels {
label = "coder.workspace_id"
value = local.workspace_id
}
}
# Qdrant container
resource "docker_container" "qdrant" {
count = data.coder_parameter.enable_services.value ? 1 : 0
image = "qdrant/qdrant:${var.qdrant_version}"
name = "qdrant-${local.workspace_id}"
# Resource limits for better isolation
memory = 2048 * 1024 * 1024 # 2GB for vector operations
cpu_shares = 512 # Medium priority
# Qdrant configuration
env = [
"QDRANT__SERVICE__HTTP_PORT=6333",
"QDRANT__SERVICE__GRPC_PORT=6334",
"QDRANT__SERVICE__HOST=0.0.0.0",
"QDRANT__LOG_LEVEL=INFO"
]
networks_advanced {
name = docker_network.workspace.name
}
# Data persistence
volumes {
volume_name = docker_volume.qdrant_data[0].name
container_path = "/qdrant/storage"
}
# Health check using Qdrant's HTTP endpoint with proper timing
healthcheck {
test = ["CMD-SHELL", "wget --no-verbose --tries=1 --spider http://localhost:6333/health || exit 1"]
interval = "20s"
timeout = "5s"
retries = 5
start_period = "40s" # Qdrant needs time to initialize storage
}
restart = "unless-stopped"
labels {
label = "coder.service"
value = "qdrant"
}
labels {
label = "coder.workspace_id"
value = local.workspace_id
}
}
# =============================================================================
# pgAdmin for PostgreSQL Management (Optional)
# =============================================================================
# pgAdmin data volume
resource "docker_volume" "pgadmin_data" {
count = data.coder_parameter.enable_services.value && data.coder_parameter.enable_pgadmin.value ? 1 : 0
name = "pgadmin-data-${local.workspace_id}"
labels {
label = "coder.service"
value = "pgadmin"
}
labels {
label = "coder.workspace_id"
value = local.workspace_id
}
}
# pgAdmin container
resource "docker_container" "pgadmin" {
count = data.coder_parameter.enable_services.value && data.coder_parameter.enable_pgadmin.value ? 1 : 0
image = "dpage/pgadmin4:latest"
name = "pgadmin-${local.workspace_id}"
# pgAdmin configuration
env = [
"PGADMIN_DEFAULT_EMAIL=${var.pgadmin_email}",
"PGADMIN_DEFAULT_PASSWORD=${var.pgadmin_password}",
"PGADMIN_CONFIG_SERVER_MODE=False",
"PGADMIN_CONFIG_MASTER_PASSWORD_REQUIRED=False",
"PGADMIN_LISTEN_PORT=80"
]
networks_advanced {
name = docker_network.workspace.name
}
# Data persistence
volumes {
volume_name = docker_volume.pgadmin_data[0].name
container_path = "/var/lib/pgadmin"
}
# Health check for pgAdmin web interface
healthcheck {
test = ["CMD-SHELL", "nc -z localhost 80 || exit 1"]
interval = "30s"
timeout = "10s"
retries = 3
start_period = "60s"
}
restart = "unless-stopped"
labels {
label = "coder.service"
value = "pgadmin"
}
labels {
label = "coder.workspace_id"
value = local.workspace_id
}
}
# =============================================================================
# Jupyter Lab Service (Optional for Data Science)
# =============================================================================
# Jupyter data volume
resource "docker_volume" "jupyter_data" {
count = data.coder_parameter.enable_jupyter.value ? 1 : 0
name = "jupyter-data-${local.workspace_id}"
labels {
label = "coder.service"
value = "jupyter"
}
labels {
label = "coder.workspace_id"
value = local.workspace_id
}
}
# Jupyter Lab container
resource "docker_container" "jupyter" {
count = data.coder_parameter.enable_jupyter.value ? 1 : 0
image = "jupyter/scipy-notebook:latest"
name = "jupyter-${local.workspace_id}"
# Jupyter configuration
env = [
"JUPYTER_ENABLE_LAB=yes",
"JUPYTER_TOKEN=",
"RESTARTABLE=yes",
"JUPYTER_PORT=8888"
]
networks_advanced {
name = docker_network.workspace.name
}
# Port accessible within workspace network - no host exposure needed
# Data persistence
volumes {
volume_name = docker_volume.jupyter_data[0].name
container_path = "/home/jovyan/work"
}
# Share workspace volume
volumes {
volume_name = docker_volume.workspaces.name
container_path = "/home/jovyan/workspaces"
read_only = false
}
restart = "unless-stopped"
labels {
label = "coder.service"
value = "jupyter"
}
labels {
label = "coder.workspace_id"
value = local.workspace_id
}
}