How to customize the Spotfire containerized Python service Dockerfile to install Python packages

How to customize the Spotfire containerized Python service Dockerfile to install Python packages

book

Article ID: KB0070353

calendar_today

Updated On:

Products Versions
Spotfire Server 14.2.0 and later

Description

The Spotfire containerized Python service allows you to separate the Python service from the host file system. However in some cases, you may not want to maintain on-prem installations of any required Python libraries which are not already provided with the service by default. Default packages provided with the Python service are listed here.

To install additional packages on-the-fly during the Docker build phase, you may configure the containerized Python service to use a custom Docker image. Follow the steps below to create a containerized Python service. The example shown below uses a node manager running on AlmaLinux 9 and a Spotfire Server running on Windows.
 

Issue/Introduction

Outlines the steps needed to customize the Spotfire containerized Python Service so that Python packages are installed via Dockerfile commands. This avoids having to maintain on-prem SPKs or Python library folders to house those packages.

Resolution

1. On node manager machine, create the custom Dockerfile. Here is an example:
 
 # Use Debian 12 slim as the base image FROM debian:12-slim # Install necessary dependencies RUN apt update -y \     && apt upgrade -y \     && apt install -y \     ca-certificates \     build-essential \     libssl-dev \     zlib1g-dev \     libncurses5-dev \     libncursesw5-dev \     libreadline-dev \     libsqlite3-dev \     libgdbm-dev \     libdb5.3-dev \     libbz2-dev \     libexpat1-dev \     liblzma-dev \     tk-dev \     wget \     curl \     llvm \     libncurses5-dev \     xz-utils \     tk-dev \     libxml2-dev \     libxmlsec1-dev \     libffi-dev \     liblzma-dev \     libpq-dev \     libjpeg-dev \     libtiff5-dev \     libopenjp2-7-dev \     libwebp-dev \     libzstd-dev \     libfreetype6-dev \     liblcms2-dev \     libwebp-dev \     libharfbuzz-dev \     libfribidi-dev \     tcl-dev \     && apt install -y --no-install-recommends \     openjdk-17-jdk \     python3.11 \     python3.11-venv \     && apt clean all # Download and install Python 3.11 RUN wget https://www.python.org/ftp/python/3.11.0/Python-3.11.0.tgz && \     tar -xf Python-3.11.0.tgz && \     cd Python-3.11.0 && \     ./configure --enable-optimizations && \     make -j$(nproc) && \     make altinstall # Clean up RUN rm -rf Python-3.11.0 Python-3.11.0.tgz # Set Python 3.11 as the default Python version RUN ln -s /usr/local/bin/python3.11 /usr/local/bin/python # set environmental variables ENV JAVA_HOME=${JAVA_HOME:-/usr/lib/jvm/java-17-openjdk-amd64} ENV SERVICE_HOME=/opt/python # Set up python environment ENV SPOTFIRE_PYTHON_HOME=/opt RUN python3.11 -m venv ${SPOTFIRE_PYTHON_HOME} --upgrade-deps \   && ${SPOTFIRE_PYTHON_HOME}/bin/python -m pip install spotfire # Install additional packages WORKDIR / COPY --chown=spotfire:spotfire ./requirements.txt /requirements.txt RUN python3.11 -m venv ${SPOTFIRE_PYTHON_HOME} --upgrade-deps \   && ${SPOTFIRE_PYTHON_HOME}/bin/python -m pip install -r /requirements.txt # Create directories RUN mkdir -p $SERVICE_HOME \   && mkdir $SERVICE_HOME/conf \   && mkdir /opt/packages RUN groupadd -g 1000 spotfire \     && useradd --uid 22051 --gid 1000 --home /opt/python/ --shell=/bin/bash spotfire \     && mkdir "$SERVICE_HOME"/../../logs \     && chown spotfire:spotfire "$SERVICE_HOME"/../../logs USER spotfire

2. In the same directory where you created the custom Dockerfile, add the requirements.txt file. In this file, add the packages you want to install. For example..
 
 tensorflow matplotlib

3. From that same directory, build the image:
 
 $ docker build -t pythonsrv:100 .

This will take some time, as Python needs to be built from source. This is needed to enable the SSL module, which is a required package for downloading additional packages from pypi.org. The Python SSL module is not enabled when using the default containerized Python service configuration. We will customize the configuration in steps 6-8 below.

4. Run the image to ensure that the expected packages have been installed:
 
 $ docker run -it pythonsrv:100 bash spotfire@43744ba47fa5:/$ $SPOTFIRE_PYTHON_HOME/bin/python -m pip list WARNING: The directory '/opt/python/.cache/pip' or its parent directory is not owned or  is not writable by the current user. The cache has been disabled. Check the permissions  and owner of that directory. If executing pip with sudo, you should use sudo's -H flag. Package                      Version ---------------------------- ----------- absl-py                      2.1.0 astunparse                   1.6.3 certifi                      2024.2.2 ... matplotlib                   3.8.4 ... tensorflow                   2.16.1

In the above output, we can see that matplotlib and tensorflow have been installed.

5. After confirming that the packages have been installed, you should exit the container's bash prompt (by typing 'exit') and then stop the running container:
 
 $ docker ps -a CONTAINER ID   IMAGE           COMMAND   CREATED         STATUS ...  43744ba47fa5   pythonsrv:100   "bash"    2 minutes ago   Exited (0) 1 second ago ... $ docker rm -f 43744ba47fa5

6. On the Spotfire Server machine, export the Python service configuration from an administrative command prompt:
 
 C:\Windows\system32>cd \spotfire\spotfireserver\14.2.0\tomcat\spotfire-bin C:\spotfire\spotfireserver\14.2.0\tomcat\spotfire-bin> config export-service-config --capability=Python --deployment-area=Production --force

7. Open the service configuration file (under C:\spotfire\spotfireserver\14.2.0\tomcat\spotfire-bin\config\root\conf\custom.properties) in a text editor, and set the following properties:
 
 docker.image.name: pythonsrv:100 use.immutable.container: true

8. Import the custom service configuration:
 
 C:\spotfire\spotfireserver\14.2.0\tomcat\spotfire-bin> config import-service-config --config-name=python-with-packages

9. In the Spotfire web admin UI, go to 'Nodes and Services', and select your node manager. Then click 'Create new service' to add the Python service.

10. In the 'Create new service' dialog window, set 'Configuration' to 'python-with-packages'.

custom python service config

Then click 'Create Service'.

You have now configured a custom containerized Python service with your required Python packages installed.