diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index ea50a4d70fb9e332cebd0418e590abd38b8535b7..9a0b10980099a95f062d8961b685d7fca1b4e656 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -47,6 +47,18 @@ stages:
     - bash ./.build.ci.sh
     - bash ./.test.ci.sh
 
+# for k8s
+.build_template_k8s:
+  extends: .envvar_template
+  stage: build
+  tags:
+    - k8s # using k8s as runner
+  script:
+    - sed -i 's%^CVMFS_HTTP_PROXY=.*%CVMFS_HTTP_PROXY=http://squid-01.ihep.ac.cn:3128%' /etc/cvmfs/default.local
+    - for repo in sft.cern.ch geant4.cern.ch cepcsw.ihep.ac.cn; do [ -d "/cvmfs/$repo" ] || mkdir /cvmfs/$repo; sudo mount -t cvmfs $repo /cvmfs/$repo; done
+    - bash ./.build.ci.sh
+    - bash ./.test.ci.sh
+
 ##############################################################################
 # Build & Test in CentOS 7 (LCG)
 ##############################################################################
@@ -67,25 +79,29 @@ build:lcg:el7:
 # Build & Test in k8s (LCG)
 ##############################################################################
 build:lcg:el7:k8s:
-  extends: .build_template
+  extends: .build_template_k8s
   image: cepc/cepcsw-cvmfs:el7
-  tags:
-    - k8s # using k8s as runner
-  script:
-    - sed -i 's%^CVMFS_HTTP_PROXY=.*%CVMFS_HTTP_PROXY=http://squid-01.ihep.ac.cn:3128%' /etc/cvmfs/default.local
-    - for repo in sft.cern.ch geant4.cern.ch cepcsw.ihep.ac.cn; do [ -d "/cvmfs/$repo" ] || mkdir /cvmfs/$repo; sudo mount -t cvmfs $repo /cvmfs/$repo; done
-    - bash ./.build.ci.sh
-    - bash ./.test.ci.sh
+
+build:lcg:el9:k8s:
+  extends: .build_template_k8s
+  image: cepc/cepcsw-cvmfs:el9
+  variables:
+    CEPCSW_LCG_PLATFORM: x86_64-el9-gcc11-opt
+    CEPCSW_LCG_VERSION: 105.0.0
 
 ##############################################################################
 # Build the docs
 ##############################################################################
-build:docs:
-  stage: build 
-  tags:
-    - centos7
+build:docs:k8s:
+  extends: .build_template_k8s
+  image: cepc/cepcsw-cvmfs:el9
   script:
     - bash ./.build.ci.sh docs
   artifacts:
     paths:
       - docs/build/html/
+  rules:
+    - if: $CI_PIPELINE_SOURCE == "merge_request_event"
+      changes:
+      - docs/**/*
+
diff --git a/Dockerfile b/docker/el7/Dockerfile
similarity index 100%
rename from Dockerfile
rename to docker/el7/Dockerfile
diff --git a/docker/el9/Dockerfile b/docker/el9/Dockerfile
new file mode 100644
index 0000000000000000000000000000000000000000..150549c8104490748c78e4c8412e6ece532305c2
--- /dev/null
+++ b/docker/el9/Dockerfile
@@ -0,0 +1,67 @@
+##############################################################################
+# Docker image for CEPCSW
+##############################################################################
+
+# # Instruction
+# To build the docker image:
+#   $ docker build -t cepc/cepcsw:el9 .
+# Or with CVMFS installed also
+#   $ docker build -t cepc/cepcsw-cvmfs:el9 . --build-arg CVMFSMOD=INSIDE
+#
+# To publish it to DockerHub:
+#   $ docker push cepc/cepcsw:el9
+#   $ docker push cepc/cepcsw-cvmfs:el9
+
+FROM almalinux:9
+
+ARG CVMFSMOD
+
+RUN dnf install -y 'dnf-command(config-manager)'
+RUN dnf config-manager --set-enabled crb
+
+RUN dnf install -y epel-release \
+ && dnf install -y almalinux-release-devel \
+ && dnf install -y sudo \
+ && dnf install -y wget
+
+##############################################################################
+# CVMFS client
+##############################################################################
+# this will install the cvmfs client inside the container
+# User needs to run with --privileged mode.
+RUN if [ "$CVMFSMOD" = "INSIDE" ]; then \
+  sudo yum install -y https://ecsft.cern.ch/dist/cvmfs/cvmfs-release/cvmfs-release-latest.noarch.rpm \
+  && sudo yum install -y cvmfs \
+  && sudo mkdir /etc/cvmfs/keys/ihep.ac.cn \
+  && sudo curl -o /etc/cvmfs/keys/ihep.ac.cn/ihep.ac.cn.pub http://cvmfs-stratum-one.ihep.ac.cn/cvmfs/software/client_configure/ihep.ac.cn/ihep.ac.cn.pub \
+  && sudo curl -o /etc/cvmfs/domain.d/ihep.ac.cn.conf http://cvmfs-stratum-one.ihep.ac.cn/cvmfs/software/client_configure/ihep.ac.cn.conf \
+  && echo "CVMFS_REPOSITORIES='sft.cern.ch,cepcsw.ihep.ac.cn,geant4.cern.ch'" | sudo tee    /etc/cvmfs/default.local \
+  && echo "CVMFS_HTTP_PROXY=DIRECT"                                                 | sudo tee -a /etc/cvmfs/default.local \
+  && cat /etc/cvmfs/default.local \
+  && sudo mkdir -p /cvmfs/sft.cern.ch \
+  && sudo mkdir -p /cvmfs/cepcsw.ihep.ac.cn \
+  && sudo mkdir -p /cvmfs/geant4.cern.ch; \
+  fi
+
+# START Container:
+# # docker run  --privileged  --rm -i -t cepc/cepcsw-cvmfs:el9 /bin/bash
+# Due to the fuse issue, following commands need to be run inside container when --privileged is specified
+# $ mount -t cvmfs sft.cern.ch /cvmfs/sft.cern.ch
+# $ mount -t cvmfs geant4.cern.ch /cvmfs/geant4.cern.ch
+# $ mount -t cvmfs cepcsw.ihep.ac.cn /cvmfs/cepcsw.ihep.ac.cn
+
+##############################################################################
+# Install necessary packages
+##############################################################################
+
+RUN dnf install -y git \
+ && dnf install -y libglvnd-devel \
+ && dnf install -y mesa-libGLU-devel \
+ && dnf install -y libXmu-devel \
+ && dnf install -y motif-devel \
+ && dnf install -y make \
+ && dnf install -y gcc-c++ gcc binutils \
+ && dnf install -y libuuid-devel \
+ && dnf clean -y all \
+ && rm -rf /var/cache/dnf
+
diff --git a/docker/el9/build.sh b/docker/el9/build.sh
new file mode 100644
index 0000000000000000000000000000000000000000..05c02059889b9e81a7f278d8393da107db017ecd
--- /dev/null
+++ b/docker/el9/build.sh
@@ -0,0 +1,4 @@
+#!/bin/bash
+
+docker build -t cepc/cepcsw-cvmfs:el9 . --build-arg CVMFSMOD=INSIDE && docker push cepc/cepcsw-cvmfs:el9
+docker build -t cepc/cepcsw:el9 . && docker push cepc/cepcsw:el9