You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Terraform在Azure Container Apps中部署docker-compose

用Terraform将Traefik+Docker Compose部署到Azure Container Apps

关键架构调整说明

Azure Container Apps是托管式容器服务,不提供/var/run/docker.sock访问,所以你原Docker Compose中Traefik的--providers.docker配置无法工作——Traefik没法通过Docker socket发现form-service的实例。因此需要先调整架构:

方案1:使用Container Apps内置Ingress(推荐)

直接利用Azure Container Apps自带的Ingress功能替代Traefik的反向代理作用,简化架构并利用托管服务的特性。

方案2:保留Traefik(需调整配置)

如果必须保留Traefik,需要放弃Docker provider,改用静态文件配置或其他服务发现方式,会增加复杂度。


方案1:Terraform配置示例(内置Ingress)

以下是将你的服务部署到Azure Container Apps的Terraform代码,使用azurerm provider:

1. 基础资源定义

terraform {
  required_providers {
    azurerm = {
      source  = "hashicorp/azurerm"
      version = "~> 3.0"
    }
  }
}

provider "azurerm" {
  features {}
}

# 创建资源组
resource "azurerm_resource_group" "example" {
  name     = "container-apps-rg"
  location = "East US"
}

# 创建Container Apps环境
resource "azurerm_container_app_environment" "example" {
  name                = "container-apps-env"
  resource_group_name = azurerm_resource_group.example.name
  location            = azurerm_resource_group.example.location
}

# 关联Azure Container Registry(替换为你的ACR信息)
data "azurerm_container_registry" "acr" {
  name                = "XX"
  resource_group_name = azurerm_resource_group.example.name
}

resource "azurerm_container_app_registry_credential" "acr" {
  container_app_environment_id = azurerm_container_app_environment.example.id
  server                        = data.azurerm_container_registry.acr.login_server
  username                      = data.azurerm_container_registry.acr.admin_username
  password                      = data.azurerm_container_registry.acr.admin_password
}

2. 部署form-service容器应用

resource "azurerm_container_app" "form_service" {
  name                = "form-service"
  resource_group_name = azurerm_resource_group.example.name
  location            = azurerm_resource_group.example.location
  environment_id      = azurerm_container_app_environment.example.id

  template {
    container {
      name   = "form-service"
      image  = "${data.azurerm_container_registry.acr.login_server}/form-service:latest"
      cpu    = 0.5
      memory = "1Gi"

      env {
        name  = "LOG_LEVEL"
        value = "trace"
      }

      ports {
        port     = 3031
        protocol = "TCP"
      }

      ports {
        port     = 3032
        protocol = "TCP"
      }
    }
  }

  ingress {
    external_enabled = true
    target_port      = 3031
    allow_insecure_connections = true
  }
}

3. 配置自定义路由规则(对应原Traefik路由)

通过azurerm_container_app_ingress_route配置路径路由:

# 配置/app1路由
resource "azurerm_container_app_ingress_route" "app1" {
  container_app_id = azurerm_container_app.form_service.id
  name             = "app1-route"
  match_path       = "/app1/*"
  priority         = 100
  service {
    port = 3031
  }
}

# 配置/app2路由
resource "azurerm_container_app_ingress_route" "app2" {
  container_app_id = azurerm_container_app.form_service.id
  name             = "app2-route"
  match_path       = "/app2/*"
  priority         = 90
  service {
    port = 3032
  }
}

方案2:保留Traefik的Terraform配置(可选)

如果必须保留Traefik,需修改配置放弃Docker provider,改用静态文件配置:

1. 准备Traefik配置文件

在Terraform代码目录下创建两个配置文件:

  • traefik.yml(静态配置):
api:
  insecure: true
entryPoints:
  web:
    address: ":80"
providers:
  file:
    filename: /etc/traefik/dynamic_config.yml
  • dynamic_config.yml(动态路由配置,替换为你的Container Apps域名):
http:
  routers:
    app1:
      rule: "Host(`<your-container-app-domain>`) && PathPrefix(`/app1`)"
      entryPoints: [web]
      service: app1
    app2:
      rule: "Host(`<your-container-app-domain>`) && PathPrefix(`/app2`)"
      entryPoints: [web]
      service: app2
  services:
    app1:
      loadBalancer:
        servers: [{url: "http://form-service:3031"}]
    app2:
      loadBalancer:
        servers: [{url: "http://form-service:3032"}]

2. Terraform部署配置

# 部署Traefik容器应用
resource "azurerm_container_app" "traefik" {
  name                = "traefik"
  resource_group_name = azurerm_resource_group.example.name
  location            = azurerm_resource_group.example.location
  environment_id      = azurerm_container_app_environment.example.id

  template {
    container {
      name   = "traefik"
      image  = "traefik:v2.10"
      cpu    = 0.5
      memory = "1Gi"

      volume_mounts {
        volume_name = "traefik-config"
        mount_path  = "/etc/traefik"
      }
    }

    volume {
      name = "traefik-config"
      secret {
        secret_name = "traefik-config-secret"
      }
    }
  }

  ingress {
    external_enabled = true
    target_port      = 80
    allow_insecure_connections = true
  }
}

# 存储Traefik配置的Secret
resource "azurerm_container_app_secret" "traefik_config" {
  container_app_id = azurerm_container_app.traefik.id
  name             = "traefik-config-secret"
  data = {
    "traefik.yml"        = filebase64("${path.module}/traefik.yml")
    "dynamic_config.yml" = filebase64("${path.module}/dynamic_config.yml")
  }
}

# 部署form-service(仅内部访问)
resource "azurerm_container_app" "form_service" {
  name                = "form-service"
  resource_group_name = azurerm_resource_group.example.name
  location            = azurerm_resource_group.example.location
  environment_id      = azurerm_container_app_environment.example.id

  template {
    container {
      name   = "form-service"
      image  = "${data.azurerm_container_registry.acr.login_server}/form-service:latest"
      cpu    = 0.5
      memory = "1Gi"

      env {
        name  = "LOG_LEVEL"
        value = "trace"
      }

      ports {
        port     = 3031
        protocol = "TCP"
      }

      ports {
        port     = 3032
        protocol = "TCP"
      }
    }
  }

  ingress {
    external_enabled = false
  }
}

注意事项

  • Container Apps环境内的容器可通过服务名直接通信,无需额外网络配置。
  • 若使用ACR镜像,需确保Container Apps环境已配置ACR访问凭据(代码中已包含)。
  • 自定义域名需在DNS服务商处配置CNAME指向Container Apps的默认域名。

内容的提问来源于stack exchange,提问作者Karim Chaari

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 15:08:19