Сервер узла недоступен в контейнере докеров на aws

Я создал веб-приложение реагирования, которое создается с использованием файла dockerfile и Supervisord.conf и развертывается в контейнере AWS с балансировщиком нагрузки. Мое приложение React работает на локальном хосте: 3000 и доступно по адресу http://www.jermasearch.com/

Я хочу добавить соединение с базой данных в свое приложение реагирования, которому требуется секретная переменная окружения клиента для подключения/запроса к базе данных. Чтобы безопасно включить эту секретную переменную, я пытаюсь создать простой небольшой внутренний сервер узла, который работает вместе с моим приложением реагирования.

Когда я запускаю свое репо локально с помощью команд npm start для приложения-реагирования и node server.js для моего узла-сервера, они оба запускаются нормально. И я могу отправить запрос почтальону на http://localhost:3030/dbtest, который вернет ожидаемый правильный текстовый ответ: Hello from the Node.js server!.

Если я создам свой образ докера и запущу его с помощью этих команд:

  • docker build -t myapp .
  • docker run -p 80:80 -p 3030:3030 myapp

обратите внимание, как я указываю порт 3030:3030 здесь, в строке выше, может быть, я как-то упускаю это из aws?

Маршрут /dbtest также работает, если я делаю запрос почтальона на тот же URL-адрес.

Но когда я помещаю свой код в контейнер aws ec2 и пытаюсь сделать запрос к производственному URL http://jermasearch.com:3030/dbtest или http://jermasearch.com:3030/dbtest, он возвращает html-содержимое страницы реагирующего приложения, что неверно:

<!doctype html>
<html lang = "en">

<head>
    <meta charset = "utf-8" />
    <link rel = "icon" href = "/favicon.ico" />
    <meta name = "viewport" content = "width=device-width,initial-scale=1" />
    <meta name = "theme-color" content = "#000000" />
    <meta name = "description" content = "Web site created using create-react-app" />
    <link rel = "apple-touch-icon" href = "/logo192.png" />
    <link rel = "manifest" href = "/manifest.json" />
    <title>React App</title>
    <script defer = "defer" src = "/static/js/main.9daeaa7a.js"></script>
    <link href = "/static/css/main.f855e6bc.css" rel = "stylesheet">
</head>

<body><noscript>You need to enable JavaScript to run this app.</noscript>
    <div id = "root"></div>
</body>

</html>

Все мои файлы здесь: https://github.com/MartinBarker/aws-react-docker-ghactions

В настоящее время мой файл dockerfile копирует встроенное содержимое реакции-приложения и server.js, затем предоставляет порты и запускает последнюю команду:

# Specify a base image
FROM node:18-alpine as build

# Set the working directory
WORKDIR /app

# Copy package.json and package-lock.json
COPY package*.json ./

# Install dependencies
RUN npm install

# Copy the rest of the application files
COPY ./ ./

# Build the React application
RUN npm run build

# Use a multi-stage build to keep the final image small
FROM nginx:alpine

# Install supervisor and Node.js
RUN apk add --no-cache supervisor nodejs npm

# Set the working directory
WORKDIR /app

# Copy nginx configuration
COPY nginx.conf /etc/nginx/nginx.conf

# Copy the built application from the previous stage
COPY --from=build /app/build /usr/share/nginx/html

# Copy the source files for the Node server and React app
COPY server.js ./server.js
COPY package*.json ./
COPY src/ ./src/
COPY public/ ./public/

# Copy node_modules from the build stage
COPY --from=build /app/node_modules ./node_modules

# Install production dependencies (this may be optional if all dependencies are already installed in the build stage)
RUN npm install --only=production

# Copy the supervisord configuration
COPY supervisord.conf /etc/supervisord.conf

# Expose ports
EXPOSE 80 3000 3030

# Command to run supervisord
CMD ["/usr/bin/supervisord", "-c", "/etc/supervisord.conf"]

В конце файла docker запускается файл mu supervisord.conf, npm start и node server.js, а также указывает вывод в некоторые файлы журналов:

[supervisord]
nodaemon=true

[program:nginx]
command=nginx -g 'daemon off;'
autostart=true
autorestart=true
stdout_logfile=/var/log/nginx.log
stderr_logfile=/var/log/nginx_err.log

[program:node-server]
command=node server.js
autostart=true
autorestart=true
stdout_logfile=/var/log/node_server.log
stderr_logfile=/var/log/node_server_err.log

[program:react-app]
command=npm start
directory=/app
autostart=true
autorestart=true
stdout_logfile=/var/log/react_app.log
stderr_logfile=/var/log/react_app_err.log

Я проверил свои журналы aws, и приложение-реагирование и сервер узлов, похоже, запустились нормально:

2024-07-03 09:04:58,002 CRIT Supervisor is running as root.  Privileges were not dropped because no user is specified in the config file.  If you intend to run as root, you can set user=root in the config file to avoid this message.
2024-07-03 09:04:58,006 INFO supervisord started with pid 1
2024-07-03 09:04:59,009 INFO spawned: 'nginx' with pid 7
2024-07-03 09:04:59,014 INFO spawned: 'node-server' with pid 8
2024-07-03 09:04:59,018 INFO spawned: 'react-app' with pid 9
2024-07-03 09:05:00,859 INFO success: nginx entered RUNNING state, process has stayed up for > than 1 seconds (startsecs)
2024-07-03 09:05:00,860 INFO success: node-server entered RUNNING state, process has stayed up for > than 1 seconds (startsecs)
2024-07-03 09:05:00,860 INFO success: react-app entered RUNNING state, process has stayed up for > than 1 seconds (startsecs)
2024-07-03 09:11:51,682 WARN received SIGTERM indicating exit request
2024-07-03 09:11:51,683 INFO waiting for nginx to die
2024-07-03 09:11:53,719 INFO stopped: nginx (exit status 0)

Я запустил nmap по своему URL-адресу, и кажется, что порт 3030 должен быть открыт. Как мне сделать запрос к нему в рабочей среде? Моя конфигурация nginx каким-то образом не обеспечивает доступ к порту?

$ nmap www.jermasearch.com
Warning: Nmap may not work correctly on Windows Subsystem for Linux.
For best performance and accuracy, use the native Windows build from https://nmap.org/download.html#windows.
Starting Nmap 7.80 ( https://nmap.org ) at 2024-07-03 02:30 PDT
Problem binding to interface , errno: 92
socket_bindtodevice: Protocol not available
Problem binding to interface , errno: 92
socket_bindtodevice: Protocol not available
NSOCK ERROR [0.6100s] mksock_bind_device(): Setting of SO_BINDTODEVICE failed (IOD #1): Protocol not available (92)
NSOCK ERROR [0.6110s] mksock_bind_device(): Setting of SO_BINDTODEVICE failed (IOD #2): Protocol not available (92)
Problem binding to interface , errno: 92
socket_bindtodevice: Protocol not available
...
Problem binding to interface , errno: 92
socket_bindtodevice: Protocol not available
Nmap scan report for www.jermasearch.com (54.177.88.67)
Host is up (0.16s latency).
Other addresses for www.jermasearch.com (not scanned): 54.176.90.55
rDNS record for 54.177.88.67: ec2-54-177-88-67.us-west-1.compute.amazonaws.com
Not shown: 998 filtered ports
PORT     STATE SERVICE
80/tcp   open  http
3030/tcp open  arepa-cas

Nmap done: 1 IP address (1 host up) scanned in 14.93 seconds

Я даже пытался убедиться, что мой файл nginx.conf поддерживает порт :3030:

worker_processes 1;

events {
  worker_connections 1024;
}

http {
  include mime.types;
  default_type application/octet-stream;

  sendfile on;
  keepalive_timeout 65;

  server {
    listen 80;

    location /internal-api {
        proxy_pass http://localhost:3030/;
        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-Proto $scheme;
    }

    location / {
      add_header 'Access-Control-Allow-Origin' '*';
      add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
      add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';

      root /usr/share/nginx/html;
      index index.html;
      try_files $uri $uri/ /index.html;
    }
  }
}

На чем работает мой server.js:

const express = require('express');
const cors = require('cors');
const app = express();
const port = 3030;

console.info('server.js staring')

// Enable CORS for all routes
app.use(cors());

app.get('/dbtest', (req, res) => {
  res.send('Hello from the Node.js server!');
});

app.listen(port, () => {
  console.info(`Server is running on port ${port}`);
});

🤔 А знаете ли вы, что...
React позволяет создавать пользовательские интерфейсы для веб-приложений.


1
57
1

Ответ:

Решено

Nmap показывает, что у вас открыты 2 порта: 80 и 3030:

Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-07-02 12:04 PDT
Nmap scan report for www.jermasearch.com (54.176.90.55)
Host is up (0.011s latency).
Other addresses for www.jermasearch.com (not scanned): 54.177.88.67
rDNS record for 54.176.90.55: ec2-54-176-90-55.us-west-1.compute.amazonaws.com
Not shown: 998 filtered tcp ports (no-response)
PORT     STATE SERVICE
80/tcp   open  http
3030/tcp open  arepa-cas

Nmap done: 1 IP address (1 host up) scanned in 10.46 seconds

Но кнопка получения данных обращается только к порту 80, а не к 3030. При доступе к порту 3030, похоже, отображается тот же вывод.

Судя по вашему файлу докера, порты 80, 3000 и 3030 должны быть открыты. Конфигурация вашего супервизора запускает CRA (а не сборку) на порту 3000, ваш бэкэнд на порту 3030 и nginx(80).

Nginx использует порт 80, но оба порта 80 и 3030 отображают выходные данные nginx. В вашей конфигурации nginx также указано, что к вашему бэкэнду должен иметь доступ /internal-data/, но возвращается ошибка 502 Bad Gateway, указывающая, что сервер не работает.

В ваших журналах также указано, что процессы node-server и react-app завершились вскоре после инициализации. Несмотря на то, что они запускаются, похоже, возникает ошибка.

react-app возвращает код ошибки 127, что означает, что сценарий не найден. Это может быть связано с тем, что вы не установили node_modules и пытаетесь использовать react-scripts. Этот процесс также является избыточным, поскольку nginx обслуживает встроенные файлы.

Приложение node-server завершает работу с кодом 1, который дает мало информации. Я подозреваю, что это может быть связано с тем, что nginx также использует порт 3030.

В целом это означает, что произошла ошибка: nginx использует порт 3030, сервер узла не может запуститься и, возможно, ваш API обращается к неправильному API.