404 Not Found with Docker, React Router and Nginx

Patrick O'Neill
2 min readAug 25, 2020

I had found other guides for dockerising a React project using React Router and served using Nginx. However I kept on coming upon this error when going to an address that was not the root (ie /users or /posts). I could navigate through my React SPA and the address bar would update but when going directly to a route I would get a 404 error.

Arghhhhh!
# Build Environment
FROM node:14.8.0-alpine as build
WORKDIR /app
COPY package*.json ./
RUN npm ci --silent
# Have a .dockerignore file ignoring node_modules and build
COPY . ./
RUN npm run build
# Production
FROM nginx:stable-alpine
COPY --from=build /app/build /usr/share/nginx/html
COPY nginx.conf /etc/nginx/nginx.conf
CMD ["nginx", "-g", "daemon off;"]

This was my Dockerfile and all seemed to make sense the local nginx.conf file (in the same folder as the Dockerfile) was overwriting the one in the container and it should use mine instead but this wasn’t happening.

server {
listen 80;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
try_files $uri $uri/ /index.html;
}
}

This needs to be in your nginx.conf file and the important bit is the try_files which is it can’t find the route you are looking for will then try index.html as we want to.

The problem was my in my nginx.conf file I had a line:

 include /etc/nginx/conf.d/*.conf;

This was telling it to include the default config files which seemed to be overwriting my own. Commenting out or deleting this line then building and running the images meant the end of the 404 errors.

I had created my original nginx.conf file by going into the container using:

docker exec -it container_name /bin/sh

From there I navigated to the /etc/nginx directory and used:

cat nginx.conf

To print out the contents of the file and then copied and pasted it into VS Code which left the include default config files in.

Here is the corrected nginx.conf file:

# nginx.confuser  nginx;
worker_processes auto;
error_log /var/log/nginx/error.log warn;pid /var/run/nginx.pid;events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main; sendfile on;
#tcp_nopush on;

keepalive_timeout 65;
#gzip on; #include /etc/nginx/conf.d/*.conf;server {
listen 80;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
try_files $uri $uri/ /index.html;
}
}
}

I hope this can help some people out and save some head scratching!

--

--