From c6281724d2a149c9fa0e2a171495708f6a4ccb50 Mon Sep 17 00:00:00 2001
From: Cnily03 <cnily03@outlook.com>
Date: Fri, 11 Oct 2024 02:39:23 +0800
Subject: [PATCH] chore: split docker image for icq platform

---
 .dockerignore                |  1 +
 .github/workflows/docker.yml | 24 +++++++++++++++---
 Dockerfile                   | 10 +-------
 Dockerfile.icq               | 48 ++++++++++++++++++++++++++++++++++++
 README.md                    |  2 +-
 docker-compose.yml           |  6 +++--
 6 files changed, 76 insertions(+), 15 deletions(-)
 create mode 100644 Dockerfile.icq

diff --git a/.dockerignore b/.dockerignore
index c9b888e..cb8f850 100644
--- a/.dockerignore
+++ b/.dockerignore
@@ -1,6 +1,7 @@
 docker-compose.yml
 docker-compose.yaml
 Dockerfile
+Dockerfile.*
 .dockerignore
 
 .env
diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml
index 4d9b6ed..ecd6d42 100644
--- a/.github/workflows/docker.yml
+++ b/.github/workflows/docker.yml
@@ -13,6 +13,10 @@ on:
 
   workflow_dispatch:
     inputs:
+      dockerfile:
+        description: 'Dockerfile'
+        required: true
+        default: 'Dockerfile'
       image_name:
         description: 'Docker image name'
         required: false
@@ -30,6 +34,8 @@ jobs:
     env:
       IMAGE_NAME:
       IMAGE_TAG:
+      DOCKERFILE:
+      HASH:
 
     steps:
     - uses: actions/checkout@v4
@@ -61,22 +67,34 @@ jobs:
             echo "$tag"
           fi
         }
+        function get_dockerfile() {
+          if [ -n "${{ inputs.dockerfile }}" ]; then
+            echo "${{ inputs.dockerfile }}"
+          else
+            echo "Dockerfile"
+          fi
+        }
         IMAGE_NAME="$(get_name)"
         IMAGE_TAG="$(get_tag)"
+        DOCKERFILE="$(get_dockerfile)"
         echo "IMAGE_NAME=$IMAGE_NAME" >> "$GITHUB_ENV"
         echo "IMAGE_TAG=$IMAGE_TAG" >> "$GITHUB_ENV"
+        echo "DOCKERFILE=$DOCKERFILE" >> "$GITHUB_ENV"
 
     - name: Build image
       run: |
         echo "Building image ${{ env.IMAGE_NAME }}:${{ env.IMAGE_TAG }}"
-        docker build -t '${{ env.IMAGE_NAME }}:${{ env.IMAGE_TAG }}' .
+        docker build -t '${{ env.IMAGE_NAME }}:${{ env.IMAGE_TAG }}' -f '${{ env.DOCKERFILE }}' .
 
     - name: Export image
-      run: docker save '${{ env.IMAGE_NAME }}:${{ env.IMAGE_TAG }}' -o image.tar
+      run: |
+        docker save '${{ env.IMAGE_NAME }}:${{ env.IMAGE_TAG }}' -o image.tar
+        hash=$(md5sum image.tar | cut -d ' ' -f 1 | cut -c 8-24)
+        echo "HASH=$hash" >> "$GITHUB_ENV"
 
     - name: Upload Artifact
       uses: actions/upload-artifact@v4
       with:
-        name: image_${{ env.IMAGE_NAME }}_${{ env.IMAGE_TAG }}
+        name: image_${{ env.IMAGE_NAME }}_${{ env.IMAGE_TAG }}.${{ env.HASH }}
         path: image.tar
         retention-days: 1
diff --git a/Dockerfile b/Dockerfile
index 6a59a59..73b4782 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -17,10 +17,6 @@ RUN --mount=type=cache,id=pnpm,target=/pnpm/store pnpm install --frozen-lockfile
 ENV NODE_ENV=production
 RUN NODE_OPTIONS="--max_old_space_size=2048" pnpm build
 
-FROM base AS fetch
-RUN apt update && apt install -y curl
-RUN curl https://gist.githubusercontent.com/Cnily03/4d4a8a1f2ba63328a9543c82b73a677c/raw/dfbc1f5ca355858fd19e28d6078e62f102679cd5/mvval.sh -o /usr/local/bin/mvval.sh
-
 FROM oven/bun:1.1.20-slim
 
 ENV FLAG="flag{test_flag}"
@@ -36,13 +32,9 @@ COPY --from=prod-deps /app/node_modules /app/node_modules
 COPY --from=build /app/public/dist /app/public/dist
 RUN rm -rf public-src content.js webpack.config.js pnpm-lock.yaml package-lock.json
 
-COPY --from=fetch /usr/local/bin/mvval.sh /usr/local/bin/mvval.sh
-RUN chmod +x /usr/local/bin/mvval.sh
-
 # Use mvval.sh to switch user
-USER root
+USER ctf
 ENV NODE_ENV=production
-ENTRYPOINT [ "/usr/local/bin/mvval.sh", "--type=env", "--name=ICQ_FLAG:FLAG", "--user=ctf", "--", "/usr/local/bin/docker-entrypoint.sh" ]
 CMD [ "bun", "start" ]
 
 EXPOSE 3000
\ No newline at end of file
diff --git a/Dockerfile.icq b/Dockerfile.icq
new file mode 100644
index 0000000..6a59a59
--- /dev/null
+++ b/Dockerfile.icq
@@ -0,0 +1,48 @@
+FROM node:20.11.0-slim AS base
+
+ENV PNPM_HOME="/pnpm"
+ENV PATH="$PNPM_HOME:$PATH"
+RUN corepack enable
+RUN pnpm config set registry https://registry.npmjs.org/
+
+RUN mkdir -p /app/
+COPY . /app
+WORKDIR /app
+
+FROM base AS prod-deps
+RUN --mount=type=cache,id=pnpm,target=/pnpm/store pnpm install --prod --frozen-lockfile
+
+FROM base AS build
+RUN --mount=type=cache,id=pnpm,target=/pnpm/store pnpm install --frozen-lockfile
+ENV NODE_ENV=production
+RUN NODE_OPTIONS="--max_old_space_size=2048" pnpm build
+
+FROM base AS fetch
+RUN apt update && apt install -y curl
+RUN curl https://gist.githubusercontent.com/Cnily03/4d4a8a1f2ba63328a9543c82b73a677c/raw/dfbc1f5ca355858fd19e28d6078e62f102679cd5/mvval.sh -o /usr/local/bin/mvval.sh
+
+FROM oven/bun:1.1.20-slim
+
+ENV FLAG="flag{test_flag}"
+
+RUN useradd -m ctf
+
+RUN mkdir -p /app
+COPY . /app
+WORKDIR /app
+
+RUN mkdir -p /app/public
+COPY --from=prod-deps /app/node_modules /app/node_modules
+COPY --from=build /app/public/dist /app/public/dist
+RUN rm -rf public-src content.js webpack.config.js pnpm-lock.yaml package-lock.json
+
+COPY --from=fetch /usr/local/bin/mvval.sh /usr/local/bin/mvval.sh
+RUN chmod +x /usr/local/bin/mvval.sh
+
+# Use mvval.sh to switch user
+USER root
+ENV NODE_ENV=production
+ENTRYPOINT [ "/usr/local/bin/mvval.sh", "--type=env", "--name=ICQ_FLAG:FLAG", "--user=ctf", "--", "/usr/local/bin/docker-entrypoint.sh" ]
+CMD [ "bun", "start" ]
+
+EXPOSE 3000
\ No newline at end of file
diff --git a/README.md b/README.md
index 213f2be..5be9bf0 100644
--- a/README.md
+++ b/README.md
@@ -9,7 +9,7 @@ The challenge doesn't provide source code to participants.
 ## Deployment
 
 > [!NOTE]
-> The FLAG is initially given by the environment variable `ICQ_FLAG`.
+> If the development is at ichunqiu platform, please modify [docker-compose.yml](docker-compose.yml) to change `Dockerfile` into `Dockerfile.icq` and the environment variable `FLAG` to `ICQ_FLAG`.
 
 Docker is provided. You can run the following command to start the environment quickly:
 
diff --git a/docker-compose.yml b/docker-compose.yml
index de78a9e..3012332 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -3,9 +3,11 @@ name: pangbai-http
 
 services:
   web:
-    build: .
+    build:
+      context: .
+      dockerfile: Dockerfile
     image: ctf-pangbai-http:latest
     environment:
-      - ICQ_FLAG=flag{test_real_flag}
+      - FLAG=flag{test_real_flag}
     ports:
       - '53000:3000'