@ErichZann

Почему Nginx возвращает 404 для Docker контейнера с фронтенд? И почему не перенаправляет 404 на главную страницу?

Добрый день
столкнулся со следующей проблемой, решил поместить Vue фронтенд и ASP Core бекенд в Docker, и вроде бы все работает хорошо, но нашел недостаток в моей схеме, что могу открыть фронтенд только по корневому домену (например mydomain.com). Если пытаюсь открыть через браузер mydomain.com/employees или mydomain.com/customers то всегда получаю ошибку 404, но могу их открыть если в браузере открою корневой домен mydomain.com и потом нажимаю на иконки, которые перенаправляют на /employee. Скорее всего я что-то не так настроил в Nginx, но что понять не могу.
Cам Nginx не в контейнере, а использую из хост-машины (Ubuntu 22.04.1), настраивался по руководству с сайта Digital Ocean. Может я не прав, что так делаю и надо Nginx тоже обязательно в Docker контейнет?

Можете пожалуйста подсказать где не прав в конфигурации Nginx?
Также подскажите пожалуйста почему не перенаправляет 404 на главную страницу?
Спасибо

Содержимое `Dockerfile` для Frontend.
FROM node:16.19.0 as build-stage

# install simple http server for serving static content (from app/dist )
RUN npm install --quiet -g http-server

# make the 'app' folder the current working directory
WORKDIR /app

# copy both 'package.json' and 'package-lock.json' (if available)
# use slashes in copy because of error in `Github Action` build process
COPY package*.json ./ 

# copy project files and folders to the current working directory (i.e. 'app' folder)
COPY . ./

# install project dependencies
RUN npm install

# build the app
RUN npm run build


Часть кода из `docker.compose`

mag-frontend:
    container_name: mag-frontend
    restart: always
    build:
      context: ./mag-frontend
      dockerfile: Dockerfile
    ports:
      - "8080:8080"
    depends_on:
        -mag-backend
    command: "http-server dist"


nginx.conf cтандартный, вроде там ничего не менял

user www-data;
worker_processes auto;
pid /run/nginx.pid;
include /etc/nginx/modules-enabled/*.conf;

events {
	worker_connections 768;
	# multi_accept on;
}


http {

	##
	# Basic Settings
	##
	server_names_hash_bucket_size 64;
	sendfile on;
	tcp_nopush on;
	types_hash_max_size 2048;
	# server_tokens off;

	# server_names_hash_bucket_size 64;
	# server_name_in_redirect off;

	include /etc/nginx/mime.types;
	default_type application/octet-stream;

	##
	# SSL Settings
	##

	ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3; # Dropping SSLv3, ref: POODLE
	ssl_prefer_server_ciphers on;

	##
	# Logging Settings
	##

	access_log /var/log/nginx/access.log;
	error_log /var/log/nginx/error.log;

	##
	# Gzip Settings
	##

	gzip on;

	# gzip_vary on;
	# gzip_proxied any;
	# gzip_comp_level 6;
	# gzip_buffers 16 8k;
	# gzip_http_version 1.1;
	# gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;

	##
	# Virtual Host Configs
	##


	access_log  /var/log/nginx/access.log;
	error_log  /var/log/nginx/error_log;

	include /etc/nginx/conf.d/*.conf;
	include /etc/nginx/sites-enabled/*;
}


ниже содержимое конфиг файла для моего домена mydomain.com из /etc/nginx/sites-available.

server {
  access_log  /var/log/nginx/mydomain.access.log;
  error_log  /var/log/nginx/mydomain.error_log;

  listen 443 ssl ;
  listen [::]:443 ssl ;
  server_name mydomain.com; # managed by Certbot
  error_page 404 = /;

  location / {
    proxy_pass http://127.0.0.1:8080;
    proxy_redirect off;
    proxy_set_header Host $host:$server_port;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    error_page 400 500 404 /;
  }

  location /api/ {
    rewrite ^/api^/ /$1 break;
    proxy_pass http://127.0.0.1:5008/api/;
  }

  ssl_certificate /etc/letsencrypt/live/mydomain.com/fullchain.pem; # managed by Certbot
  ssl_certificate_key /etc/letsencrypt/live/mydomain.com/privkey.pem; # managed by Certbot
  include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
  ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}

server {
  if ($host = mydomain.com) {
        return 301 https://$host$request_uri;
  } # managed by Certbot

  listen 80 ;
  listen [::]:80 ;
  server_name mydomain.com;
  return 404; 
}


в логах Nginx никаких ошибок, а для mydomain.com/employees пишет в mydomain.access.log следующую строку.

[03/Mar/2023:04:40:58 +0000] "GET /employees HTTP/1.1" 404 5 "-" "Mozilla/5.0 (Windows NT 10.0; rv:109.0) Gecko/20100101 Firefox/109.0"
  • Вопрос задан
  • 588 просмотров
Решения вопроса 1
@ErichZann Автор вопроса
Спасибо Lynn «Кофеман» за подсказку, что проблема была больше не на уровне хост машины Ubuntu, а в моем Vue приложении. Подправил Dockerfile и убрал command: "http-server dist" и все заработало

Ниже исправленный Dockerfile

FROM node:16.19.0 as build-stage

# make the 'app' folder the current working directory
WORKDIR /app

# copy both 'package.json' and 'package-lock.json' (if available)
# use slashes in copy because of error in `Github Action` build process
COPY package*.json ./ 

# copy project files and folders to the current working directory (i.e. 'app' folder)
COPY . ./

# install project dependencies
RUN npm install

# build the app
RUN npm run build

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


Файл nginx.conf, который находится в корне фронтенд проекта (используется в Dockerfile выше):

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   /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;
    }
  }
}


Исправленная часть кода из `docker.compose`

mag-frontend:
    container_name: mag-frontend
    restart: always
    build:
      context: ./mag-frontend
      dockerfile: Dockerfile
    ports:
      - "8080:80"
    depends_on:
        -mag-backend


С этими изменениями все заработало, сразу в новом окне браузера открывается mydomain.com/employees . Единственное, что если ввести несуществующий маршрут mydomain.com/blahblah, то открывает не страницу 404 для Nginx, а пустую страницу сайта, но это понятно, надо будет самому создать компонент 404 для моего сайта.
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы