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

如何用Docker Compose实现双域名指向同一项目并分连不同数据库?

Alright, let's break down how to get your two domains pointing to the same app instance but connecting to separate databases using Docker Compose. Here's a practical, step-by-step solution tailored to your setup:

Core Idea

The key is to use Nginx as a reverse proxy to route requests from each domain to your single app service, while passing the domain information to the app. Your app will then use that domain info to connect to the corresponding database. We'll also spin up two independent database containers for each domain.

1. Update Docker Compose Configuration

We'll modify your existing docker-compose.yml to add two database services, keep your single app service, and add an Nginx proxy service. Here's the full config:

version: '3.8'

services:
  # Shared app service (uses the same codebase)
  app:
    build: . # Assumes your Dockerfile is in the current directory
    environment:
      - APP_ENV=local # Add any shared env vars here
    volumes:
      - ./app:/app # Mount local code for development convenience
    depends_on:
      - db_xyz_com
      - db_xyz_net
    networks:
      - app_network

  # Database for xyz.com
  db_xyz_com:
    image: mysql:8.0 # Swap with your preferred DB (PostgreSQL, MongoDB, etc.)
    environment:
      - MYSQL_ROOT_PASSWORD=secure_root_pass_123
      - MYSQL_DATABASE=xyz_com_db
      - MYSQL_USER=xyz_app_user
      - MYSQL_PASSWORD=secure_app_pass_456
    volumes:
      - db_com_data:/var/lib/mysql # Isolated volume for xyz.com data
    networks:
      - app_network

  # Database for xyz.net
  db_xyz_net:
    image: mysql:8.0
    environment:
      - MYSQL_ROOT_PASSWORD=secure_root_pass_123
      - MYSQL_DATABASE=xyz_net_db
      - MYSQL_USER=xyz_app_user
      - MYSQL_PASSWORD=secure_app_pass_456
    volumes:
      - db_net_data:/var/lib/mysql # Isolated volume for xyz.net data
    networks:
      - app_network

  # Nginx reverse proxy to handle domain routing
  nginx:
    image: nginx:alpine
    ports:
      - "80:80" # Map port 80 on your host to Nginx
    volumes:
      - ./nginx.conf:/etc/nginx/conf.d/default.conf # Mount custom Nginx config
    depends_on:
      - app
    networks:
      - app_network

volumes:
  db_com_data:
  db_net_data:

networks:
  app_network:
    driver: bridge
2. Configure Nginx for Domain Routing

Create an nginx.conf file in the same directory as your docker-compose.yml. This config will route requests based on the incoming domain and pass the domain name to your app:

server {
    listen 80;
    server_name xyz.com www.xyz.com;

    location / {
        proxy_pass http://app:2000; # Forward to your app's internal port (matches your original localhost:2000)
        proxy_set_header Host $host; # Pass the original domain to the app
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}

server {
    listen 80;
    server_name xyz.net www.xyz.net;

    location / {
        proxy_pass http://app:2000;
        proxy_set_header Host $host; # Critical for the app to identify the domain
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}
3. Modify Your App to Switch Databases by Domain

This is the most important part—your app needs to detect the incoming domain and use the corresponding database connection. Here's an example using Python/Flask (the logic translates to any language):

from flask import Flask, request
import mysql.connector

app = Flask(__name__)

# Define database configs for each domain
DB_CONFIGS = {
    "xyz.com": {
        "host": "db_xyz_com", # Matches the DB service name in Docker Compose
        "user": "xyz_app_user",
        "password": "secure_app_pass_456",
        "database": "xyz_com_db"
    },
    "xyz.net": {
        "host": "db_xyz_net",
        "user": "xyz_app_user",
        "password": "secure_app_pass_456",
        "database": "xyz_net_db"
    }
}

def get_db_connection():
    # Extract the domain (strip www if present)
    raw_host = request.host.split(':')[0]
    domain = raw_host[4:] if raw_host.startswith('www.') else raw_host
    
    # Fallback to xyz.com if domain isn't recognized
    config = DB_CONFIGS.get(domain, DB_CONFIGS["xyz.com"])
    return mysql.connector.connect(**config)

@app.route('/')
def home():
    conn = get_db_connection()
    cursor = conn.cursor()
    cursor.execute("SELECT DATABASE()")
    current_db = cursor.fetchone()[0]
    return f"Welcome to {request.host}! Connected to database: {current_db}"

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=2000)

For other languages (Node.js/Express, PHP, etc.), the logic is identical:

  1. Grab the Host header from the request
  2. Map it to the corresponding database config
  3. Use that config to establish a connection
4. Map Domains to Your Local Machine

Since you're testing locally, add these lines to your system's hosts file to point the domains to your localhost:

  • Windows: C:\Windows\System32\drivers\etc\hosts
  • macOS/Linux: /etc/hosts
127.0.0.1 xyz.com
127.0.0.1 xyz.net
5. Start Services & Test

Run this command to build and start all services:

docker-compose up -d --build

Now open your browser and visit:

  • http://xyz.com → Should show it's connected to xyz_com_db
  • http://xyz.net → Should show it's connected to xyz_net_db
Extra Tips
  • Database Initialization: If you need to seed each database with tables/data, mount an init script to each DB service. For example, add - ./init_com.sql:/docker-entrypoint-initdb.d/init.sql to db_xyz_com volumes, and a corresponding init_net.sql for db_xyz_net.
  • Production Considerations: For production, add SSL certificates (use Let's Encrypt with Nginx) and harden database security (avoid root users, use stronger passwords).
  • Config Management: Instead of hardcoding DB configs in your app, use environment variables or external config files for easier updates.

内容的提问来源于stack exchange,提问作者Aayush Raj Joshi

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.08 13:02:58