diff --git a/bin/start-ds.sh b/bin/start-ds.sh
index 7b601c4c8f5e24ac56755ad08a1203a6cbba62d2..a48b0b4554cd2ef9380cbc482b07edfc38203043 100755
--- a/bin/start-ds.sh
+++ b/bin/start-ds.sh
@@ -2,6 +2,11 @@
 
 # Serves as entrypoint script for docker containers
 
+if [[ ! -d "/opt/lofar/tango" ]]; then
+  >&2 echo "/opt/lofar/tango volume does not exist!"
+  exit 1
+fi
+
 # Check required support file exists
 if [[ ! -f "/usr/local/bin/wait-for-it.sh" ]]; then
     >&2 echo "/usr/local/bin/wait-for-it.sh file does not exist!"
@@ -14,6 +19,11 @@ if [[ ! $TANGO_HOST ]]; then
   exit 1
 fi
 
+# Store directory so we can return to it after installation
+CWD=$(pwd)
+
+cd /opt/lofar/tango || exit 1
+
 # Check if configured for specific version
 if [[ $TANGOSTATIONCONTROL ]]; then
   # TODO (Corne): Download version from artifacts or pypi.
@@ -28,4 +38,8 @@ else
   sudo pip install --force-reinstall "$(ls -Art /tmp/tangostationcontrol/*.whl | tail -n 1)"
 fi
 
+# Return to the stored the directory, this preserves the working_dir argument in
+# docker-compose files.
+cd "$CWD" || exit 1
+
 /usr/local/bin/wait-for-it.sh "$TANGO_HOST" --timeout=30 --strict -- "$@"
diff --git a/docker-compose/jupyter.yml b/docker-compose/jupyter.yml
index f32c6c1395fe6e41764e4569d472178620f731dd..bbc20f269f8a44acff3ce9f36bf11eeef17cea8f 100644
--- a/docker-compose/jupyter.yml
+++ b/docker-compose/jupyter.yml
@@ -31,10 +31,6 @@ services:
     user: ${CONTAINER_EXECUTION_UID}
     working_dir: /jupyter-notebooks
     entrypoint:
-      - /usr/local/bin/wait-for-it.sh
-      - ${TANGO_HOST}
-      - --timeout=30
-      - --strict
-      - --
+      - /opt/lofar/tango/bin/start-ds.sh
       - /usr/bin/tini -- /usr/local/bin/jupyter-notebook --port=8888 --no-browser --ip=0.0.0.0 --allow-root --NotebookApp.token= --NotebookApp.password=
     restart: unless-stopped
diff --git a/docker-compose/jupyter/Dockerfile b/docker-compose/jupyter/Dockerfile
index 5393cece6a74ff1de85e9c37ce6a8307e3a66cf5..cc1652e4a45bc14805632ec1d4056beaab1fd34c 100644
--- a/docker-compose/jupyter/Dockerfile
+++ b/docker-compose/jupyter/Dockerfile
@@ -10,23 +10,13 @@ ENV HOME=/home/user
 RUN sudo mkdir -p ${HOME}
 RUN sudo chown ${CONTAINER_EXECUTION_UID} -R ${HOME}
 
-# ipython 7.28 is broken in combination with Jupyter, it causes connection errors with notebooks
-RUN sudo pip3 install ipython==7.27.0
-
-RUN sudo pip3 install jupyter
-RUN sudo pip3 install ipykernel
-RUN sudo pip3 install jupyter_bokeh
-# Install matplotlib, jupyterplot
-RUN sudo pip3 install matplotlib jupyterplot
-
-# Allow Download as -> PDF via html
-RUN sudo pip3 install nbconvert
-RUN sudo pip3 install notebook-as-pdf
+COPY requirements.txt ./
+RUN sudo pip3 install -r requirements.txt
 
 # see https://github.com/jupyter/nbconvert/issues/1434
 RUN sudo bash -c "echo DEFAULT_ARGS += [\\\"--no-sandbox\\\"] >> /usr/local/lib/python3.7/dist-packages/pyppeteer/launcher.py"
 RUN sudo apt-get update -y
-RUN sudo apt-get install -y gconf-service libasound2 libatk1.0-0 libatk-bridge2.0-0 libc6 libcairo2 libcups2 libdbus-1-3 libexpat1 libfontconfig1 libgcc1 libgconf-2-4 libgdk-pixbuf2.0-0 libglib2.0-0 libgtk-3-0 libnspr4 libpango-1.0-0 libpangocairo-1.0-0 libstdc++6 libx11-6 libx11-xcb1 libxcb1 libxcomposite1 libxcursor1 libxdamage1 libxext6 libxfixes3 libxi6 libxrandr2 libxrender1 libxss1 libxtst6 ca-certificates fonts-liberation libappindicator1 libnss3 lsb-release xdg-utils wget libcairo-gobject2 libxinerama1 libgtk2.0-0 libpangoft2-1.0-0 libthai0 libpixman-1-0 libxcb-render0 libharfbuzz0b libdatrie1 libgraphite2-3 libgbm1
+RUN sudo apt-get install -y git gconf-service libasound2 libatk1.0-0 libatk-bridge2.0-0 libc6 libcairo2 libcups2 libdbus-1-3 libexpat1 libfontconfig1 libgcc1 libgconf-2-4 libgdk-pixbuf2.0-0 libglib2.0-0 libgtk-3-0 libnspr4 libpango-1.0-0 libpangocairo-1.0-0 libstdc++6 libx11-6 libx11-xcb1 libxcb1 libxcomposite1 libxcursor1 libxdamage1 libxext6 libxfixes3 libxi6 libxrandr2 libxrender1 libxss1 libxtst6 ca-certificates fonts-liberation libappindicator1 libnss3 lsb-release xdg-utils wget libcairo-gobject2 libxinerama1 libgtk2.0-0 libpangoft2-1.0-0 libthai0 libpixman-1-0 libxcb-render0 libharfbuzz0b libdatrie1 libgraphite2-3 libgbm1
 
 # Allow Download as -> PDF via LaTeX
 RUN sudo apt-get install -y texlive-xetex texlive-fonts-recommended texlive-latex-recommended
@@ -43,15 +33,8 @@ RUN sudo chown ${CONTAINER_EXECUTION_UID} -R /opt/ipython-profiles
 COPY jupyter-kernels /usr/local/share/jupyter/kernels/
 
 # Install patched jupyter executable
-RUN sudo pip3 install python-logstash-async
 COPY jupyter-notebook /usr/local/bin/jupyter-notebook
 
-#Install further python modules
-RUN sudo pip3 install PyMySQL[rsa] sqlalchemy
-
-# Packages to interface with testing hardware directly
-RUN sudo pip3 install pyvisa pyvisa-py opcua
-
 # Add Tini. Tini operates as a process subreaper for jupyter. This prevents kernel crashes.
 ENV TINI_VERSION v0.6.0
 ENV JUPYTER_RUNTIME_DIR=/tmp
diff --git a/docker-compose/jupyter/ipython-profiles/stationcontrol-jupyter/startup/02-stationcontrol.py b/docker-compose/jupyter/ipython-profiles/stationcontrol-jupyter/startup/02-stationcontrol.py
new file mode 100644
index 0000000000000000000000000000000000000000..d2d810b1ad5915504e4a5b508e9a128bd2981628
--- /dev/null
+++ b/docker-compose/jupyter/ipython-profiles/stationcontrol-jupyter/startup/02-stationcontrol.py
@@ -0,0 +1 @@
+from tangostationcontrol import *
\ No newline at end of file
diff --git a/docker-compose/jupyter/requirements.txt b/docker-compose/jupyter/requirements.txt
new file mode 100644
index 0000000000000000000000000000000000000000..3be9c3d4c8f1052920b577d77442a348c09aa7ca
--- /dev/null
+++ b/docker-compose/jupyter/requirements.txt
@@ -0,0 +1,15 @@
+GitPython >= 3.1.24 # BSD
+ipython >=7.27.0,!=7.28.0 # BSD
+jupyter
+ipykernel
+jupyter_bokeh
+matplotlib
+jupyterplot
+nbconvert
+notebook-as-pdf
+python-logstash-async
+PyMySQL[rsa]
+sqlalchemy
+pyvisa
+pyvisa-py
+opcua
\ No newline at end of file
diff --git a/docs/source/devices/sst-xst.rst b/docs/source/devices/sst-xst.rst
index cdb689e457dc2d6abebcfc1391f057135f30b722..092bdda832eb0493f93956f4aec8025410d0bf9b 100644
--- a/docs/source/devices/sst-xst.rst
+++ b/docs/source/devices/sst-xst.rst
@@ -63,7 +63,7 @@ Typically, ``N_ant == 192``, and ``N_blocks == 136``.
 
 The metadata refers to the *blocks*, which are emitted by the FPGAs to represent the XSTs between 12 x 12 consecutive antennas. The following code converts block numbers to the indices of the first antenna pair in a block::
 
-  from common.baselines import baseline_from_index
+  from tangostationcontrol.common.baselines import baseline_from_index
 
   def first_antenna_pair(block_nr: int) -> int:
       coarse_a, coarse_b = baseline_from_index(block_nr)
@@ -71,7 +71,7 @@ The metadata refers to the *blocks*, which are emitted by the FPGAs to represent
 
 Conversely, to calculate the block index for an antenna pair ``(a,b)``, use::
 
-  from common.baselines import baseline_index
+  from tangostationcontrol.common.baselines import baseline_index
 
   def block_nr(a: int, b: int) -> int:
       return baseline_index(a // 12, b // 12)