Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I run multiple sites on the same server using docker and nginx?

I'm trying to run two sites on django on the same server under different ip, an error occurs that the port is busy, I fixed the ports, but the site does not start. Tell me where is the error please? Ip work, when I go to the second ip I get redirects to the first site. All settings were specified for the second site. At the end, I added the nginx setting of the first site

This is the second docker-compose file and its settings. I would be very grateful for your help

.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

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: {}

default.conf

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;
    }
}

default.conf for first site

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;
        }
}

like image 570
Oleksandr Avatar asked Sep 14 '21 12:09

Oleksandr


People also ask

Can we run multiple apps on one server with Docker?

It's ok to have multiple processes, but to get the most benefit out of Docker, avoid one container being responsible for multiple aspects of your overall application. You can connect multiple containers using user-defined networks and shared volumes.

Can a Docker container have multiple networks?

You can create multiple networks with Docker and add containers to one or more networks. Containers can communicate within networks but not across networks. A container with attachments to multiple networks can connect with all of the containers on all of those networks.

How do I host multiple websites from a single Docker container?

But, containerizing software leads to another problem that confuses many: How do I host multiple websites, each in a separate Docker container, from one VPS? Fortunately, with a little bit of foresight and configuring, you can use Docker and Nginx to host multiple websites from a single VPS.

How do I link a docker-compose website to a Nginx server?

The docker-compose.yml file of the website, you want to link, should include the following instructions provided in the template available in the folder your-website-one.com ( not the one from nginx-proxy above). The content of the template looks like this: VIRTUAL_HOST: your domain name, used in the nginx configuration.

What is the difference between Docker-Gen and Nginx-proxy?

Nginx-proxy consists in a simple Nginx server and docker-gen. Docker-gen is a small tool written in Go which can be used to generate Nginx/HAProxy configuration files using Docker containers meta-data (obtained via the Docker API). These two applications are running as a Docker container and so are easy to get up running.

Can I run multiple WordPress sites on a Nginx server?

From here, you can start up any number of additional WordPress site—or any type of service, for that matter—and have them be automatically added to the nginx-proxy network. This Docker and Nginx configuration is pretty infinitely extensible, limited only by the VPS resources available to you.


Video Answer


3 Answers

Thanks to @Roman Tokaren and @Oleksandr

Here the english translated version submitted by @Roman Tokaren here


You can always argue a lot about the "correct" launch - after all, how many people, so many opinions, but I will describe an example + - of a "convenient" and scalable configuration. For the "convenience" of working in such a configuration, I would suggest installing nginxproxymanager as a reverse proxy and combining containers and nginxproxymanager into one network - after which it will be possible to forward container ports via http (s), tcp, udp to an external interface using the GUI as well as a number of other goodies, such as the generation of SSL certificates and their auto renewal


First, let's create the network itself

docker network create --driver bridge --subnet 172.26.0.0/24 testnet

Let's configure NPM (nginxproxymanager) - by default we will consider the reverse proxy as the last network node, as a result we will get

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

And configure the container itself

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: {}

After that, we carry out the initial configuration of NPM according to the instructions and add the host

Domain Setting

like image 161
Chandan Avatar answered Oct 27 '22 05:10

Chandan


If you want run more than one site in a server, you can

  1. use different ip
  2. use different port
  3. use different domain
  4. use different path and rewrite it ...

You can choose one of top list tips.

In your config, you choose different ip and same port, but you set all the site to default and not listen the different ip

server{
      listen      ip:port;
}

Usually IP is just omitted.

Or you can one ip and different port.

server{
      listen      port1;
}
server{
      listen      port2;
}

Or you can one ip and one port but different domain.

server{
      listen      port;
      server_name 1.a.com;
}
server{
      listen      port;
      server_name 2.a.com;
}
like image 30
rozbo Avatar answered Oct 27 '22 04:10

rozbo


If you're running two virtual servers with different IPs on the same machine, you'd want to specify the IP address in the listen directive:

server {
    listen      192.168.1.1:80;
    server_name example.net www.example.net;
    ...
}

server {
    listen      192.168.1.2:80;
    server_name example.com www.example.com;
    ...
}

More on how nginx processes requests can be found here: http://nginx.org/en/docs/http/request_processing.html

like image 31
hexbioc Avatar answered Oct 27 '22 04:10

hexbioc