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

如何使用Terraform配置两个不同端口的Nginx Docker实例?

How to Run Two Web Instances with Different External Ports Using Terraform + Nginx

Got it, let's tackle this problem step by step. To run two web instances on the same server with different external ports (and integrate Nginx as part of the setup using Terraform), here's a clean, scalable approach:

We'll use Terraform's count meta-argument to spin up multiple web instances, a dedicated Docker network for inter-container communication, and Nginx as a reverse proxy to route traffic from different external ports to each web instance.

Step 1: Define a Docker Network

First, create a private Docker network so all containers can communicate with each other using their names (no messy IP dependencies):

resource "docker_network" "web_network" {
  name = "web-instances-net"
}

Step 2: Spin Up Two Web Instances

Use count = 2 to create identical (or configurable) web instances. We'll use Nginx as the web app here, but you can swap in any image you need:

# Pull the base web app image
resource "docker_image" "web_app" {
  name = "nginx:1.11-alpine"
}

# Create 2 web instances
resource "docker_container" "web_instance" {
  count = 2
  name  = "web-instance-${count.index + 1}" # Names: web-instance-1, web-instance-2
  image = docker_image.web_app.latest

  # Attach to our private network
  networks_advanced {
    name = docker_network.web_network.name
  }

  # Internal port stays 80 (no need to expose directly to the host)
  ports {
    internal = 80
  }
}

Step 3: Configure Nginx as Reverse Proxy

We'll generate an Nginx config dynamically using Terraform's template functionality, mapping external ports 8080 and 8081 to our two web instances.

Option A: Use an inline template (no external file)

# Pull the Nginx proxy image
resource "docker_image" "nginx_proxy" {
  name = "nginx:1.11-alpine"
}

# Dynamically render Nginx config
data "template_file" "nginx_proxy_config" {
  template = <<EOF
events {}

http {
  # Route external port 8080 to web-instance-1
  server {
    listen 8080;
    server_name localhost;

    location / {
      proxy_pass http://${web_instance_1}:80;
      proxy_set_header Host $host;
      proxy_set_header X-Real-IP $remote_addr;
    }
  }

  # Route external port 8081 to web-instance-2
  server {
    listen 8081;
    server_name localhost;

    location / {
      proxy_pass http://${web_instance_2}:80;
      proxy_set_header Host $host;
      proxy_set_header X-Real-IP $remote_addr;
    }
  }
}
EOF

  vars = {
    web_instance_1 = docker_container.web_instance[0].name
    web_instance_2 = docker_container.web_instance[1].name
  }
}

# Save the rendered config to a local file
resource "local_file" "nginx_proxy_config" {
  content  = data.template_file.nginx_proxy_config.rendered
  filename = "${path.module}/nginx-proxy.conf"
}

# Launch the Nginx proxy container
resource "docker_container" "nginx_proxy" {
  name  = "nginx-reverse-proxy"
  image = docker_image.nginx_proxy.latest

  networks_advanced {
    name = docker_network.web_network.name
  }

  # Expose the external ports to the host
  ports {
    internal = 8080
    external = 8080
  }
  ports {
    internal = 8081
    external = 8081
  }

  # Mount our custom config into the Nginx container
  volumes {
    container_path = "/etc/nginx/nginx.conf"
    host_path      = local_file.nginx_proxy_config.filename
    read_only      = true
  }

  # Ensure the config file and web instances exist before starting the proxy
  depends_on = [local_file.nginx_proxy_config, docker_container.web_instance]
}

Option B: Use an external template file

If you prefer keeping the Nginx config separate, create a file named nginx-proxy.conf.tpl in your Terraform directory:

events {}

http {
  server {
    listen 8080;
    server_name localhost;

    location / {
      proxy_pass http://${web_instance_1}:80;
      proxy_set_header Host $host;
      proxy_set_header X-Real-IP $remote_addr;
    }
  }

  server {
    listen 8081;
    server_name localhost;

    location / {
      proxy_pass http://${web_instance_2}:80;
      proxy_set_header Host $host;
      proxy_set_header X-Real-IP $remote_addr;
    }
  }
}

Then replace the data "template_file" block with:

data "template_file" "nginx_proxy_config" {
  template = file("${path.module}/nginx-proxy.conf.tpl")

  vars = {
    web_instance_1 = docker_container.web_instance[0].name
    web_instance_2 = docker_container.web_instance[1].name
  }
}

How It Works

  • Private Network: All containers are on the same network, so Nginx can reach the web instances using their container names (e.g., web-instance-1).
  • Dynamic Config: Terraform injects the correct container names into the Nginx config, so you don't have to hardcode IPs.
  • Port Routing: External traffic to localhost:8080 goes to the first web instance, and localhost:8081 goes to the second.

Key Notes

  • Scalability: If you need more instances later, just change count = 2 to count = N and update the Nginx config template to add more server blocks (or use a loop in the template with for if you're using Terraform 0.12+).
  • Custom Web Apps: Swap the docker_image.web_app name with your actual web app image (e.g., my-node-app:latest) and adjust the internal port if your app uses something other than 80.
  • Dependency Order: The depends_on ensures the proxy doesn't start before the web instances and config file are ready, avoiding startup errors.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 03:28:57