diff --git a/apps/swh-graph/Dockerfile b/apps/swh-graph/Dockerfile
new file mode 100644
index 0000000000000000000000000000000000000000..c9c7a9a9e25ba1acaeac91d5dac522fd47c27c92
--- /dev/null
+++ b/apps/swh-graph/Dockerfile
@@ -0,0 +1,53 @@
+# Deeply inspired from the Dockerfile of the swh-graphql project
+FROM python:3.11-bookworm
+ARG UID=1000
+ARG GID=1000
+
+RUN apt-get -y update && \
+    apt-get -y upgrade && \
+    apt-get install -y libcmph-dev librdkafka-dev \
+      build-essential libclang-dev \
+      zstd protobuf-compiler && \
+    apt clean && \
+    addgroup --gid $UID swh && \
+    useradd --gid $GID --uid $UID -m -d /opt/swh swh && \
+    mkdir /etc/swh
+
+USER swh
+WORKDIR /opt/swh
+
+COPY --chown=swh:swh requirements-frozen.txt /opt/swh
+
+ENV PYTHONPATH=/opt/swh
+ENV PATH=/opt/swh/.local/bin:$PATH
+
+RUN /usr/local/bin/python -m pip install --upgrade pip && \
+    pip install --no-cache-dir -r requirements-frozen.txt
+
+# Install rustup and the default rust toolchain
+
+ENV CARGO_HOME="/opt/swh/.cargo"
+ENV RUSTUP_HOME="/opt/swh/.rustup"
+
+RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs -o /tmp/rustup-init.sh && \
+  chmod +x /tmp/rustup-init.sh && \
+  /tmp/rustup-init.sh -y && \
+  rm /tmp/rustup-init.sh
+
+ENV PATH="${CARGO_HOME}/bin:${PATH}"
+
+# Install
+
+RUN RUSTFLAGS="-C target-cpu=native" \
+  cargo install --git https://gitlab.softwareheritage.org/swh/devel/swh-graph.git \
+    --features grpc-server \
+    swh-graph
+
+ENV SWH_CONFIG_FILENAME=/etc/swh/config.yml
+ENV PORT 5009
+EXPOSE $PORT
+
+COPY --chown=swh:swh entrypoint.sh /opt/swh
+RUN chmod u+x /opt/swh/entrypoint.sh
+
+ENTRYPOINT ["/opt/swh/entrypoint.sh"]
diff --git a/apps/swh-graph/entrypoint.sh b/apps/swh-graph/entrypoint.sh
new file mode 100755
index 0000000000000000000000000000000000000000..0ba8956cc677955b0c1987b8fbe1b433ebda0b80
--- /dev/null
+++ b/apps/swh-graph/entrypoint.sh
@@ -0,0 +1,28 @@
+#!/bin/bash
+
+set -e
+
+case "${GRAPH_TYPE}" in
+    "rpc")
+        echo Starting the swh-graph rpc server
+        swh \
+            graph \
+            -C ${SWH_CONFIG_FILENAME} \
+            rpc-serve \
+            -g ${GRAPH_PATH} \
+            -h 0.0.0.0 \
+            -p ${PORT}
+        ;;
+    "grpc")
+        echo Starting the swh-graph grpc server
+        swh \
+            graph \
+            -C ${SWH_CONFIG_FILENAME} \
+            grpc-serve \
+            -g ${GRAPH_PATH} \
+            -p ${PORT}
+        ;;
+    *)
+        echo "Unknown graph type <$GRAPH_TYPE> (can only be one of rpc or gprc)"
+        exit 1
+esac
diff --git a/apps/swh-graph/requirements.txt b/apps/swh-graph/requirements.txt
new file mode 100644
index 0000000000000000000000000000000000000000..272edad0b06c56d693aab22c546a809fb86c1632
--- /dev/null
+++ b/apps/swh-graph/requirements.txt
@@ -0,0 +1,2 @@
+swh.graph
+python-json-logger