node.js - 当 Docker 化时, Node 在 SSR 中提供空静态文件

标签 node.js docker dockerfile razzle

我有一个包含 razzle、react 和 typescript 的示例应用程序。 我试图将其进行 dockerize 并将其作为容器运行,但是虽然容器运行了,但静态文件是空的。

这是我的 Dockerfile

FROM node:alpine
RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app

ENV NODE_ENV production
ENV RAZZLE_CUSTOM_VARIABLE xxxxx

COPY package.json .

RUN npm install --production

COPY build ./build

EXPOSE 3000

CMD [ "node", "build/server.js" ]

我使用 docker build --tag=my-app:0.0.1 . 创建图像

我收到以下警告(不确定是否与我的问题相关):

SECURITY WARNING: You are building a Docker image from Windows against a non-Windows Docker host. All files and directories added to build context will have '-rwxr-xr-x' permissions. It is recommended to double check and reset permissions for sensitive files and directories.

最后我运行我的容器,例如:docker run -p 3001:3000 my-app:0.0.1并且它执行正确。

当我访问localhost:30001时我可以看到我的 react 应用程序,但没有样式。 例如,我可以看到 http://localhost:3003/static/css/bundle.b1e53d9a.css正在送达,但空着 还有http://localhost:3003/static/js/bundle.fd36658a.js是空的,这一定是问题所在。问题是为什么?

如果我做 node build/server.js在我的本地文件系统上,我可以在 localhost:30001 上看到提供的 React 应用程序与样式正常配合。

我是否遗漏了什么或做错了什么?

我对 docker 和 Node js 太陌生,无法自己弄清楚。

更新 1:如果需要,这是我的 package.json

{
  "name": "llevatelo-web",
  "version": "0.1.0",
  "license": "MIT",
  "scripts": {
    "start": "razzle start",
    "build": "razzle build",
    "test": "razzle test --env=jsdom",
    "start:prod": "NODE_ENV=production node build/server.js"
  },
  "dependencies": {
    "express": "4.17.1",
    "razzle": "3.0.0",
    "react": "16.9.0",
    "react-dom": "16.9.0",
    "react-router-dom": "5.0.1"
  },
  "devDependencies": {
    "@testing-library/jest-dom": "^4.0.0",
    "@testing-library/react": "^8.0.9",
    "@types/express": "^4.17.0",
    "@types/jest": "^24.0.17",
    "@types/react": "^16.9.0",
    "@types/react-dom": "^16.8.5",
    "@types/react-router-dom": "^4.3.4",
    "@types/webpack-env": "^1.14.0",
    "eslint": "^6.1.0",
    "razzle-plugin-typescript": "^3.0.0",
    "ts-jest": "^24.0.2",
    "typescript": "^3.5.3"
  },
  "jest": {
    "transform": {
      "\\.(ts|tsx)$": "ts-jest",
      "\\.css$": "<rootDir>/node_modules/razzle/config/jest/cssTransform.js",
      "^(?!.*\\.(js|jsx|css|json)$)": "<rootDir>/node_modules/razzle/config/jest/fileTransform.js"
    },
    "testMatch": [
      "<rootDir>/src/**/__tests__/**/*.(ts|js)?(x)",
      "<rootDir>/src/**/?(*.)(spec|test).(ts|js)?(x)"
    ],
    "moduleFileExtensions": [
      "ts",
      "tsx",
      "js",
      "json"
    ],
    "collectCoverageFrom": [
      "src/**/*.{js,jsx,ts,tsx}"
    ]
  }
}

最佳答案

您应该在图像上构建应用程序,而不是在 Windows 上构建并复制它。

您可以稍后使用 multi stage builds 优化大小

完整的 Dockerfile:

FROM node:alpine as builder
RUN mkdir -p /app
WORKDIR /app
ENV NODE_ENV production

COPY package.json ./
RUN npm install --production

COPY src ./src
COPY public ./public
RUN npm run build


FROM node:alpine
RUN mkdir -p /app
WORKDIR /app
ENV NODE_ENV production

COPY --from=builder /app/node_modules ./node_modules
COPY --from=builder /app/build ./build

EXPOSE 3000

CMD [ "node", "build/server.js" ]

通过多阶段构建,razzle 示例应用程序的图像大小从 290MB 下降到 267MB。

在 Windows 上经过全面测试, Assets 服务正确。

关于node.js - 当 Docker 化时, Node 在 SSR 中提供空静态文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57445601/

相关文章:

node.js - 如何在 http 模块中收听没有 '/' 的路径

docker - 在 Dockerfile 中运行与手动运行时存在不同的问题。出了什么问题?

docker - 尝试在 Windows 2016 Core 容器中创建计划任务时出错

node.js - GeoJSON 在 Node.js 中与 Mongoose/Mongodb 配合使用

node.js - 在 socket.io 中使用 RedisStore 的示例

javascript - 找不到模块 : Error: Cannot resolve module 'fs' in

spring - 带有Spring Boot 2的Docker Stack “configs”

vagrant - 无法通过 Docker 和 Vagrant 安装 MariaDB

bash - 如何为 docker 容器订购 Kafka 启动 shell 脚本?