使用 Docker 和 PM2 时在浏览器中自动重新加载 React 应用程序

问题描述 投票:0回答:1

当我对 src/App.js 文件进行更改时,我一直在尝试在 http://localhost:3000 上的浏览器中实现 React 应用程序的自动重新加载。我使用

docker-compose
在 Docker 容器内运行我的应用程序,并使用 PM2 对其进行管理。 您能否建议一个解决方案或找出任何缺失的配置?

项目结构

project_root/
├── app/                  # Django app backend code
│   ├── app/
│   │   ├── settings.py        
│   └── manage.py         
├── frontend/             # React app frontend code
│   ├── node_modules/     
│   ├── public/            
│   ├── src/                 
│   │   ├── App.js
│   │   └── ...
│   ├── templates/            
│   ├── ecosystem.conf.js
│   ├── package-lock.json
│   ├── package.json          
│   ├── Dockerfile.frontend   
│   └── ...
├── Dockerfile          
├── docker-compose.yml      
└── ...

Package.json 文件:

{
  "name": "frontend",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "@testing-library/jest-dom": "^5.17.0",
    "@testing-library/react": "^13.4.0",
    "@testing-library/user-event": "^13.5.0",
    "react": "^18.2.0",
    "react-dom": "^18.2.0",
    "react-scripts": "5.0.1",
    "web-vitals": "^2.1.4",
    "pm2": "5.3.0"
  },
  "devDependencies": {
    "concurrently": "8.2.0",
    "babel-eslint": "^10.1.0",
    "eslint": "8.47.0"
  },
  "scripts": {
    "lint": "npx eslint --fix --ext .js,.jsx .",
    "server": "pm2 start src/App.js --watch npm -- start",
    "react": "export SET NODE_OPTIONS=--openssl-legacy-provider && CHOKIDAR_USEPOLLING=true react-scripts start",
    "start": "concurrently \"npm run lint\" \"npm run react\" \"npm run server \" ",
    "build": "export SET NODE_OPTIONS=--openssl-legacy-provider && react-scripts build",
    "test": "export SET NODE_OPTIONS=--openssl-legacy-provider && react-scripts test",
    "eject": "export SET NODE_OPTIONS=--openssl-legacy-provider && react-scripts eject"
  },
  "eslintConfig": {
    "extends": [
      "react-app",
      "react-app/jest"
    ]
  },
  "browserslist": {
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  }
}

Dockerfile.frontend 文件:

FROM node:18.3.0-alpine
WORKDIR /frontend
ENV PATH /frontend/node_modules/.bin:$PATH

COPY ./frontend/package*.json ./
COPY ./frontend/ecosystem.config.js ./

RUN npm install --silent && \
    npm install [email protected] -g --silent && \
    npm install pm2 -g && \
    npm install eslint babel-eslint --save-dev && \
    npm i -g concurrently && \
    npm ci \
    && npm cache clean --force \
    && mv /frontend/node_modules /node_modules

COPY ./frontend ./
EXPOSE 3000
RUN ls -al -R

CMD ["pm2", "reload", "all", \
     "pm2-runtime", "npm", "run", "start", "ecosystem.config.js", "--watch"]

ecosystem.config.js文件:

module.exports = {
    apps : [{
      name: "app",
      script: "./src/App.js",
      "watch": true,
      "autorestart": true,
      "ignore_watch": ["node_modules"],
      env: {
        NODE_ENV: "development",
      },
      env_production: {
        NODE_ENV: "production",
      }
    }]
}

docker-compose 文件:

version: "3.9"
services:
  app: # pass
  db: # pass
  frontend:
    container_name: frontend-dev
    build:
      context: . 
      dockerfile: ./frontend/Dockerfile.frontend
    restart: always
    ports:
      - 3000:3000
    volumes:
      - ./frontend:/app
      - ./frontend/node_modules:/app/node_modules
    environment:
      - CHOKIDAR_USEPOLLING=true
      - WATCHPACK_POLLING=true
      - FAST_REFRESH=true
      - WDS_SOCKET_PORT=0
      - NODE_ENV=development
      - PORT=3000
    command: ["npm", "run", "start"]

我感谢任何解决此问题的帮助或建议。先谢谢你了!

运行后

日志

docker-compose up

frontend-dev         | \> [email protected] start
frontend-dev         | \> concurrently "npm run lint" "npm run react" "npm run server "
frontend-dev         | \[1\]
frontend-dev         |
frontend-dev         | \[1\] \> [email protected] react
frontend-dev         | \[1\] \> export SET NODE_OPTIONS=--openssl-legacy-provider && CHOKIDAR_USEPOLLING=true react-scripts start
frontend-dev         | \[1\]
frontend-dev         |
frontend-dev         | \[0\]
frontend-dev         | \[0\] \> [email protected] lint
frontend-dev         | \[0\] \> npx eslint --fix --ext .js,.jsx .
frontend-dev         | \[0\]
frontend-dev         | \[2\]
frontend-dev         |
frontend-dev         | \[2\] \> [email protected] server
frontend-dev         | \[2\] \> pm2 start src/App.js --watch npm -- start
frontend-dev         | \[2\]
frontend-dev         | \[2\]                         -------------
frontend-dev         | \[2\]
frontend-dev         | \[2\]                           Runtime Edition
frontend-dev         | \[2\]
frontend-dev         | \[2\]         PM2 is a Production Process Manager for Node.js applications
frontend-dev         | \[2\]                      with a built-in Load Balancer.
frontend-dev         | \[2\]
frontend-dev         | \[2\]                 Start and Daemonize any application:
frontend-dev         | \[2\]                 $ pm2 start app.js
frontend-dev         | \[2\]
frontend-dev         | \[2\]                 Load Balance 4 instances of api.js:
frontend-dev         | \[2\]                 $ pm2 start api.js -i 4
frontend-dev         | \[2\]
frontend-dev         | \[2\]                 Monitor in production:
frontend-dev         | \[2\]                 $ pm2 monitor
frontend-dev         | \[2\]
frontend-dev         | \[2\]                 Make pm2 auto-boot at server restart:
frontend-dev         | \[2\]                 $ pm2 startup
frontend-dev         | \[2\]
frontend-dev         | \[2\]                 To go further checkout:
frontend-dev         | \[2\]                 http://pm2.io/
frontend-dev         | \[2\]
frontend-dev         | \[2\]
frontend-dev         | \[2\]                         -------------
frontend-dev         | \[2\]
frontend-dev         |
frontend-dev         | \[2\]
frontend-dev         | \[PM2\] Spawning PM2 daemon with pm2_home=/root/.pm2
app-dev              | Waiting for database...
app-dev              | Database available!
frontend-dev         | \[2\]
frontend-dev         | \[PM2\] PM2 Successfully daemonized
frontend-dev         | \[2\]
frontend-dev         | \[PM2\] Starting /frontend/src/App.js in fork_mode (1 instance)
frontend-dev         | \[2\] \[PM2\] Done.
frontend-dev         | \[2\]
frontend-dev         | ┌────┬────────┬─────────────┬─────────┬─────────┬──────────┬────────┬──────┬───────────┬──────────┬──────────┬──────────┬──────────┐
frontend-dev         | \[2\] │ id │ name   │ namespace   │ version │ mode    │ pid      │ uptime │ ↺    │ status    │ cpu      │ mem      │ user     │ watching │
frontend-dev         | \[2\] ├────┼────────┼─────────────┼─────────┼─────────┼──────────┼────────┼──────┼───────────┼──────────┼──────────┼──────────┼──────────┤
frontend-dev         | \[2\] │ 0  │ App    │ default     │ 0.1.0   │ fork    │ 132      │ 0s     │ 0    │ online    │ 0%       │ 25.5mb   │ root     │ enabled  │
frontend-dev         | \[2\] └────┴────────┴─────────────┴─────────┴─────────┴──────────┴────────┴──────┴───────────┴──────────┴──────────┴──────────┴──────────┘
frontend-dev         | \[2\] npm run server  exited with code 0
app-dev              | Operations to perform:
app-dev              |   Apply all migrations: admin, auth, authtoken, contenttypes, core, sessions, token_blacklist
app-dev              | Running migrations:
app-dev              |   No migrations to apply.
frontend-dev         | \[1\]
frontend-dev         | (node:94) \[DEP_WEBPACK_DEV_SERVER_ON_AFTER_SETUP_MIDDLEWARE\] DeprecationWarning: 'onAfterSetupMiddleware' option is deprecated. Please use the 'setupMiddlewares' option.
frontend-dev         | \[1\] (Use `node --trace-deprecation ...` to show where the warning was created)
frontend-dev         | \[1\] (node:94) \[DEP_WEBPACK_DEV_SERVER_ON_BEFORE_SETUP_MIDDLEWARE\] DeprecationWarning: 'onBeforeSetupMiddleware' option is deprecated. Please use the 'setupMiddlewares' option.
frontend-dev         | \[1\] Starting the development server...
frontend-dev         | \[1\]
app-dev              | Watching for file changes with StatReloader
app-dev              | Performing system checks...
app-dev              |
app-dev              |
app-dev              | System check identified no issues (0 silenced).
frontend-dev         | \[0\] One of your dependencies, babel-preset-react-app, is importing the
frontend-dev         | \[0\] "@babel/plugin-proposal-private-property-in-object" package without
frontend-dev         | \[0\] declaring it in its dependencies. This is currently working because
frontend-dev         | \[0\] "@babel/plugin-proposal-private-property-in-object" is already in your
frontend-dev         | \[0\] node_modules folder for unrelated reasons, but it may break at any time.
frontend-dev         | \[0\]
frontend-dev         | \[0\] babel-preset-react-app is part of the create-react-app project, which
frontend-dev         | \[0\] is not maintianed anymore. It is thus unlikely that this bug will
frontend-dev         | \[0\] ever be fixed. Add "@babel/plugin-proposal-private-property-in-object" to
frontend-dev         | \[0\] your devDependencies to work around this error. This will make this message
frontend-dev         | \[0\] go away.
frontend-dev         | \[0\]
frontend-dev         | \[0\] npm run lint exited with code 0
app-dev              | August 24, 2023 - 02:23:11
app-dev              | Django version 4.2.4, using settings 'app.settings'
app-dev              | Starting development server at http://0.0.0.0:8000/
app-dev              | Quit the server with CONTROL-C.
app-dev              |
app-dev              |
frontend-dev         | \[1\] One of your dependencies, babel-preset-react-app, is importing the
frontend-dev         | \[1\] "@babel/plugin-proposal-private-property-in-object" package without
frontend-dev         | \[1\] declaring it in its dependencies. This is currently working because
frontend-dev         | \[1\] "@babel/plugin-proposal-private-property-in-object" is already in your
frontend-dev         | \[1\] node_modules folder for unrelated reasons, but it may break at any time.
frontend-dev         | \[1\]
frontend-dev         | \[1\] babel-preset-react-app is part of the create-react-app project, which
frontend-dev         | \[1\] is not maintianed anymore. It is thus unlikely that this bug will
frontend-dev         | \[1\] ever be fixed. Add "@babel/plugin-proposal-private-property-in-object" to
frontend-dev         | \[1\] your devDependencies to work around this error. This will make this message
frontend-dev         | \[1\] go away.
frontend-dev         | \[1\]
frontend-dev         | \[1\] Compiled successfully!
frontend-dev         | \[1\]
frontend-dev         | \[1\] You can now view frontend in the browser.
frontend-dev         | \[1\]
frontend-dev         | \[1\]   Local:            http://localhost:3000
frontend-dev         | \[1\]   On Your Network:  http://172.27.0.3:3000
frontend-dev         | \[1\]
frontend-dev         | \[1\] Note that the development build is not optimized.
frontend-dev         | \[1\] To create a production build, use npm run build.
frontend-dev         | \[1\]
frontend-dev         | \[1\] webpack compiled successfully
frontend-dev         | \[1\] Compiling...
frontend-dev         | \[1\] Compiled successfully!
frontend-dev         | \[1\] webpack compiled successfullyuccessfully\`
reactjs docker pm2 hot-reload
1个回答
0
投票

您已经非常接近了,但您的

docker-compose
需要更新为以下内容

volumes:
      - .:/frontend  # whatever is defined WORKDIR in Dockerfile
      - ./frontend/node_modules:/frontend/node_modules  # unrelated but doesn't hurt to update

这意味着当前目录中的所有内容都将与您在 Dockerfile 中定义的目录同步

WORKDIR
,因此在 Docker 容器内运行的应用程序能够实际获取更新的文件,通知文件监视程序,重新转译应用程序,并重新加载页面。

© www.soinside.com 2019 - 2024. All rights reserved.