diff --git a/apps/swh-storage/Dockerfile b/apps/swh-storage/Dockerfile
new file mode 100644
index 0000000000000000000000000000000000000000..0971c8fa65d9a619c32e172f362886a35ad7765d
--- /dev/null
+++ b/apps/swh-storage/Dockerfile
@@ -0,0 +1,34 @@
+# Deeply inspired from the Dockerfile of the swh-graphql project
+FROM python:3.10-bullseye
+
+RUN apt-get -y update && \
+    apt-get -y upgrade && \
+    apt-get install -y libcmph-dev librdkafka-dev && \
+    apt clean && \
+    addgroup --gid 1000 swh && \
+    useradd --gid 1000 --uid 1000 -m -d /opt/swh swh && \
+    mkdir /etc/swh
+
+USER swh
+WORKDIR /opt/swh
+
+COPY --chown=swh:swh requirements-frozen.txt /opt/swh
+COPY --chown=swh:swh entrypoint.sh /opt/swh
+
+ENV PYTHONPATH=/opt/swh
+ENV PATH=/opt/swh/.local/bin:$PATH
+
+RUN chmod u+x /opt/swh/entrypoint.sh && \
+    /usr/local/bin/python -m pip install --upgrade pip && \
+    pip install --no-cache-dir -r requirements-frozen.txt && \
+    pip install gunicorn
+
+ENV SWH_CONFIG_FILENAME=/etc/swh/config.yml
+ENV PORT 5002
+EXPOSE $PORT
+ENV THREADS 4
+ENV WORKERS 2
+ENV LOG_LEVEL INFO
+ENV TIMEOUT 3600
+
+ENTRYPOINT ["/opt/swh/entrypoint.sh"]
diff --git a/apps/swh-storage/entrypoint.sh b/apps/swh-storage/entrypoint.sh
new file mode 100755
index 0000000000000000000000000000000000000000..0891c46134efbe773f988dc1d943b3785bcba8fd
--- /dev/null
+++ b/apps/swh-storage/entrypoint.sh
@@ -0,0 +1,24 @@
+#!/bin/bash
+
+set -e
+
+case "$1" in
+    "shell")
+      exec bash -i
+      ;;
+    "swh")
+        shift
+        echo "Running swh command $@"
+        exec swh $@
+        ;;
+    *)
+      echo Starting the swh-storage API server
+      exec gunicorn --bind 0.0.0.0:${PORT} \
+           --threads ${THREADS} \
+           --workers ${WORKERS} \
+           --log-level ${LOG_LEVEL} \
+           --timeout ${TIMEOUT} \
+           --config 'python:swh.core.api.gunicorn_config' \
+           'swh.storage.api.server:make_app_from_configfile()'
+      ;;
+esac
diff --git a/apps/swh-storage/requirements-frozen.txt b/apps/swh-storage/requirements-frozen.txt
new file mode 100644
index 0000000000000000000000000000000000000000..98435f2e6ef108a135c3ecdb82c505533b59982c
--- /dev/null
+++ b/apps/swh-storage/requirements-frozen.txt
@@ -0,0 +1,61 @@
+aiohttp==3.8.4
+aiohttp-utils==3.2.1
+aiosignal==1.3.1
+async-timeout==4.0.2
+attrs==22.2.0
+attrs-strict==1.0.0
+blinker==1.5
+cassandra-driver==3.25.0
+certifi==2022.12.7
+cffi==1.15.1
+charset-normalizer==3.1.0
+click==8.1.3
+confluent-kafka==2.0.2
+Deprecated==1.2.13
+exceptiongroup==1.1.1
+Flask==2.2.3
+frozenlist==1.3.3
+geomet==0.2.1.post1
+gunicorn==20.1.0
+hypothesis==6.70.0
+idna==3.4
+iniconfig==2.0.0
+iso8601==1.1.0
+itsdangerous==2.1.2
+Jinja2==3.1.2
+MarkupSafe==2.1.2
+mirakuru==2.5.1
+msgpack==1.0.5
+multidict==6.0.4
+mypy-extensions==1.0.0
+packaging==23.0
+pluggy==1.0.0
+port-for==0.6.3
+psutil==5.9.4
+psycopg2==2.9.5
+pycparser==2.21
+pytest==7.2.2
+pytest-postgresql==3.1.3
+python-dateutil==2.8.2
+python-magic==0.4.27
+python-mimeparse==1.6.0
+PyYAML==6.0
+redis==4.5.3
+requests==2.28.2
+sentry-sdk==1.17.0
+six==1.16.0
+sortedcontainers==2.4.0
+swh.core==2.21.2
+swh.counters==0.9.2
+swh.journal==1.3.1
+swh.model==6.6.3
+swh.objstorage==2.1.0
+swh.perfecthash==0.1.2
+swh.storage==1.11.0
+tenacity==8.2.2
+tomli==2.0.1
+typing_extensions==4.5.0
+urllib3==1.26.15
+Werkzeug==2.2.3
+wrapt==1.15.0
+yarl==1.8.2
diff --git a/apps/swh-storage/requirements.txt b/apps/swh-storage/requirements.txt
new file mode 100644
index 0000000000000000000000000000000000000000..c702dcbf5b6d17160c6c62f78b2d1ba1ce8c9945
--- /dev/null
+++ b/apps/swh-storage/requirements.txt
@@ -0,0 +1 @@
+swh.storage