diff --git a/Dockerfile b/Dockerfile index 3ea6fd03e3..7c33e364b1 100644 --- a/Dockerfile +++ b/Dockerfile @@ -153,10 +153,12 @@ ARG WITH_HELM=true ARG WITH_GIT=true ARG features="" -# The version new instances start on: PyVAlias::NEW_INSTANCE in the backend. Instances keep -# the version they were initialized with, so when raising it, keep installing every earlier -# value alongside it. +# Instances keep the Python version they were initialized with, so both are preinstalled: +# LATEST_STABLE_PY is what instances initialized before the version was raised are on +# (PyVAlias::default() in the backend), NEW_INSTANCE_PY the one new instances start on +# (PyVAlias::NEW_INSTANCE). When raising the latter, keep installing every earlier value. ARG LATEST_STABLE_PY=3.12 +ARG NEW_INSTANCE_PY=3.15 ENV UV_PYTHON_INSTALL_DIR=/tmp/windmill/cache/py_runtime ENV UV_PYTHON_PREFERENCE=only-managed @@ -249,6 +251,7 @@ RUN curl --proto '=https' --tlsv1.2 -LsSf https://github.com/astral-sh/uv/releas # timestamps or Python's mtime-based .pyc invalidation discards these compiled files. RUN UV_CACHE_DIR=/tmp/build_cache/uv UV_PYTHON_INSTALL_DIR=/tmp/build_cache/py_runtime uv python install 3.11 --compile-bytecode RUN UV_CACHE_DIR=/tmp/build_cache/uv UV_PYTHON_INSTALL_DIR=/tmp/build_cache/py_runtime uv python install $LATEST_STABLE_PY --compile-bytecode +RUN UV_CACHE_DIR=/tmp/build_cache/uv UV_PYTHON_INSTALL_DIR=/tmp/build_cache/py_runtime uv python install $NEW_INSTANCE_PY --compile-bytecode RUN curl -sL https://deb.nodesource.com/setup_24.x | bash - diff --git a/backend/windmill-common/src/worker.rs b/backend/windmill-common/src/worker.rs index 8d7662722d..6dd87f2153 100644 --- a/backend/windmill-common/src/worker.rs +++ b/backend/windmill-common/src/worker.rs @@ -2917,7 +2917,7 @@ impl PyVAlias { /// What the server writes into `instance_python_version` when it initializes an instance. /// Raising it also means the images must keep preinstalling every earlier value, or /// instances that started on one download their runtime on first use. - pub const NEW_INSTANCE: PyVAlias = PyVAlias::Py312; + pub const NEW_INSTANCE: PyVAlias = PyVAlias::Py315; pub fn all>() -> Vec { use PyVAlias::*; diff --git a/backend/windmill-worker/src/python_versions.rs b/backend/windmill-worker/src/python_versions.rs index 7f9a9448f7..2166383df7 100644 --- a/backend/windmill-worker/src/python_versions.rs +++ b/backend/windmill-worker/src/python_versions.rs @@ -14,6 +14,7 @@ use tokio::{fs::DirBuilder, process::Command, sync::RwLock}; use uuid::Uuid; use windmill_common::{ error::{self, Error}, + global_settings::{load_value_from_global_settings, INSTANCE_PYTHON_VERSION_SETTING}, worker::{try_parse_locked_python_version_from_requirements, Connection, PyVAlias}, }; @@ -256,7 +257,23 @@ impl PyV { conn: Option, ) -> Self { let mut err = None; - let pyv = match INSTANCE_PYTHON_VERSION.read().await.clone() { + let mut setting = INSTANCE_PYTHON_VERSION.read().await.clone(); + // A worker that loaded its settings while the server was still initializing the instance + // read no version, and may have started listening for setting changes only after it was + // written. Jobs only exist once it is, so reading it here settles that worker for good. + if setting.is_none() { + if let Some(Connection::Sql(db)) = conn.as_ref() { + setting = load_value_from_global_settings(db, INSTANCE_PYTHON_VERSION_SETTING) + .await + .ok() + .flatten() + .and_then(|v| serde_json::from_value::(v).ok()); + if setting.is_some() { + *INSTANCE_PYTHON_VERSION.write().await = setting.clone(); + } + } + } + let pyv = match setting { Some(v) if &v == "default" => PyVAlias::default().into(), Some(v) => pep440_rs::Version::from_str(&v).unwrap_or_else(|_| { let v = PyVAlias::default().into(); diff --git a/docker/DockerfileSlim b/docker/DockerfileSlim index a37ced0eca..085b3540a8 100644 --- a/docker/DockerfileSlim +++ b/docker/DockerfileSlim @@ -30,6 +30,7 @@ FROM ${DEBIAN_IMAGE} ARG APP=/usr/src/app ARG LATEST_STABLE_PY=3.12.13 +ARG NEW_INSTANCE_PY=3.15.0 # UV configuration ENV UV_CACHE_DIR=/tmp/windmill/cache/uv @@ -65,6 +66,7 @@ RUN curl --proto '=https' --tlsv1.2 -LsSf https://github.com/astral-sh/uv/releas # under the read-only nsjail runtime mount (uv >= 0.9.25). The copy below MUST preserve # timestamps or Python's mtime-based .pyc invalidation discards these compiled files. RUN UV_PYTHON_INSTALL_DIR=/tmp/build_cache/py_runtime uv python install $LATEST_STABLE_PY --compile-bytecode +RUN UV_PYTHON_INSTALL_DIR=/tmp/build_cache/py_runtime uv python install $NEW_INSTANCE_PY --compile-bytecode # Copy to final location with world-writable permissions for arbitrary UID support RUN mkdir -p /tmp/windmill/cache && \ diff --git a/docker/DockerfileSlimEe b/docker/DockerfileSlimEe index 687b1506ce..7a2483067f 100644 --- a/docker/DockerfileSlimEe +++ b/docker/DockerfileSlimEe @@ -30,6 +30,7 @@ FROM ${DEBIAN_IMAGE} ARG APP=/usr/src/app ARG LATEST_STABLE_PY=3.12.13 +ARG NEW_INSTANCE_PY=3.15.0 # UV configuration ENV UV_CACHE_DIR=/tmp/windmill/cache/uv @@ -65,6 +66,7 @@ RUN curl --proto '=https' --tlsv1.2 -LsSf https://github.com/astral-sh/uv/releas # under the read-only nsjail runtime mount (uv >= 0.9.25). The copy below MUST preserve # timestamps or Python's mtime-based .pyc invalidation discards these compiled files. RUN UV_PYTHON_INSTALL_DIR=/tmp/build_cache/py_runtime uv python install $LATEST_STABLE_PY --compile-bytecode +RUN UV_PYTHON_INSTALL_DIR=/tmp/build_cache/py_runtime uv python install $NEW_INSTANCE_PY --compile-bytecode # Copy to final location with world-writable permissions for arbitrary UID support RUN mkdir -p /tmp/windmill/cache && \