_tkinter.TclError: no display name and no $DISPLAY environment variable
Tk draws real windows, so it needs a display to draw on. Servers, containers and CI machines have none, and SSH sessions do not forward one unless you ask.
This often appears from im.show(), which opens a viewer. Save the file instead:
im.save("/tmp/out.png")
Matplotlib causes it the same way. Choose a backend that draws to a file:
import matplotlib
matplotlib.use("Agg")
Connect with X forwarding:
ssh -X user@server
You also need an X server locally: XQuartz on macOS, VcXsrv or the built in WSLg on Windows.
sudo apt-get install xvfb
xvfb-run -a python app.py
Xvfb is a display that exists only in memory. This is the usual answer for running Tkinter tests in CI.
Install Tk at all, first, because slim images do not have it:
RUN apt-get update && apt-get install -y python3-tk xvfb
If instead you see ModuleNotFoundError: No module named 'tkinter', that is the same gap: Tk is not bundled with pip, it comes from the system package.
The PIL to Pillow converter finds most of these automatically, and the other error pages cover the rest.