Powered by Zoomin Software. For more details please contactZoomin

Install Semaphore on Linux

Run Progress-supplied Docker images with Docker Compose

Run Progress-supplied Docker images with Docker Compose

  • Last Updated: July 8, 2026
  • 5 minute read
    • Semaphore
    • Documentation

Using Docker Compose is recommended for running multiple Progress-supplied Semaphore containers on a single host. By using this method, you can use a single compose.yml to describe the services, networks, and volumes. In addition, a single command can be used to start, stop, and upgrade all containers.

In this topic, we cover the following:

Example compose file

The following compose.yml runs Semaphore Studio with the Classification and Language Service, the Semantic Enhancement Server, and all required internal Semaphore services, including:

  • Document Analyzer (DA)
  • Rulebase Manager (RM)
  • SES Manager (SM)
  • Concepts Manager (CM)
  • Alerting
  • Knowledge Model Management (KMM)
  • KMM AI Assistant

To use this example, adjust the image tags, mount points, and credentials to match your environment.

Be aware that the example applies the following settings:

  • Recommended container security-hardening settings, including:
    • read_only: true
    • cap_drop: [ALL]
    • security_opt: [no-new-privileges:true]
  • Each service uses a dedicated tmpfs mount for temporary files.
  • Semaphore Studio declares depends_on with condition: service_healthy for internal services to help ensure the correct startup order.

Note that because all services are attached to the semaphore-network bridge network, Semaphore Studio can reach the other services using the Compose service names (cs, ses, da, rm, sm, cm, alerting, ai, kmm) as host names. When configuring Semaphore Studio, use the Compose service names as host names in the service URLs. For example, set the CS URL to http://cs:5058 and the SES URL to http://ses:8983/ses.

services:

  cs:
    image: semaphore-cs:5.10.4
    container_name: semaphore-cs
    read_only: true
    cap_drop:
      - ALL
    security_opt:
      - no-new-privileges:true
    tmpfs:
      - /var/opt/semaphore/CS/tmp:uid=185,gid=0
    restart: unless-stopped
    ports:
      - "5058:5058"
      - "5059:5059"
    volumes:
      - /mnt/cs-licence/licence:/opt/semaphore/licence:ro
      - /mnt/cs-data:/var/opt/semaphore/CS
    networks:
      - semaphore-network

  ses:
    image: semaphore-ses:5.10.4
    container_name: semaphore-ses
    read_only: true
    cap_drop:
      - ALL
    security_opt:
      - no-new-privileges:true
    tmpfs:
      - /var/opt/semaphore/SES/temp:uid=185,gid=0
    restart: unless-stopped
    ports:
      - "8983:8983"
    environment:
      - SOLR_JAVA_MEM=-Xms1g -Xmx4g
      - SEMAPHORE_LICENCE_DIR=/opt/semaphore/licence
    volumes:
      - /mnt/ses-licence:/opt/semaphore/licence:ro
      - /mnt/ses-config:/etc/opt/semaphore/SES
      - /mnt/ses-data:/var/opt/semaphore/SES/data
      - /mnt/ses-logs:/var/opt/semaphore/SES/logs
    networks:
      - semaphore-network

  da:
    image: semaphore-da:5.10.4
    container_name: semaphore-da
    read_only: true
    cap_drop:
      - ALL
    security_opt:
      - no-new-privileges:true
    tmpfs:
      - /var/opt/semaphore/da/temp:uid=185,gid=0
    restart: unless-stopped
    volumes:
      - /mnt/da-config:/etc/opt/semaphore/da
      - /mnt/da-data:/var/opt/semaphore/da/data
      - /mnt/da-logs:/var/opt/semaphore/da/logs
    healthcheck:
      test: ["CMD", "curl", "-sf", "http://localhost:5081/", "-o", "/dev/null"]
      interval: 30s
      timeout: 10s
      start_period: 60s
      retries: 3
    networks:
      - semaphore-network

  rm:
    image: semaphore-rm:5.10.4
    container_name: semaphore-rm
    read_only: true
    cap_drop:
      - ALL
    security_opt:
      - no-new-privileges:true
    tmpfs:
      - /var/opt/semaphore/rm/temp:uid=185,gid=0
    restart: unless-stopped
    volumes:
      - /mnt/rm-config:/etc/opt/semaphore/rm
      - /mnt/rm-data:/var/opt/semaphore/rm/data
      - /mnt/rm-logs:/var/opt/semaphore/rm/logs
    healthcheck:
      test: ["CMD", "curl", "-sf", "http://localhost:5083/", "-o", "/dev/null"]
      interval: 30s
      timeout: 10s
      start_period: 60s
      retries: 3
    networks:
      - semaphore-network

  sm:
    image: semaphore-sm:5.10.4
    container_name: semaphore-sm
    read_only: true
    cap_drop:
      - ALL
    security_opt:
      - no-new-privileges:true
    tmpfs:
      - /var/opt/semaphore/sm/temp:uid=185,gid=0
    restart: unless-stopped
    volumes:
      - /mnt/sm-config:/etc/opt/semaphore/sm
      - /mnt/sm-data:/var/opt/semaphore/sm/data
      - /mnt/sm-logs:/var/opt/semaphore/sm/logs
    healthcheck:
      test: ["CMD", "curl", "-sf", "http://localhost:5084/", "-o", "/dev/null"]
      interval: 30s
      timeout: 10s
      start_period: 60s
      retries: 3
    networks:
      - semaphore-network

  cm:
    image: semaphore-cm:5.10.4
    container_name: semaphore-cm
    read_only: true
    cap_drop:
      - ALL
    security_opt:
      - no-new-privileges:true
    tmpfs:
      - /var/opt/semaphore/cm/temp:uid=185,gid=0
    restart: unless-stopped
    volumes:
      - /mnt/cm-config:/etc/opt/semaphore/cm
      - /mnt/cm-data:/var/opt/semaphore/cm/data
      - /mnt/cm-logs:/var/opt/semaphore/cm/logs
    healthcheck:
      test: ["CMD", "curl", "-sf", "http://localhost:5085/", "-o", "/dev/null"]
      interval: 30s
      timeout: 10s
      start_period: 60s
      retries: 3
    networks:
      - semaphore-network

  alerting:
    image: semaphore-alerting:5.10.4
    container_name: semaphore-alerting
    read_only: true
    cap_drop:
      - ALL
    security_opt:
      - no-new-privileges:true
    tmpfs:
      - /var/opt/semaphore/alerting/temp:uid=185,gid=0
    restart: unless-stopped
    environment:
      - QUARKUS_MAILER_HOST=smtp.example.com
      - QUARKUS_MAILER_PORT=587
      - QUARKUS_MAILER_USERNAME=alerting@example.com
      - QUARKUS_MAILER_PASSWORD=<password>
      - QUARKUS_MAILER_FROM=alerting@example.com
    volumes:
      - /mnt/alerting-config:/etc/opt/semaphore/alerting
      - /mnt/alerting-data:/var/opt/semaphore/alerting/data
      - /mnt/alerting-logs:/var/opt/semaphore/alerting/logs
    healthcheck:
      test: ["CMD", "curl", "-sf", "http://localhost:5086/application/info", "-o", "/dev/null"]
      interval: 30s
      timeout: 10s
      start_period: 60s
      retries: 3
    networks:
      - semaphore-network

  ai:
    image: semaphore-ai:5.10.4
    container_name: semaphore-ai
    read_only: true
    cap_drop:
      - ALL
    security_opt:
      - no-new-privileges:true
    tmpfs:
      - /var/opt/semaphore/ai/temp:uid=185,gid=0
    restart: unless-stopped
    volumes:
      - /mnt/ai-config:/etc/opt/semaphore/ai
      - /mnt/ai-data:/var/opt/semaphore/ai/data
      - /mnt/ai-logs:/var/opt/semaphore/ai/logs
    healthcheck:
      test: ["CMD", "curl", "-sf", "http://localhost:5087/application/info", "-o", "/dev/null"]
      interval: 30s
      timeout: 10s
      start_period: 60s
      retries: 3
    networks:
      - semaphore-network

  kmm:
    image: semaphore-kmm:5.10.4
    container_name: semaphore-kmm
    read_only: true
    cap_drop:
      - ALL
    security_opt:
      - no-new-privileges:true
    tmpfs:
      - /var/opt/semaphore/kmm/temp:uid=185,gid=0
    restart: unless-stopped
    volumes:
      - /mnt/kmm-config:/etc/opt/semaphore/kmm
      - /mnt/kmm-data:/var/opt/semaphore/kmm/workspace
      - /mnt/kmm-logs:/var/opt/semaphore/kmm/logs
      - /mnt/studio-data/licenses:/var/opt/semaphore/studio/data/licenses:ro
    depends_on:
      alerting:
        condition: service_healthy
    healthcheck:
      test: ["CMD", "curl", "-sf", "http://localhost:5082/", "-o", "/dev/null"]
      interval: 30s
      timeout: 10s
      start_period: 60s
      retries: 3
    networks:
      - semaphore-network

  studio:
    image: semaphore-studio:5.10.4
    container_name: semaphore-studio
    read_only: true
    cap_drop:
      - ALL
    security_opt:
      - no-new-privileges:true
    tmpfs:
      - /var/opt/semaphore/studio/temp:uid=185,gid=0
    restart: unless-stopped
    ports:
      - "5080:5080"
    environment:
      - STUDIO_LOG_LEVEL=WARN
      - JVM_OPTS_APPEND=-Xms128M -Xmx2048M
      - STUDIO_KMM_URL=http://kmm:5082/
      - STUDIO_DA_URL=http://da:5081/
      - STUDIO_RM_URL=http://rm:5083/
      - STUDIO_SM_URL=http://sm:5084/
      - STUDIO_CM_URL=http://cm:5085/
      - STUDIO_AI_URL=http://ai:5087/
    volumes:
      - /mnt/studio-config:/etc/opt/semaphore/studio
      - /mnt/studio-data/tdb:/var/opt/semaphore/studio/data/tdb
      - /mnt/studio-data/licenses:/var/opt/semaphore/studio/data/licenses
      - /mnt/studio-logs:/var/opt/semaphore/studio/logs
    depends_on:
      kmm:
        condition: service_healthy
      da:
        condition: service_healthy
      rm:
        condition: service_healthy
      sm:
        condition: service_healthy
      cm:
        condition: service_healthy
      alerting:
        condition: service_healthy
      ai:
        condition: service_healthy
    healthcheck:
      test: ["CMD", "curl", "-sf", "http://localhost:5080/", "-o", "/dev/null"]
      interval: 30s
      timeout: 10s
      start_period: 60s
      retries: 3
    networks:
      - semaphore-network

networks:
  semaphore-network:
    name: semaphore-network

The :ro suffix on the licence volume mount makes the directory read-only inside the container. The read_only: true setting makes the entire container root filesystem read-only. Only explicitly mounted volumes and tmpfs mounts are writable.

Important: The Semaphore Studio licenses directory must be mounted read-write (do not use :ro). The KMM licence mount may remain read-only. See Licence directory requirements for details.

For details on the dual URL configuration required by CS, SES, and the Concepts Server (Inter-Service URL vs Client URL), see Run individual Progress-supplied Docker images.

Common commands

This section describes some common commands for Docker Compose that you might need to use with your Semaphore deployment.

Note that these commands should be issued from the directory containing your compose.yml file.

Refer to the Docker Compose documentation for the full command reference.

  • docker compose pull: Pulls the configured image versions.

  • docker compose up -d: Creates and starts all services in the background.

  • docker compose ps: Displays the status of running services.

  • docker compose logs -f <service>: Follows the logs for a service.

  • docker compose stop: Stops the services without removing the containers.

  • docker compose down: Stops and removes the containers (mounted volumes are preserved).

Upgrading

To upgrade your Semaphore deployment to a newer release:

  1. Stop the running services by executing the following command:

    docker compose stop
    

    Stopping the services prevents files from changing when backing up the deployment.

  2. Back up every host directory that is mounted into a container. Although mounted volumes are preserved when containers are recreated, a new image may apply schema or on-disk migrations that cannot be reversed by reverting the image tag. A file-system snapshot or copy makes it possible to roll back if necessary. For example:

    tar czf semaphore-backup-$(date +%F).tgz \
       /mnt/cs-data \
       /mnt/ses-config /mnt/ses-data /mnt/ses-logs \
       /mnt/studio-config /mnt/studio-data
    
  3. Update the image tags in compose.yml. For example, change semaphore-studio:5.10.3 to semaphore-studio:5.10.4.

  4. Pull the new images:

    docker compose pull
    
  5. Recreate the containers with the new images:

    docker compose up -d
    

Result: The containers are now running the new image version. Mounted configuration and data directories are preserved, so the new containers start with the existing state.

TitleResults for “How to create a CRG?”Also Available inAlert