As shown below, I have set up the environment with docker containers. The reason for this is because I only have a single VPS where I can run both frontend and backend on.
The way I want to tackle the problem is to put Nginx inside a docker container, using certbot for the verification (which already works) and then to reverse proxy into the frontend or backend based on what location the user is requesting. As shown I am not sure how Nginx should communicate with the frontend or backend.
When I tried to do
upstream docker-frontend {
server frontend:8081;
}
upstream docker-backend {
server backend:8080;
}
Gave me a 502 bad gateway
error. I somewhere on Stackoverflow found that instead of running the backend or frontend purely on 8080->8080/tcp or 8081->8081/tcp, I should run both on 80/tcp.
I also made sure to put all the containers on the same network, which seemed to have helped slightly.
Then as follows write the Nginx configuration
upstream docker-frontend {
server frontend:80;
}
upstream docker-backend {
server backend:80;
}
However by doing so I now have a completely blank page with nothing showing up. I can assure you that there's no blank page in the frontend (which is built with Vue 3.0 vite).
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;
upstream docker-frontend {
server frontend:80;
}
upstream docker-backend {
server backend:80;
}
server {
listen 8081;
location / {
proxy_pass http://docker-frontend/;
proxy_redirect off;
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-Forwarded-Host $server_name;
}
}
server {
listen 8080;
location / {
proxy_pass http://docker-backend/example/;
proxy_redirect off;
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-Forwarded-Host $server_name;
}
}
server {
listen 80;
listen [::]:80;
server_name www.example.com;
include letsencrypt-acme-challenge.conf;
return 301 https://www.example.com;
}
server {
listen 443 ssl;
listen [::]:443 ssl;
server_name example.com;
ssl_certificate fullchain.pem;
ssl_certificate_key privkey.pem;
ssl_trusted_certificate chain.pem;
return 301 https://www.example.com;
}
server {
listen 443 ssl default_server;
listen [::]:443 ssl default_server;
server_name www.example.com;
ssl_certificate fullchain.pem;
ssl_certificate_key privkey.pem;
ssl_trusted_certificate chain.pem;
root /usr/share/nginx/html/;
location / {
gzip off;
root /usr/share/nginx/html/;
index index.html;
try_files $uri $uri/ /index.html;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload";
add_header X-Frame-Options DENY;
add_header X-Content-Type-Options nosniff;
add_header X-XSS-Protection "1; mode=block";
add_header Referrer-Policy "origin";
proxy_pass http://docker-frontend/;
proxy_redirect off;
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-Forwarded-Host $server_name;
}
location /example/ {
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload";
add_header X-Frame-Options DENY;
add_header X-Content-Type-Options nosniff;
add_header X-XSS-Protection "1; mode=block";
add_header Referrer-Policy "origin";
proxy_pass http://docker-backend/example/;
proxy_redirect off;
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-Forwarded-Host $server_name;
}
}
}
The nginx.conf created in the process of trying to learn how reverse proxy works, but I cannot seem to figure out why it is still showing a blank page. Any help would be appreciated.
EDIT: It does seem like it shows the index.html, but I don't see any of the css or javascript within the page. Right now the dockerfile of the Vue app is configured as follows
Dockerfile
FROM node:lts-alpine as build-stage
RUN mkdir -p /app
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build
FROM nginx:stable-alpine as production-stage
COPY ./nginx.conf /etc/nginx/nginx.conf
RUN rm -rf /usr/share/nginx/html/*
COPY --from=build-stage /app/dist /usr/share/nginx/html
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
However I am still not sure why it does not load the javascript or css. Is there a special way of setting up a reverse proxy for Vue? Or is my nginx.conf not set up properly?
EDIT: Even after adding hot reload
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
It still does not want to show anything but a blank page.
When I inspect the docker container of the Vue application with
docker exec -it example /bin/sh
In the /html
folder it shows with the favicon, assets and the index.html, but there's no css or js folder? Within the assets folder however there's a weird index.a6f56555.js
and index.1212255f.css
. Did anyone else experience this before or is it just me?
EDIT: I found out that Vue isn't correctly building itself with the Dockerfile to the /html
folder, for some reason it only puts the index.html there but not the javascript or css?
vite.config.js
import { fileURLToPath, URL } from 'url'
import vue from '@vitejs/plugin-vue'
import { defineConfig } from 'vite'
import svgLoader from 'vite-svg-loader'
export default defineConfig({
server: {
port: 8081
},
plugins: [vue(), svgLoader()],
resolve: {
alias: {
'@': fileURLToPath(new URL('./src', import.meta.url)),
},
},
publicPath: process.env.NODE_ENV === 'production'
? ''
: '/',
css: {
loaderOptions: {
sass: {
prependData: `@import "@/styles/_variables.scss";`
},
},
preprocessorOptions: {
scss: {
implementation: require('sass'),
additionalData: `
@import "./src/assets/scss/main.scss";
`
}
}
},
base: './'
})
Even with setting up the Vite config file as recommended by multiple sources and the package.json containing the
npm run build && vite preview --port 8081 --host
command, it still shows up with a blank page, can anyone tell me what I've been doing wrong? Because I have no clue at this point...
所有评论(0)