我有一个 React 应用程序 (SPA),我使用 docker 创建一个图像,该图像被添加到 gitlab 容器注册表以进行部署。 该代码使用
serve -s
提供静态文件
在本地测试时一切都很好,但在移动到 prod(ec2 实例)时却不是
对这一切还很陌生所以希望有人能指出我正确的方向
Docker文件:
FROM node:lts-alpine3.16 as builder
WORKDIR /usr/src/app
COPY package*.json ./
RUN npm ci --silent
RUN npm install [email protected] -g --silent
COPY . ./
RUN npm run production
RUN ls "./build"
RUN pwd
FROM node:lts-alpine3.16 as production
WORKDIR /usr/src/app
RUN npm install serve -g
COPY --from=builder /usr/src/app/build ./
ENTRYPOINT ["serve", "-s", "./", "-l", "3000", "-n"]
#docker build --progress=plain -f Dockerfile -t merchant .
#docker run -p 3000:3000 merchant
gitlab-ci.yml 只是使用“上传”阶段推送到容器注册表
stages:
- test
- upload
before_script:
- export TIMESTAMP=$(date +%Y-%m-%d-%H.%M.%S)
- export RELEASE=$(echo $CI_BUILD_REF_SLUG | sed "s/[^[[:alnum:]]//g")
- export BRANCH=$(echo $CI_COMMIT_TITLE | sed 's/.*\([0-9]*CW*-[0-9][0-9][0-9][0-9]*\).*/\1/')
test:
image: node:lts-alpine3.16
stage: test
script:
- npm ci --silent
- npm run test
- echo "success"
upload:
stage: upload
image: docker:latest
rules:
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
services:
- docker:20.10.16-dind-alpine3.16
script:
- docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" $CI_REGISTRY
- TAG="$CI_REGISTRY_IMAGE:latest"
- docker build --cache-from $TAG -t "$TAG" -t "$CI_REGISTRY_IMAGE:$TIMESTAMP-$BRANCH" -f Dockerfile .
- docker push "$CI_REGISTRY_IMAGE" --all-tags
测试我使用的图像
docker build --no-cache --progress=plain -f Dockerfile -t merchant .
docker run -d --name merchant --env-file ./.env -p 3000:3000 -it --rm merchant
我根据 stakeoverflow 上的一些建议创建了一个 .htaccess 文件,如下所示
RewriteEngine On
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -f [OR]
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -d
RewriteRule ^ - [L]
RewriteRule ^ /index.html [L]
package.json
"scripts": {
"start": "react-scripts start",
"production": "tsc --noEmit && rimraf ./build && DISABLE_ESLINT_PLUGIN=true react-scripts build",
"build": "cp .env.${REACT_APP_ENV} .env && tsc --noEmit && rimraf ./build && sh -ac '. ./.env.${REACT_APP_ENV}; DISABLE_ESLINT_PLUGIN=true react-scripts build'",
docker 容器内部
docker exec -it merchant sh
/usr/src/app # ls -la
total 44
drwxr-xr-x 1 root root 4096 Mar 22 19:28 .
drwxr-xr-x 1 root root 4096 Mar 22 18:55 ..
-rw-r--r-- 1 root root 164 Mar 22 19:28 .htaccess
-rw-r--r-- 1 root root 20 Mar 22 19:28 _redirects
-rw-r--r-- 1 root root 1329 Mar 22 19:28 asset-manifest.json
-rw-r--r-- 1 root root 7276 Mar 22 19:28 favicon.ico
-rw-r--r-- 1 root root 946 Mar 22 19:28 index.html
-rw-r--r-- 1 root root 180 Mar 22 19:28 manifest.json
-rw-r--r-- 1 root root 68 Mar 22 19:28 robots.txt
drwxr-xr-x 5 root root 4096 Mar 22 19:28 static
/usr/src/app # cd static
/usr/src/app/static # ls -ll
total 12
drwxr-xr-x 2 root root 4096 Mar 22 19:28 css
drwxr-xr-x 2 root root 4096 Mar 22 19:28 js
drwxr-xr-x 2 root root 4096 Mar 22 19:28 media
在 chrome 中点击 url 时,我在控制台中没有收到任何错误,但我总是会创建一个 404 页面作为反应中的全部,而且我的路线都不起作用!
当访问一个不存在的页面(我的页面)时,我得到 200 访问现有页面时出现 304 但是全部捕获被触发并且我自己的反应 404 页面显示在浏览器中