Serving static files stored in the physical machine using docker-compose

Viewed 137

I have a docker-compose file that I'm using to host a backend service:

nginx:
    image: nginx:latest
    container_name: nginx
    restart: unless-stopped
    ports:
      - 80:80
    volumes:
      - /projects/tour/tour-nginx-conf/nginx.conf:/etc/nginx/nginx.conf
      - /projects/tour/tour-nginx-conf/tour.conf:/etc/nginx/sites-enabled/tour.online.conf
      - /projects/tour/tour-nginx-conf/security.conf:/etc/nginx/nginxconfig.io/security.conf
      - /projects/tour/tour-nginx-conf/proxy.conf:/etc/nginx/nginxconfig.io/proxy.conf
      - /projects/tour/tour-nginx-conf/general.conf:/etc/nginx/nginxconfig.io/general.conf

tour-be:
    image: tour-be
    container_name: tour-be
    depends_on:
      mysql:
        condition: service_healthy
    ports:
      - "5000:5000"
    restart: always
    volumes:
      - be_data:/uploads

The nginx conf file:

...
location = /api {
    return 302 /api/;
}

location = /bo {
    return 302 /bo/;
}

location /api/ {
    proxy_pass http://tour-be:5000/;
}

location /uploads {
    root /uploads/;
}
...

I'm storing some static files under the /uploads/image directory. As of now I'm not able to get these images and I get the standard Nginx error 404 page. I get that this way I'm looking for the container filesystem path. How should I use correctly the volumes as declared in the docker-compose.yaml file?

1 Answers

You haven't given the nginx container access to the uploads directory. You just need to copy the volume entry from the tour-be container. Both containers can share access to the same directory.

services:
  nginx:
    image: nginx:latest
    container_name: nginx
    restart: unless-stopped
    ports:
      - "80:80"
    volumes:
      - /projects/tour/tour-nginx-conf/nginx.conf:/etc/nginx/nginx.conf
      - /projects/tour/tour-nginx-conf/tour.conf:/etc/nginx/sites-enabled/tour.online.conf
      - /projects/tour/tour-nginx-conf/security.conf:/etc/nginx/nginxconfig.io/security.conf
      - /projects/tour/tour-nginx-conf/proxy.conf:/etc/nginx/nginxconfig.io/proxy.conf
      - /projects/tour/tour-nginx-conf/general.conf:/etc/nginx/nginxconfig.io/general.conf
      - be_data:/uploads
      
  tour-be:
    image: tour-be
    container_name: tour-be
    depends_on:
      mysql:
        condition: service_healthy
    ports:
      - "5000:5000"
    restart: always
    volumes:
      - be_data:/uploads

Then make sure your nginx.conf has the following configuration :

http {
  server {
    port_in_redirect off;
    location /uploads/ {
      alias /uploads/;
    }
  }
}

The port_in_redirect off; directive is extremely important. Without it, nginx will strip the externally mapped port number from your request and try to redirect to port 80.

Related