naveen purohit
naveen purohit

Reputation: 11

How to use another docker container as a subdirectory of main website?

I am new to docker and container concepts, I want to host a react website xyz.com with a container at port:3000 and I want to add Admin subdirectory into it like xyz.com/Admin in which main website(xyz.com) is one container and /Admin must be another one (Total 2 containers). Please help me how can I figure this out (like changes in Dockerfile, code or in docker-compose).

Upvotes: 0

Views: 1626

Answers (1)

Andreas Lorenzen
Andreas Lorenzen

Reputation: 4230

What you need for this is a reverse proxy. The reverse proxy will stand in front of the two web applications, and map the appropriate paths to the appropriate containers.

I have a simple example here for you, using docker-compose and nginx. It starts three nginx containers, one acting as the proxy, and the two others just acting as your web applications (root and admin)

Project structure:

/simple-proxy-two-websites
├── docker-compose.yml
├── default.conf

In the docker-compose definition, we map the config into the reverse-proxy and map the listening port (80) to the host machine port 80. And then we just set up two default nginx containers to act as the web applications that we want to serve.

docker-compose.yml

version: "3"

services:

  reverse-proxy:
    image: nginx
    volumes:
      - ./default.conf:/etc/nginx/conf.d/default.conf:ro
    depends_on:
      - "web-admin"
      - "web-root"
    ports:
      - 80:80
  
  web-root:
    image: nginx
  
  web-admin:
    image: nginx

In the nginx reverse-proxy server configuration (taken from the default config that is shipped with the docker image, with all commented lines removed) we then add location /admin and change location / as seen below. Notice that the proxy_pass parameter is a URL that uses the servicename defined in the docker-compose definition above. Docker is making this easy, when the containers are on the same network (in this case the default bridge network), by allowing us to use the service names.

default.conf

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

    location / {
        proxy_set_header X-Forwarded-Host $host;
        proxy_set_header X-Forwarded-Server $host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_pass              http://web-root:80/;  
    }
    
    location /admin {
        proxy_set_header X-Forwarded-Host $host;
        proxy_set_header X-Forwarded-Server $host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_pass              http://web-admin:80/;    
    }

    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }
}

With this configuration the nginx reverse-proxy will do an internal network forward of the request to the proxy_pass destination defined in the /location - the destination does not have to be reachable from the outside.

you can take this example and update it with your servicenames, and specific ports - it should get you going.

I also have a complete example, where I override the default index.html pages of the web-admin and web-root containers, to verify that the correct destination has been reached. Let me know if you want that, then I will make it available in a repository on GitHub.

Upvotes: 1

Related Questions