节点在 dockerized 时在 SSR 中提供空静态文件
Node serves empty static files in a SSR when dockerized
我有一个带有 razzle、react 和 typescript 的示例应用程序。
我正在尝试 docker 化它并 运行 它作为一个容器,但是尽管容器 运行s,静态文件是空的。
这是我的 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 和节点 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 上进行全面测试,资产已正确投放。
我有一个带有 razzle、react 和 typescript 的示例应用程序。 我正在尝试 docker 化它并 运行 它作为一个容器,但是尽管容器 运行s,静态文件是空的。
这是我的 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 和节点 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 上进行全面测试,资产已正确投放。