I'm using boot2docker since I'm running Mac OSX. I can't figure out how serve up static files using nginx that is running inside a docker container (that also contains the static assets, like my html and js).
I have four docker containers being spun up with this docker-compose.yml:
web:
build: ./public
links:
- nodeapi1:nodeapi1
ports:
- "80:80"
nodeapi1:
build: ./api
links:
- redis
- db
ports:
- "5000:5000"
volumes:
- ./api:/data
redis:
image: redis:latest
ports:
- "6379:6379"
db:
image: postgres:latest
environment:
POSTGRES_USER: root
ports:
- "5432:5432"
This is my nginx.conf:
worker_processes auto;
daemon off;
events {
worker_connections 1024;
}
http {
server_tokens off;
upstream node-app {
ip_hash;
server 192.168.59.103:5000;
}
server {
listen 80;
index index.html;
root /var/www;
location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ {
expires 1d;
}
location / {
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-NginX-Proxy true;
proxy_http_version 1.1;
proxy_pass http://node-app;
proxy_cache_bypass $http_upgrade;
}
}
}
My Dockerfile for my web build (which contains my nginx.conf and static assets):
# Pull nginx base image
FROM nginx:latest
# Expost port 80
EXPOSE 80
# Copy custom configuration file from the current directory
COPY nginx.conf /etc/nginx/nginx.conf
# Copy static assets into var/www
COPY ./dist /var/www
COPY ./node_modules /var/www/node_modules
# Start up nginx server
CMD ["nginx"]
The contents of the ./dist folder is a bundle.js file and an index.html file. The file layout is:
public
-- Dockerfile
-- nginx.conf
-- dist (directory)
-- bundle.js
-- index.html
-- node_modules
...various node modules
It is properly sending requests to my node server (which is also in a docker container, which is why my upstream server points to the boot2docker ip), but I'm just getting 404s for attempts to retrieve my static assets.
I'm lost as to next steps. If I can provide any information, please let me know.
Your issue isn't related to docker but to your nginx configuration.
In your nginx config file, you define
/var/www/
as the document root (I guess to serve your static files). But below that you instruct nginx to act as a reverse proxy to your node app for all requests.Because of that, if you call the
/index.html
URL, nginx won't even bother checking the content of/var/www
and will forward that query to nodejs.Usually you want to distinguish requests for static content from requests for dynamic content by using a URL convention. For instance, all requests starting with
/static/
will be served by nginx while anything else will be forwarded to node. The nginx config file would then be: