diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
new file mode 100644
index 0000000000000000000000000000000000000000..a8d68e24bb8d4fb7cbcb0815fa314099a30580d7
--- /dev/null
+++ b/.gitlab-ci.yml
@@ -0,0 +1,119 @@
+default:
+  image: debian-bookworm:latest
+  tags:
+    - netvs
+cache:
+  key:
+    files:
+      - requirements.txt
+  paths:
+    - venv/
+before_script:
+  ## dependencies
+  - apt-get update -y
+  - command -v curl || apt-get -y install curl
+  - command -v git || apt-get -y install git
+  - if [ $CI_JOB_STAGE != "deploy" ]; then command -v pip3 || (apt-get update -y && apt-get install -y python3-pip); fi
+  - if [ $CI_JOB_STAGE != "deploy" ]; then (apt-get update -y && apt-get install -y python3-venv && python3 -m venv venv && source venv/bin/activate); fi
+  - export NETDB_VERSION="4.1"
+stages:
+  - lint
+  - deploy
+
+
+middleware-lint:
+  stage: lint
+  script:
+    - command -v venv/bin/flake8 || venv/bin/pip3 install flake8
+    - venv/bin/flake8 . --exclude venv/ --count --show-source --statistics --max-line-length=120
+  needs: []
+  allow_failure: false
+  interruptible: true
+
+middleware-audit:
+  stage: lint
+  script:
+    - 'command -v ssh-agent || ( apt-get install openssh-client -y )'
+    - eval $(ssh-agent -s)
+    - echo "${SSH_PRIVATE_KEY}" | base64 -d | ssh-add -
+    - mkdir -p ~/.ssh
+    - chmod 700 ~/.ssh
+    - echo "$SSH_KNOWN_HOSTS" > ~/.ssh/known_hosts
+    - chmod 644 ~/.ssh/known_hosts
+    - apt-get -y install libpq-dev build-essential
+    - venv/bin/pip3 install pip-audit
+    - venv/bin/pip-audit -r <(grep -vE "net-api-generator|python3.*packages.pgsql.*" requirements.txt)
+  needs: []
+  allow_failure: true
+  interruptible: true
+
+deploy_lab:
+  stage: deploy
+  script:
+    - 'command -v ssh-agent || ( apt-get install openssh-client -y )'
+    - eval $(ssh-agent -s)
+    - echo "${SSH_PRIVATE_KEY}" | base64 -d | ssh-add -
+    - mkdir -p ~/.ssh
+    - chmod 700 ~/.ssh
+    - echo "$SSH_KNOWN_HOSTS" > ~/.ssh/known_hosts
+    - chmod 644 ~/.ssh/known_hosts
+    - ssh www-netvs@netvs-lab.scc.kit.edu "${CI_COMMIT_SHA}"
+  environment:
+    name: lab
+    url: https://netvs-lab.scc.kit.edu
+  only:
+  - lab
+
+deploy_devel:
+  stage: deploy
+  script:
+    - 'command -v ssh-agent || ( apt-get install openssh-client -y )'
+    - eval $(ssh-agent -s)
+    - echo "${SSH_PRIVATE_KEY}" | base64 -d | ssh-add -
+    - mkdir -p ~/.ssh
+    - chmod 700 ~/.ssh
+    - echo "$SSH_KNOWN_HOSTS" > ~/.ssh/known_hosts
+    - chmod 644 ~/.ssh/known_hosts
+    - ssh www-netvs@netvs-devel.scc.kit.edu "${CI_COMMIT_SHA}"
+  environment:
+    name: devel
+    url: https://netvs-devel.scc.kit.edu
+  only:
+  - devel
+  interruptible: false
+
+deploy_test:
+  stage: deploy
+  script:
+    - 'command -v ssh-agent || ( apt-get install openssh-client -y )'
+    - eval $(ssh-agent -s)
+    - echo "$SSH_PRIVATE_KEY" | base64 -d | ssh-add -
+    - mkdir -p ~/.ssh
+    - chmod 700 ~/.ssh
+    - echo "$SSH_KNOWN_HOSTS" > ~/.ssh/known_hosts
+    - chmod 644 ~/.ssh/known_hosts
+    - ssh www-netvs@netvs-test.scc.kit.edu "${CI_COMMIT_SHA}"
+  environment:
+    name: test
+    url: https://netvs-test.scc.kit.edu
+  only:
+  - main
+  interruptible: false
+
+deploy_prod:
+  stage: deploy
+  script:
+    - 'command -v ssh-agent || ( apt-get install openssh-client -y )'
+    - eval $(ssh-agent -s)
+    - echo "$SSH_PRIVATE_KEY" | base64 -d | ssh-add -
+    - mkdir -p ~/.ssh
+    - chmod 700 ~/.ssh
+    - echo "$SSH_KNOWN_HOSTS" > ~/.ssh/known_hosts
+    - chmod 644 ~/.ssh/known_hosts
+    - ssh www-netvs@netvs.scc.kit.edu "${CI_COMMIT_SHA}"
+  environment:
+    name: prod
+    url: https://netvs.scc.kit.edu
+  only:
+  - main
+  interruptible: false