How to run SavaPage in Docker

This is a guide by example on how to deploy SavaPage in a Docker container.

#install Docker + Compose
sudo apt install docker.io docker-compose-v2 
# add yourself to docker group
sudo usermod -aG docker $(whoami)
mkdir -p ~/Docker-containers/savapage 
cd ~/Docker-containers/savapage

Copy files below to ~/Docker-containers/savapage

Docker containers are ephemeral by default. Changes made to a container's filesystem won't persist after the container stops.

There are a few different approaches to managing persistent data. The most common is to use a Docker Volume. Volumes are storage units that are mounted into container filesystems. Any data in a volume will remain intact after its linked container stops, letting you connect another container in the future.

docker-compose.yml
services:
  savapage:
    hostname: sp-server
    image: savapage
    container_name: savapage
    environment:
      TZ: Europe/Amsterdam
    env_file: docker.env
    ports:
      # CUPS
      - "127.0.0.1:6631:631"
      - "[::1]:6631:631"
      # http
      #- "127.0.0.1:8641:8631"
      #- "[::1]:8641:8631"
      # https
      - "127.0.0.1:8642:8632"
      - "[::1]:8642:8632"
    networks:
      # IP address assigned by Docker ...
      #- savapage_network
 
      # IP address self assigned example
      savapage_network:
        ipv4_address: 172.20.0.10
        aliases:
            - sp-server
    volumes:
      - savapage_custom:/opt/savapage/server/custom
      - savapage_data:/opt/savapage/server/data
      - savapage_ext:/opt/savapage/server/ext
      - savapage_logs:/opt/savapage/server/logs
      - savapage_cups:/etc/cups
    restart: always

  postgres:
    hostname: sp-postgres
    image: postgres
    container_name: postgres
    ports:
      - "5442:5432"
    networks:
      # IP address self assigned example
      savapage_network:
        ipv4_address: 172.20.0.20
        aliases:
            - savapage-postgres
    volumes:
      - savapage_database:/var/lib/postgresql/data
    restart: always

networks:
  savapage_network:
    driver: bridge
    # IP address self assigned example
    ipam:
      config:
        - subnet: 172.20.0.0/16

volumes:
  savapage_custom:
    driver: local
  savapage_data:
    driver: local
  savapage_ext:
    driver: local
  savapage_database:
    driver: local
  savapage_logs:
    driver: local
  savapage_cups:
    driver: local
Important SP_CONTAINER=DOCKER is required for Docker container.
docker.env
# Namespace as prefix for SavaPage envvar names (mandatory)
SAVAPAGE_NS=SP_
 
# Required for Docker container **
SP_CONTAINER=DOCKER
 
# Unique SP_SRV_* variables with server.properties key/value 
# separated by ':' like SP_SRV_n=key:value
 
# For example:
SP_SRV_01=visitor.organization:Acme Corporation
SP_SRV_02=server.port:8080
SP_SRV_03=server.ssl.port:8443
 
SP_SRV_11=database.type:PostgreSQL
SP_SRV_12=database.driver:org.postgresql.Driver
SP_SRV_13=database.url:jdbc:postgresql://savapage-postgres:5432/savapage
SP_SRV_14=database.user:sp-user
SP_SRV_15=database.password:my-password
 
# Do NOT redirect: disable http by not exposing 
# port 8631 as 8641 in docker-compose.yml
# SP_SRV_20=server.html.redirect.ssl:true

A Dockerfile describes how to run your service by installing required software and copying in files.

Dockerfile
FROM debian:bookworm
 
RUN apt update && apt install --no-install-recommends --no-install-suggests -y binutils cpio \
    cups cups-bsd debianutils default-jdk-headless gzip imagemagick librsvg2-bin perl poppler-utils \
    qpdf supervisor wkhtmltopdf libheif-examples vim-tiny findutils apt-utils iputils-ping \
    gnupg curl hplip
 
COPY supervisord.conf /etc/supervisor/conf.d/supervisord.conf
COPY docker.env /etc/environment
 
RUN useradd -rmd /opt/savapage -s /bin/bash -G lpadmin savapage && chown savapage:savapage /opt/savapage
# Create persistent password for admin tasks in CUPS web interface.
RUN echo 'savapage:mysecret' | chpasswd
 
ENV SAVAPAGE_VERSION=1.6.0-rc
ENV SAVAPAGE_NS=SP_
ENV SP_CONTAINER=DOCKER
 
USER savapage
COPY ./savapage-setup-${SAVAPAGE_VERSION}-linux-x64.bin /opt/savapage/savapage-setup.bin
RUN ["bash", "/opt/savapage/savapage-setup.bin", "-n"]
USER root
RUN ["/opt/savapage/server/bin/linux-x64/roottasks", "pam"]
 
EXPOSE 631 8631 8632
 
CMD ["/usr/bin/supervisord", "-c", "/etc/supervisor/supervisord.conf"]
supervisord.conf
[supervisord]
nodaemon=true
 
[program:cupsd]
command=/usr/sbin/cupsd -f
autostart=true
autorestart=true
 
[program:cupsctl]
command=/usr/sbin/cupsctl --remote-any
autostart=true
autorestart=true
 
[program:savapage-cups-notifier]
command=/opt/savapage/providers/cups/linux-x64/roottasks
autostart=true
autorestart=true
user=root
 
[program:savapage]
command=/opt/savapage/server/bin/linux-x64/app-server start
autostart=true
autorestart=true
user=savapage

Before you start:

  • Download the right ${SAVAPAGE_VERSION} to ./savapage-setup-${SAVAPAGE_VERSION}-linux-x64.bin
    • Make sure the build date is March 22, 2025 or later.
  • Execute in ~/Docker-containers/savapage
build.sh
#!/bin/bash
 
# Use Dockerfile to construct the image and tag as "savapage".
# Execute if any of the Docker files changed.
docker build -t savapage . 2>&1 | tee ./build.log
start.sh
#!/bin/bash
#--------------------------
# Start SavaPage container
#--------------------------
cd ~/Docker-containers/savapage 
docker compose up -d
stop.sh
#!/bin/bash
#--------------------------
# Stop SavaPage container
#--------------------------
cd ~/Docker-containers/savapage 
docker compose down
exec-it-savapage.sh
#!/bin/bash
#---------------------------------------
# Execute command in SavaPage container
#---------------------------------------
docker exec -it savapage bash
exec-it-postgres.sh
#!/bin/bash
#---------------------------------------
# Execute command in Postgres container
#---------------------------------------
docker exec -it postgres bash
# Check running containers
docker ps
 
# What's in the SavaPage-container?
docker exec -it savapage bash
 
# List docker volumes
docker volume ls
 
# List processes
docker ps -a
 
# List images
docker images
 
# List dangling images
docker images -f dangling=true
 
# Remove all the dangling images
docker system prune
Note Password for CUPS admin savapage is set in Dockerfile

CUPS Web interface: http://127.0.0.1:6631/printers/

https://docs.docker.com/reference/cli/docker/image/rm/

# List images
docker images
# ... and remove savapage
docker image rm savapage

https://docs.docker.com/reference/cli/docker/volume/rm/

# List volumes
docker volume ls
# ... and remove them
docker volume rm savapage_savapage_custom
docker volume rm savapage_savapage_data
docker volume rm savapage_savapage_database
docker volume rm savapage_savapage_ext
docker volume rm savapage_savapage_logs
  • howto/docker.txt
  • Last modified: 2025/05/31 19:13
  • by rijk