如何使用 docker 和 nginx 在同一服务器上运行多个站点?

Ole*_*ndr 13 django nginx docker-compose

我试图在同一服务器上的不同 ip 下的 django 上运行两个站点,出现端口繁忙的错误,我修复了端口,但站点无法启动。请告诉我错误在哪里?IP 工作,当我转到第二个 IP 时,我会重定向到第一个站点。所有设置都是为第二个站点指定的。最后,我添加了第一个站点的nginx设置

这是第二个 docker-compose 文件及其设置。我将非常感谢你的帮助

.env

#Django
# Should be one of dev, prod
MODE=prod
PORT=8008

#postgres
DB_NAME=xxx
DB_USER=xxx
DB_HOST=xxx
DB_PASSWORD=xxxx
DB_PORT=5432
POSTGRES_PASSWORD=mysecretpassword

#WSGI
WSGI_PORT=8008
WSGI_WORKERS=4
WSGI_LOG_LEVEL=debug

# Celery
CELERY_NUM_WORKERS=2

# Email
EMAIL_HOST_USER=xxxx
EMAIL_HOST_PASSWORD=xxxx
Run Code Online (Sandbox Code Playgroud)

docker-compose.yml

version: '3'

services:

  backend:
    build: ./
    container_name: site_container
    restart: always
    command: ./commands/start_server.sh
    ports:
      - "${PORT}:${WSGI_PORT}"
    volumes:
      - ./src:/srv/project/src
      - ./commands:/srv/project/commands
      - static_content:/var/www/site
    env_file:
      - .env
    depends_on:
      - postgres

  postgres:
    image: postgres:12
    volumes:
      - pg_data:/var/lib/postgresql/data
    env_file:
      - .env
#    environment:
#      - DJANGO_SETTINGS_MODULE=app.settings.${MODE}

  nginx:
    image: nginx:1.19
    volumes:
      - ./nginx:/etc/nginx/conf.d
      - static_content:/var/www/site
    ports:
      - 81:80
      - 444:443
    env_file:
      - .env
    depends_on:
      - backend

volumes:
  pg_data: {}
  static_content: {}
Run Code Online (Sandbox Code Playgroud)

默认配置文件

server {
    listen 80 default_server;

    server_name 183.22.332.12;

    location /static/ {
        root /var/www/site;
    }

    location /media/ {
        root /var/www/site;
    }

    location / {
        proxy_set_header Host $host;
        proxy_pass http://backend:8010;
    }
}
Run Code Online (Sandbox Code Playgroud)

第一个站点的 default.conf

server {
    #listen 80 default_server;
    listen 443 ssl http2;
    listen [::]:443 ssl http2;

    server_name site1 ip_site1;

    ssl_certificate /etc/letsencrypt/live/site1/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/site1/privkey.pem;
    ssl_trusted_certificate /etc/letsencrypt/live/site1/chain.pem;

    location /static/ {
        root /var/www/artads;
    }

    location /media/ {
        root /var/www/artads;
    }

    location / {
        proxy_set_header Host $host;
        proxy_pass http://backend:8008;
    }
}

server {
    listen 80 default_server;

    server_name ip_site2 site2;

    location /static/ {
        root /var/www/gdr_mr;
    }

    location /media/ {
        root /var/www/gdr_mr;
    }

    location / {
        proxy_set_header Host $host;
        proxy_pass http://backend:8013;
    }
}

server {
        listen 80;
        listen [::]:80;

        server_name www.site1 site1;

        location / {
                return 301 https://site1$request_uri;
        }
}
Run Code Online (Sandbox Code Playgroud)

Cha*_*dan 5

感谢@Roman Tokaren 和@Oleksandr

这是 @Roman Tokaren提交的英文翻译版本


您总是可以对“正确”启动争论很多 - 毕竟有多少人,这么多意见,但我将描述一个“方便”且可扩展的配置的示例。为了在这种配置中工作的“方便”,我建议安装nginxproxymanager作为反向代理,并将容器和nginxproxymanager组合到一个网络中 - 之后就可以通过 http(s)、tcp、udp 将容器端口转发到使用 GUI 的外部界面以及许多其他功能,例如 SSL 证书的生成及其自动续订


首先,让我们创建网络本身

docker network create --driver bridge --subnet 172.26.0.0/24 testnet
Run Code Online (Sandbox Code Playgroud)

让我们配置 NPM ( nginxproxymanager ) - 默认情况下我们将反向代理视为最后一个网络节点,结果我们将得到

version: "3"
services:
  app:
    image: 'jc21/nginx-proxy-manager:latest'
    networks:
      testnet:
        ipv4_address: 172.26.0.254
    restart: always
    ports:
      # Public HTTP Port:
      - '80:80'
      # Public HTTPS Port:
      - '443:443'
      # Admin Web Port:
      - '81:81'
    environment:
      # These are the settings to access your db
      DB_MYSQL_HOST: "172.26.0.253"
      DB_MYSQL_PORT: 3306
      DB_MYSQL_USER: "user"
      DB_MYSQL_PASSWORD: "pwd"
      DB_MYSQL_NAME: "npm"
    volumes:
      - ./data/nginx-proxy-manager:/data
      - ./letsencrypt:/etc/letsencrypt
    depends_on:
      - db
  db:
    image: yobasystems/alpine-mariadb:latest
    restart: always
    networks:
      testnet:
        ipv4_address: 172.26.0.253
    environment:
      MYSQL_ROOT_PASSWORD: "pwd"
      MYSQL_DATABASE: "npm"
      MYSQL_USER: "user"
      MYSQL_PASSWORD: "pwd"
    volumes:
      - ./data/mariadb:/var/lib/mysql
networks:
  testnet:
    external: true
Run Code Online (Sandbox Code Playgroud)

并配置容器本身

version: '3'
services:
  backend:
    build: ./
    container_name: site_container
    restart: always
    command: ./commands/start_server.sh
    networks:
      testnet:
        ipv4_address: 172.26.0.2
    volumes:
      - ./src:/srv/project/src
      - ./commands:/srv/project/commands
      - static_content:/var/www/site
    env_file:
      - .env
    depends_on:
      - postgres

  postgres:
    image: postgres:12
    volumes:
      - pg_data:/var/lib/postgresql/data
    env_file:
      - .env
#    environment:
#      - DJANGO_SETTINGS_MODULE=app.settings.${MODE}

networks:
  testnet:
    external: true
volumes:
  pg_data: {}
  static_content: {}
Run Code Online (Sandbox Code Playgroud)

之后我们按照说明进行NPM的初始配置添加主机

域名设置