Read-Only File System Mode
This feature is a closed beta.
Overview
Companies may have a security requirement to run containers in “read-only file system” mode.
For an application like Mend.io’s Repository Integrations, this can be complex to support due to Mend.io’s Scanning and Remediation containers inherently needing to read-write a large amount of data, such as to clone repositories. Additionally, Mend.io containers may need to run tools like npm and maven which write data to the file system themselves.
Support Status
Read-only file systems for Mend.io Repository Integrations are now supported, starting with release 24.12.1.2. It has been verified by Mend so far with the following:
Mend for GitHub Enterprise
Application, SCA Scanner and Remediate containers
No dynamic/runtime tool installation support (tools must be pre-installed as part of image builds, as if the default behavior)
Getting it done
Mend.io has done work to:
Consolidate language and package manager tools to use /tmp where possible
Map known “home directory” folder such as .m2 to locations in /tmp
Document the remaining locations which must allow read-write at runtime
The intended outcome of read-only file system support is that Repository Integrations retain the same functionality, with read-only file system enabled. There is no particular “new” behavior to observe.
Configuration
To activate read-only file system mode requires you to:
Configure containers to read-only mode, using your container runtime of choice
Map certain locations to read-write volumes per-container
Set environment variables to steer applications and programming languages to use /tmp instead of $HOME
Volumes
These are the specific read-write volumes needed by each container:
Controller
/tmp
/etc/usr/local/whitesource
Scanner
/tmp
/home/wss-scanner/whitesource
/etc/usr/local/whitesource/scm-scanner
Remediate Server
/tmp
Remediate Worker
/tmp
While the majority of locations above can be non-persistent (e.g. /tmp), the directory /etc/usr/local/whitesource contains an important file which must be both readable and writable, and persisted across any reboots - it cannot be wiped/empty at startup.
It’s also very important that “scaled” containers do not share the same volumes, e.g. you cannot have multiple Scanners reading/writing to a shared /tmp contents.
The way to configure read-only mode and volume mapping varies per hosting type. An example is given below in the Examples section.
Environment Variables
For some package managers, it’s necessary to configure environment variables so that they don’t perform a check on whether $HOME is writable (it is not).
Ruby example:
GEM_HOME: /tmp
GEM_PATH: /tmp
Example
The following example Docker Compose configuration shows how to configure the four container types:
services:
remediate-server:
image: wss-remediate:24.12.1.1
container_name: remediate-server
read_only: true
ports:
- "8083:8080"
volumes:
- "remediate-server_tmp:/tmp"
restart: always
remediate-worker:
image: wss-remediate:24.12.1.1
container_name: remediate-worker
read_only: true
ports:
- "8084:8080"
volumes:
- "remediate-worker_tmp:/tmp"
restart: always
depends_on:
- remediate-server
app:
image: wss-ghe-app:24.12.1.1
container_name: wss-ghe-app
read_only: true
ports:
- "9494:9494"
- "5678:5678"
volumes:
- "controller_tmp:/tmp"
- "controller-whitesource:/etc/usr/local/whitesource"
restart: always
depends_on:
- remediate-server
scanner:
image: wss-scanner:24.12.1.2
container_name: wss-scanner-ghe
read_only: true
ports:
- "9393:9393"
- "4000:4000"
volumes:
- "scanner-tmp:/tmp"
- "scanner-home_whitesource:/home/wss-scanner/whitesource"
- "scanner-scm_scanner:/etc/usr/local/whitesource/scm-scanner"
restart: always
depends_on:
- app
environment:
GEM_HOME: /tmp/gems
GEM_PATH: /tmp/gems
volumes:
controller_tmp:
controller-whitesource:
scanner-tmp:
scanner-home_whitesource:
scanner-scm_scanner:
remediate-server_tmp:
remediate-worker_tmp:
networks:
default:
name: my_bridge
external: false
Limitations and Unknowns
Scan log cleanup in /tmp
The SCA Scanner uses /tmp for temporary log storage. Normally when /tmp is not mapped to a persistent volume then this means that such logs are automatically “cleaned up” by container reboots after each scan. Now with persistent /tmp volumes, it means scan logs are persisted indefinitely.
Mend.io is adding an opt-in feature to configure the erasing of /tmp at each container start if desired.
Kubernetes Testing
Testing has primarily been performed using Docker Compose. Although Kubernetes supports the concept of read-only FS and persistent volumes, the volumes in particular aren’t implemented identically to Docker compose. In particular it’s important to make sure that the Controller’s /etc/usr/local/whitesource directory is copied (once) to the persistent volume before mounting, because unlike Docker, Kubernetes does not perform this copying automatically.