How to config nginx for Vue-router on Docker

Viewed 7073

I'm setting up a docker image from nginx to serve a Vue app as static files. My vue app uses Vue-Router and it works perfectly on an other server. My nginx config is just like this: https://router.vuejs.org/guide/essentials/history-mode.html#example-server-configurations

And now I wanna migrate to docker, and this is my Dockerfile

# build stage
FROM node:9.11.1-alpine as build-stage
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build

# production stage
FROM nginx:1.15.8-alpine as production-stage
COPY docker/nginx/prod.conf /etc/nginx/nginx.conf/prod.conf         # [*]
COPY --from=build-stage /app/dist /usr/share/nginx/html
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]

And this is the docker/nginx/prod.conf

server {
  listen 80;
  server_name _ default_server;

  root /usr/share/nginx/html;

  location / {
    try_files $uri $uri/ /index.html;
  }
}

It works with the home page, for example: http://192.168.1.10 but got 404 on other URL, such as http://192.168.1.10/settings

The prod.conf was copied to the nginx folder, I do see it.

Do you have any idea, or am I missing something?

2 Answers

This is how I solved my problem.

# Add nginx config
COPY .docker/nginx/prod.conf /temp/prod.conf
RUN envsubst /app < /temp/prod.conf > /etc/nginx/conf.d/default.conf

I would suggest to create a docker folder on the same level like public and src.

Then create inside the docker folder the Dockerfile:

# Step 1: Build Vue Project
FROM node:lts-alpine as build-stage
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build

# Step 2: Create Nginx Server
FROM nginx:stable-alpine as production-stage
COPY docker/nginx.conf /etc/nginx/nginx.conf

COPY --from=build-stage /app/dist /usr/share/nginx/html

CMD ["nginx", "-g", "daemon off;"]

Then create another file inside the docker folder and name it nginx.conf

# Ref: https://cli.vuejs.org/guide/deployment.html#docker-nginx

user  nginx;
worker_processes  1;
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;
  keepalive_timeout  65;
  server {
    # good practice not to use port 80 inside a container
    # because container should run as non root and they can't run under port < 1024 
    listen       8080;
    server_name  localhost;
    location / {
      root   /usr/share/nginx/html;
      index  index.html;
      try_files $uri $uri/ /index.html;
    }
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
      root   /usr/share/nginx/html;
    }
  }
}

Then build it with:

docker build <your_image_name> -f docker/Dockerfile .

Run it with:

docker run -d 8080:8080 <your_image_name>
Related