11

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?

3 Answers 3

16

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
Sign up to request clarification or add additional context in comments.

2 Comments

I don't know why you used envsubst command, I used your config file but directly copied it to the same location and it worked : COPY nginx.conf /etc/nginx/conf.d/default.conf
yes copying server tag in default.conf worked
2

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>

2 Comments

Tried many times to get this to work but the final commands do not work for me. I added a -t to the build command to actually get it to build but the run command fails with a 8080:8080 not found
Did you tried another port and did you get a specific error message?
1

This article resolved all issues

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

FROM nginx as production-stage
RUN mkdir /app
COPY --from=build-stage /app/dist /app
COPY nginx.conf /etc/nginx/nginx.conf

just COPY nginx.conf

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 {
    listen       80;
    server_name  localhost;
    location / {
      root   /app;
      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;
    }
  }
}

be aware on listen 80; << 8080 or other port

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.