2026-08-14 16:37:36 +02:00
2026-08-14 16:35:16 +02:00
2026-08-14 16:37:36 +02:00
2026-08-14 14:29:19 +02:00
2026-08-14 16:01:50 +02:00
2026-08-14 16:30:27 +02:00
2026-08-14 14:31:01 +02:00

0. Introduction

  • Did it on a macbook air as I am away from my Linux workstation at home
  • I will use some of my selfhosted services in examples, e.g. registry.bouvais.lu for docker registry and git.bouvais.lu for gitea.

1. Create env

First let's install everything that I will use using brew.

brew install docker

2. Images

To created the needed dependency, I did a simple 2 images base + jupyter. The first image is a minimal python slim. I then add some

2.1. Base

FROM python:3.12-slim-bookworm AS base

LABEL org.opencontainers.image.title="tenant-base" \
      org.opencontainers.image.description="Hardened base image for tenant workspaces" \
      org.opencontainers.image.source="https://git.bouvais.lu/adrien/"

# System deps only — keep this layer stable so it's rarely rebuilt
RUN apt-get update && apt-get install -y --no-install-recommends \
        ca-certificates \
        curl \
        tini \
    && rm -rf /var/lib/apt/lists/*

# Non-root user, fixed UID/GID for predictable K8s securityContext
RUN groupadd --gid 1000 appuser \
    && useradd --uid 1000 --gid appuser --shell /bin/bash --create-home appuser

WORKDIR /home/appuser
USER appuser

ENTRYPOINT ["tini", "--"]

Then build and push it to the registry

docker build -t registry.bouvais.lu/tenant-base:1.0.0 images/base
docker push registry.bouvais.lu/tenant-base:1.0.0

2.2. Jupyter

Now I dp the same for a simple jupyter image.

ARG BASE_IMAGE=registry.bouvais.lu/tenant-base:1.0.0
FROM ${BASE_IMAGE}

LABEL org.opencontainers.image.title="tenant-jupyter" \
      org.opencontainers.image.description="JupyterLab image built on tenant-base" \
      org.opencontainers.image.base.name="${BASE_IMAGE}"

USER root
COPY --chown=appuser:appuser requirements.txt /tmp/requirements.txt
RUN pip install --no-cache-dir -r /tmp/requirements.txt \
    && rm /tmp/requirements.txt

# No secrets baked in — S3 creds come from a mounted K8s Secret / env at runtime
USER appuser
WORKDIR /home/appuser/work

EXPOSE 8888

CMD ["jupyter", "lab", \
     "--ip=0.0.0.0", \
     "--port=8888", \
     "--no-browser", \
     "--ServerApp.token=", \
     "--ServerApp.allow_remote_access=True"]
Description
No description provided
Readme 40 KiB
Languages
Pip Requirements 100%