# Configuring a custom startup script to build a custom Docker image

If you have access to the internet, then you can build a custom Docker image for your Spotfire Service for Python.

## About this task

Perform this task from the command line on the computer where the Spotfire Service for Python is installed, and on the computer where your node manager is installed. For more information about the startup script, see Startup script.

## Before you begin

- You must have Docker installed on the computer running the node manager. If you install and start the service before you install Docker, then exceptions are written to the log.
- You must have a Linux computer where the node manager is installed. (Your node manager and the Spotfire Server are usually on different computers).
- If you are using the script to build the base Docker image, you must have a connection to the internet. (A connection to the internet is not required if you are using a locally-available Docker image.)

Custom docker images for the service must contain the following.

- The Eclipse Temurin 21 Java Runtime.
- The JAVA_HOME environmental variable, correctly defined.

      ENV JAVA_HOME=</correct/path/to/java>

## Procedure

1. If you have already installed the service from the Spotfire Server Nodes & Services administration page, and if it is running, then stop the service.
2. On the computer running the Spotfire Server, export the service configuration file custom.properties:

       config export-service-config --capability=PYTHON --deployment-area=<your deployment area name>

   See the export-service-config page in the Spotfire® Server and Environment - Installation and Administration guide for more information.
3. On computer running Spotfire Server, create a file called Dockerfile, and then save it to your custom configuration directory.
   Important: Remember that for any script you write, the line endings must be appropriate for the operating system where the service runs. Many text editors can perform end-of-line (EOL) conversion.

       #############################################
       # A sample Dockerfile for installing JDK. #
       #############################################
       FROM debian:12-slim
       RUN apt update -y \
         && apt upgrade -y \
         && apt install -y  \
         ca-certificates \
         && apt install -y --no-install-recommends \
         && apt clean all
       #  install jdk
       RUN DEBIAN_FRONTEND=noninteractive apt-get install -y wget apt-transport-https gpg \
              && wget -qO - https://packages.adoptium.net/artifactory/api/gpg/key/public | gpg --dearmor | tee /etc/apt/trusted.gpg.d/adoptium.gpg > /dev/null \
              && echo "deb https://packages.adoptium.net/artifactory/deb $(awk -F= '/^VERSION_CODENAME/{print$2}' /etc/os-release) main" | tee /etc/apt/sources.list.d/adoptium.list \
              && DEBIAN_FRONTEND=noninteractive apt-get update \
              && DEBIAN_FRONTEND=noninteractive apt-get install -y temurin-21-jdk \
              && apt-get clean all

       #  set JAVA_HOME variable
       ENV JAVA_HOME=/usr/lib/jvm/temurin-21-jdk-amd64

   For more information, see https://docs.docker.com/engine/reference/builder/.
4. Install Python and pip.

       #install the Debian-included Python and the pip package.
       RUN apt-get update && apt-get install -y python-is-python3 python3 python3-pip && apt-get clean

5. Install the spotfire package.

       RUN pip install spotfire --break-system-packages

6. Optional: If you need or want to use a Python interpreter that is not bundled with Spotfire Service for Python, then update the following in the Dockerfile.
   1. Install a compatible Python interpreter. See Custom Python interpreter for more information.
   2. Set the environment variable SPOTFIRE_PYTHON_HOME to the path to the directory for the installed Python interpreter that you want to use.
   3. Using `pip`, install the spotfire Python package (available at https://pypi.org/project/spotfire/).
7. On the computer running the service, create a custom script to build the Dockerfile, and then save it to your custom configuration directory.
   The following example file is named customScript.sh.

       #!/bin/bash

           # Define the image name and tag
       IMAGE_NAME="pysrv:customScript"
           # Custom configuration files are at relative path conf/FILE
       DOCKERFILE_NAME="conf/Dockerfile"
           # Command to check if image exists
       COMMAND="docker inspect ${IMAGE_NAME}"

           # Run the command then check the status code
       $COMMAND
       RESULT=$?
       if [ $RESULT -ne 0 ]; then
       	# Image did not exist
       	echo ${IMAGE_NAME} does not exist. Building now...
       	COMMAND="docker build -f ${DOCKERFILE_NAME} -t ${IMAGE_NAME} ."
       	echo ${COMMAND}
       	echo "Building the custom docker image ${IMAGE_NAME} for the python-
       service"
       	$COMMAND
       	echo "Completed building ${IMAGE_NAME}"
       else
       	# Image exists already
       	echo The requested image ${IMAGE_NAME} already exists.
       fi

8. Edit the relevant properties in the custom.properties file, specifying using the custom script.

       use.engine.containers: TRUE
       docker.image.name: pysrv:customScript
       startup.hook.script: conf/customScript.sh

9. On the computer running the Spotfire Server, import the service configuration:

       config import-service-config --config-name=<new-config-name>

   See the import-service-config page in the Spotfire® Server and Environment - Installation and Administration guide for more information.
10. From the Spotfire Server Nodes & Services administration page, install the service, specifying the configuration to use, and then start the service.

    If you have already installed the service, then, under the node manager, select the service and click Edit. From the Configuration drop-down list, select the new configuration.

If problems occur, troubleshoot by examining the Dockerfile that the service writes. After the service runs, this Dockerfile is available at the root service directory on the computer running the node manager. For example, /opt/nodemanager/<version>/nm/services/<language>-service-linux-<version_#_ID>/dockerfile/Dockerfile.