QGIS & JupyterGIS Integration

Carto-Lab Docker supports QGIS through a :qgis flavor. This image extends the base container by injecting the QGIS desktop engine and the jupytergis-qgis bridge.

This allows you to:

  1. Open native .qgz files directly in the JupyterLab browser UI via JupyterGIS.
  2. Programmatically execute QGIS geoprocessing algorithms inside your Jupyter Notebooks using import qgis.core.

Note

Currently speaking, we do not push docker images for the QGIS tag to our registry. You need to build the image yourself off our stable release.


Usage

Add the QGIS flavor overlay to your .env file:

COMPOSE_FILE=docker-compose.yml:docker-compose.qgis.yml
COMPOSE_PATH_SEPARATOR=:

Then start the container:

docker compose up -d
Have a look at the docker-compose.qgis.yml

services:
  jupyterlab:
    image: quay.io/ioer-fdz/carto-lab-docker:${TAG:-qgis}
    build:
      context: ./qgis
      args:
        VERSION: ${TAG:-latest}
See the qgis/Dockerfilefile for the list of QGIS dependencies

ARG VERSION=latest

## public:
# FROM quay.io/ioer-fdz/carto-lab-docker:$VERSION
## private:
FROM gcr.hrz.tu-chemnitz.de/ioer/fdz/carto-lab-docker:$VERSION

# 1. Install QGIS and the jupytergis-qgis bridge into the Server Environment.
# Use `conda install` (not mamba) so it respects CONDA_SOLVER=rattler.
RUN CONDA_REPODATA_THREADS=1 CONDA_SOLVER=rattler CONDA_METADATA_STRATEGY=none \
    conda install -n jupyter_env qgis jupytergis-qgis --channel conda-forge --yes \
    && mamba clean --all --force-pkgs-dirs --yes

# 2. Recreate the Worker Environment from scratch with QGIS included
RUN sed -i 's/- python>=3.10,<3.13/- python>=3.10/g' /environment_default.yml \
    && sed -i '/- pyarrow/d' /environment_default.yml \
    && echo "  - qgis" >> /environment_default.yml \
    && echo "  - jupytergis" >> /environment_default.yml \
    && echo "  - jupytergis-qgis" >> /environment_default.yml \
    && echo "  - ipykernel" >> /environment_default.yml \
    # Explicitly remove the old environment to allow a clean creation
    && rm -rf /opt/conda/envs/worker_env \
    # Create the new environment
    && CONDA_REPODATA_THREADS=1 CONDA_SOLVER=rattler CONDA_METADATA_STRATEGY=none \
    conda env create -n worker_env --file /environment_default.yml \
    # Re-register the Jupyter Kernel since the environment was wiped
    && source /opt/conda/bin/activate worker_env \
    && ipython kernel install --user --name=worker_env \
    && sed -i '/"display_name": "worker_env",/a "env":{"PROJ_LIB": "/opt/conda/envs/worker_env/share/proj"},' \
    /root/.local/share/jupyter/kernels/worker_env/kernel.json \
    && mamba clean --all --force-pkgs-dirs --yes

Note

If you are not an academic member of the gcr.hrz.tu-chemnitz.de group, replace: FROM gcr.hrz.tu-chemnitz.de/ioer/fdz/carto-lab-docker:$VERSION with: image: quay.io/ioer-fdz/carto-lab-docker:qgis This is our public image clone that is accessible without restrictions.

Building the Image Locally

If you want to build the :qgis flavor locally against the base image:

docker compose -f docker-compose.yml -f docker-compose.qgis.yml build \
        --no-cache --progress=plain \
    && docker compose -f docker-compose.yml -f docker-compose.qgis.yml up -d

Note

The above command will honor your current Carto-Lab flavor and version specified in your .env. That is, if you have TAG=v1.1.0, QGIS will be built on top of the v1.1.0 image from our registry. Vice versa, if you want QGIS + the R flavor, use TAG=r_v1.1.0 in your .env.

For more information, see the base container instructions and the developer section.

Tip

As suggested in the above, add the overlay to your .env file so you don't need to type -f every time:

COMPOSE_FILE=docker-compose.yml:docker-compose.qgis.yml
COMPOSE_PATH_SEPARATOR=:

See the developer section for more information.

Why don't we integrate QGIS directly into Carto-Lab?

The main reason is resource limitation. Users who only require Pandas and Matplotlib need only download a 2 GB base image. However, power users who need to render QGIS layers on the web must extend this base image. Furthermore, the Conda/Mamba resolver is limited in the number of packages it can effectively resolve. Therefore, adding more packages to the base 'worker_env' is impractical.