diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 175c0c39e117240dd3fc6bbc7295ba799c1acba2..5e6571e5da3c823addb9c674d0b15814529efc9e 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -1,4 +1,5 @@
 variables:
+  NODE_IMAGE: node:19-bullseye
   DOCKER_HOST: "tcp://docker-dind.gitlab-suma:2375"
   DOCKER_BUILD_IMAGE: docker:20.10.15
   DOCKER_IMAGE_NAME: keymanager
@@ -11,9 +12,28 @@ stages:
   - build
   - deploy
 
+npm_deps:
+  stage: build
+  image: ${NODE_IMAGE}
+  variables:
+    npm_config_cache: /app/.npm
+  cache:
+    key: npm-cache
+    paths:
+      - .npm
+  artifacts:
+    public: false
+    paths:
+      - node_modules
+  script:
+    - npm i
+
 build:
   stage: build
   image: ${DOCKER_BUILD_IMAGE}
+  needs:
+    - job: npm_deps
+      artifacts: true
   before_script:
     - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
   script:
diff --git a/build/pass/Dockerfile b/build/pass/Dockerfile
index e289bc854c357f47078424aec89648fa3e2e0a29..93680b4ace804e09d1075250b2a15fdfc9ba209e 100644
--- a/build/pass/Dockerfile
+++ b/build/pass/Dockerfile
@@ -1,8 +1,15 @@
-FROM node:19-bullseye
+FROM node:19-bullseye as development
 
 RUN mkdir /data && chown 1000:1000 /data
 VOLUME ["/data"]
 
 USER 1000
+WORKDIR /app
 
-CMD [ "bash", "-c", "npm i && npm run dev"]
\ No newline at end of file
+CMD [ "bash", "-c", "npm i && npm run dev"]
+
+FROM development as production
+
+ADD pass /app
+
+CMD ["npm", "start"]
\ No newline at end of file
diff --git a/docker-compose.yml b/docker-compose.yml
index 8a509bd49acb16e6751ecfae90d94ada84e2985e..80a6c465e16d4f47285e4f1855f94bb0a6f31d3b 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -17,6 +17,7 @@ services:
   express:
     build:
       context: ./build/pass
+      target: development
     networks:
       - metager
     environment: