From f729515f8edbde28096476c35181a57bd9e7205f Mon Sep 17 00:00:00 2001 From: jaywcjlove <398188662@qq.com> Date: Tue, 19 Sep 2023 21:09:37 +0800 Subject: [PATCH] feat: add script & update dockerfile. --- .dockerignore | 17 +++-------- .github/workflows/ci.yml | 27 +++++++++-------- Dockerfile | 65 ++++++++++++++++++++++++++++++++++------ config.js | 65 ++++++++++++++++++++++++++++++++++++++++ next.config.js | 8 +++++ scripts.mjs | 13 ++++++++ 6 files changed, 161 insertions(+), 34 deletions(-) create mode 100644 config.js create mode 100644 next.config.js create mode 100644 scripts.mjs diff --git a/.dockerignore b/.dockerignore index 5dd9905..72e9aa4 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,16 +1,7 @@ -# 忽略不需要复制到Docker镜像中的文件和目录 - -# 忽略开发环境依赖 +Dockerfile +.dockerignore node_modules - -# 忽略构建产物 +npm-debug.log +README.md .next - -# 忽略日志文件 -*.log - -# 忽略临时文件 -*.tmp - -# 忽略版本控制文件 .git \ No newline at end of file diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ac04000..4632453 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -12,34 +12,37 @@ jobs: steps: - name: Checkout code uses: actions/checkout@v4 + with: + path: 'config' - name: Checkout zh-hans.react.dev code uses: actions/checkout@v4 with: repository: reactjs/zh-hans.react.dev - path: 'app' - name: Set up Node.js uses: actions/setup-node@v3 with: node-version: 18 - - name: Install dependencies - run: yarn install - working-directory: app + # - name: Install dependencies + # run: yarn install + # working-directory: app - - name: Build Next.js app - run: npm run build - working-directory: app + # - name: Build Next.js app + # run: npm run build + # working-directory: app + - run: node config/scripts.mjs - run: ls -al - working-directory: app + # working-directory: app - - name: Install yarn - run: npm install -g yarn + # - name: Install yarn + # run: npm install -g yarn + - run: cp config/Dockerfile ./ + - run: cp config/.dockerignore ./ - run: ls -al - - run: cp Dockerfile ./app # Create Docker Image - uses: docker/setup-buildx-action@v3 @@ -53,6 +56,6 @@ jobs: uses: docker/build-push-action@v5 with: push: true - context: ./app/ + context: . platforms: linux/amd64,linux/arm64 tags: ${{ secrets.DOCKER_USER }}/zh-hans.react.dev:latest diff --git a/Dockerfile b/Dockerfile index 58476c3..7926820 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,25 +1,72 @@ -FROM node:18 +FROM node:18-alpine AS base -# 设置工作目录 +# Install dependencies only when needed +FROM base AS deps +# Check https://github.com/nodejs/docker-node/tree/b4117f9333da4138b03a546ec926ef50a31506c3#nodealpine to understand why libc6-compat might be needed. +RUN apk add --no-cache libc6-compat WORKDIR /app -# 复制 package.json 和 package-lock.json 文件到工作目录 -COPY package*.json ./ +# Install dependencies based on the preferred package manager +COPY package.json yarn.lock* package-lock.json* pnpm-lock.yaml* ./ -# 安装项目依赖 -# RUN yarn install +RUN \ + if [ -f yarn.lock ]; then yarn --frozen-lockfile; \ + elif [ -f package-lock.json ]; then npm ci; \ + elif [ -f pnpm-lock.yaml ]; then yarn global add pnpm && pnpm i --frozen-lockfile; \ + else echo "Lockfile not found." && exit 1; \ + fi + +# Rebuild the source code only when needed +FROM base AS builder +WORKDIR /app + + +COPY --from=deps /app/node_modules ./node_modules # 复制项目文件到工作目录 COPY . . -# 构建 Next.js 应用 +# Next.js collects completely anonymous telemetry data about general usage. +# Learn more here: https://nextjs.org/telemetry +# Uncomment the following line in case you want to disable telemetry during the build. +# ENV NEXT_TELEMETRY_DISABLED 1 + +RUN yarn build + +# If using npm comment out above and use below instead # RUN npm run build +# Production image, copy all the files and run next +FROM base AS runner +WORKDIR /app + # 设置环境变量 ENV NODE_ENV production +# Uncomment the following line in case you want to disable telemetry during runtime. +# ENV NEXT_TELEMETRY_DISABLED 1 + +RUN addgroup --system --gid 1001 nodejs +RUN adduser --system --uid 1001 nextjs + + +COPY --from=builder /app/public ./public + +# Set the correct permission for prerender cache +RUN mkdir .next +RUN chown nextjs:nodejs .next + +# Automatically leverage output traces to reduce image size +# https://nextjs.org/docs/advanced-features/output-file-tracing +COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./ +COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static + +USER nextjs -# 暴露容器的 3000 端口 EXPOSE 3000 +ENV PORT 3000 +# set hostname to localhost +ENV HOSTNAME "0.0.0.0" + # 运行 Next.js 应用 -CMD ["npm", "start"] \ No newline at end of file +CMD ["node", "server.js"] \ No newline at end of file diff --git a/config.js b/config.js new file mode 100644 index 0000000..c7c4a5a --- /dev/null +++ b/config.js @@ -0,0 +1,65 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + */ + +/** + * @type {import('next').NextConfig} + **/ +const nextConfig = { + output: 'standalone', + pageExtensions: ['jsx', 'js', 'ts', 'tsx', 'mdx', 'md'], + reactStrictMode: true, + experimental: { + // TODO: Remove after https://github.com/vercel/next.js/issues/49355 is fixed + appDir: false, + scrollRestoration: true, + legacyBrowsers: false, + }, + env: {}, + webpack: (config, {dev, isServer, ...options}) => { + if (process.env.ANALYZE) { + const {BundleAnalyzerPlugin} = require('webpack-bundle-analyzer'); + config.plugins.push( + new BundleAnalyzerPlugin({ + analyzerMode: 'static', + reportFilename: options.isServer + ? '../analyze/server.html' + : './analyze/client.html', + }) + ); + } + + // Don't bundle the shim unnecessarily. + config.resolve.alias['use-sync-external-store/shim'] = 'react'; + + const {IgnorePlugin, NormalModuleReplacementPlugin} = require('webpack'); + config.plugins.push( + new NormalModuleReplacementPlugin( + /^raf$/, + require.resolve('./src/utils/rafShim.js') + ), + new NormalModuleReplacementPlugin( + /^process$/, + require.resolve('./src/utils/processShim.js') + ), + new IgnorePlugin({ + checkResource(resource, context) { + if ( + /\/eslint\/lib\/rules$/.test(context) && + /\.\/[\w-]+(\.js)?$/.test(resource) + ) { + // Skips imports of built-in rules that ESLint + // tries to carry into the bundle by default. + // We only want the engine and the React rules. + return true; + } + return false; + }, + }) + ); + + return config; + }, +}; + +module.exports = nextConfig; diff --git a/next.config.js b/next.config.js new file mode 100644 index 0000000..b78277e --- /dev/null +++ b/next.config.js @@ -0,0 +1,8 @@ +const config = require('./config'); + +const nextConfig = { + ...config, + output: 'standalone', +} + +module.exports = nextConfig; \ No newline at end of file diff --git a/scripts.mjs b/scripts.mjs new file mode 100644 index 0000000..f71a223 --- /dev/null +++ b/scripts.mjs @@ -0,0 +1,13 @@ +import fs from 'node:fs/promises'; +import path from 'node:path'; + +;(async () => { + try { + const nextPath = path.resolve('../next.config.js'); + console.log('nextPath', nextPath); + await fs.rename(nextPath, nextPath.replace('next.config.js', 'config.js')); + await fs.copyFile('./next.config.js', nextPath); + } catch (error) { + console.error(error); + } +})(); \ No newline at end of file