@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"
  • Вопрос задан
  • 390 просмотров
Решения вопроса 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 для моего сайта.
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

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

Войти через центр авторизации
Похожие вопросы