diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
new file mode 100644
index 0000000000000000000000000000000000000000..a74711a7a6dd0f8112a8173cb79437dd3f38d3b8
--- /dev/null
+++ b/.gitlab-ci.yml
@@ -0,0 +1,44 @@
+default:
+    image: python:3.10
+
+stages:
+    - build
+    - test
+    - deploy
+
+before_script:
+    - python -V
+    - python -m venv venv
+    - . venv/bin/activate 
+    - pip install --upgrade pip
+    - pip install -e .
+
+build:
+    stage: build
+    tags:
+        - vips-runner
+    script: 
+        - pip install build
+        - python -m build
+    artifacts:
+        paths:
+            - dist/*.whl
+        expire_in: 2 days
+
+test:
+    stage: test
+    tags:
+        - vips-runner
+    script:
+        - pip install pytest
+        - pytest
+
+deploy:
+    stage: deploy
+    only: 
+        - main
+    tags:
+        - vips-runner
+    script:
+        - pip install twine
+        - TWINE_PASSWORD=${CI_JOB_TOKEN} TWINE_USERNAME=gitlab-ci-token python -m twine upload --repository-url https://gitlab.nibio.no/api/v4/projects/401/packages/pypi dist/* --verbose
diff --git a/README.md b/README.md
index 56644b821c1fa866bfd6fd54320d16e17893b834..4046682708da29a835e40b61a9e27d9171bebf23 100644
--- a/README.md
+++ b/README.md
@@ -51,4 +51,45 @@ bumpver update --major
 [(Source)](https://semver.org/#summary)
 
 ### References
-We used this excellent guide for packaging: https://realpython.com/pypi-publish-python-package/ 
\ No newline at end of file
+We used this excellent guide for packaging: https://realpython.com/pypi-publish-python-package/ 
+
+### Deployment
+
+Whenever changes are pushed to the repository, the pipeline defined in `.gitlab-ci.yml` is triggered. Here, there are three jobs: build, test and deploy.
+The final job will only be performed for the `main` branch. Please note that publishing a package to the package repository will fail (= red deploy job)
+if the version of the package has not been bumped since the previous deploy.
+
+Follow these steps for running build, test + deploy on your laptop:
+
+1. Create [Personal access token](https://gitlab.nibio.no/-/profile/personal_access_tokens) with name=`gitlab-pypi` and scope=`Api`.
+
+2. Create file `~/.pypirc` with the following content:
+```
+[distutils]
+index-servers =
+    gitlab
+
+[gitlab]
+repository = https://gitlab.nibio.no/api/v4/projects/401/packages/pypi
+username = gitlab-pypi
+password = <personal access token>
+```
+
+3. Clone project, build, test and deploy package
+```
+$ git clone git@gitlab.nibio.no:VIPS/vipscore-python-common.git
+$ cd vipscore-python-common
+$ python3 -m venv venv
+$ . venv/bin/activate 
+$ pip install -e .
+$ pip install build pytest twine
+$ python3 -m build
+-> Successfully built vipscore_common-0.1.6.tar.gz and vipscore_common-0.1.6-py3-none-any.whl
+$ pytest
+-> [100%] ======================= 2 passed in 0.27s ==========================
+$ python3 -m twine upload --repository gitlab dist/* --verbose
+-> Uploading vipscore_common-0.1.6-py3-none-any.whl
+-> 201 Created
+-> Uploading vipscore_common-0.1.6.tar.gz
+-> 201 Created
+```