Skip to content

Commit f9fb6ed

Browse files
rhatdancursoragent
andcommitted
Add --engine-args flag for custom container engine arguments
Implement a new --engine-args flag that allows users to pass additional arguments directly to the container engine (podman/docker). This provides flexibility for advanced users who need to customize container behavior beyond what RamaLama's built-in flags offer. The flag is named --engine-args (not --container-args) to clarify that arguments are passed to the container engine, not the container itself. Changes: - Add --engine-args CLI argument in runtime_options() - Can be specified multiple times to add multiple arguments - Implement add_engine_args() method in Engine class - Arguments are appended directly to exec_args before execution - Add validation to conflict with --nocontainer flag - Add engine_args to BaseConfig for ramalama.conf support - Document flag in ramalama-run and ramalama-serve man pages - Include usage examples, config file examples, and conflict documentation Configuration file support: Users can set default engine args in ramalama.conf: ```toml [ramalama] engine_args = ["--read-only", "--tmpfs /tmp"] ``` Use cases enabled: - Custom mounts: --engine-args '--mount type=bind,src=/data,dst=/data' - Additional env vars: --engine-args '--env CUSTOM_VAR=value' - Security options: --engine-args '--security-opt label=disable' - Read-only containers: --engine-args '--read-only' - Any other podman/docker run flags Tests: - Unit tests verify arguments are added to exec_args correctly - E2E dryrun tests verify arguments appear in engine command - Conflict tests verify --engine-args raises error with --nocontainer - All tests passing (5 new unit tests, 2 e2e tests) The arguments are passed directly to the container engine, allowing users to leverage the full power of podman/docker without RamaLama needing to explicitly support every possible container option. Fixes #2440 *This PR was created with the assistance of Cursor AI.* Co-authored-by: Cursor <[email protected]> Signed-off-by: Daniel J Walsh <[email protected]>
1 parent 1a46d4a commit f9fb6ed

12 files changed

Lines changed: 208 additions & 0 deletions

docs/ramalama-bench.1.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,24 @@ The device specification is passed directly to the underlying container engine.
4242
Pass '--device=none' explicitly add no device to the container, eg for
4343
running a CPU-only performance comparison.
4444

45+
#### **--engine-args**=*ARG*
46+
Additional arguments to pass to the container engine (Podman or Docker).
47+
This option can be specified multiple times to add multiple arguments.
48+
49+
This is useful for passing custom container options like additional mounts,
50+
environment variables, or other container-specific flags that RamaLama doesn't
51+
directly expose.
52+
53+
**Note**: This option conflicts with `--nocontainer` and can only be used when
54+
running with a container engine.
55+
56+
The default can be overridden in the `ramalama.conf` file:
57+
58+
```toml
59+
[ramalama]
60+
engine_args = ["--read-only", "--tmpfs /tmp"]
61+
```
62+
4563
#### **--env**=
4664

4765
Set environment variables inside of the container.

docs/ramalama-perplexity.1.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,24 @@ Example: --device=/dev/dri/renderD128:/dev/xvdc:rwm
4545

4646
The device specification is passed directly to the underlying container engine. See documentation of the supported container engine for more information.
4747

48+
#### **--engine-args**=*ARG*
49+
Additional arguments to pass to the container engine (Podman or Docker).
50+
This option can be specified multiple times to add multiple arguments.
51+
52+
This is useful for passing custom container options like additional mounts,
53+
environment variables, or other container-specific flags that RamaLama doesn't
54+
directly expose.
55+
56+
**Note**: This option conflicts with `--nocontainer` and can only be used when
57+
running with a container engine.
58+
59+
The default can be overridden in the `ramalama.conf` file:
60+
61+
```toml
62+
[ramalama]
63+
engine_args = ["--read-only", "--tmpfs /tmp"]
64+
```
65+
4866
#### **--env**=
4967

5068
Set environment variables inside of the container.

docs/ramalama-run.1.md

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,41 @@ The device specification is passed directly to the underlying container engine.
6060
Pass '--device=none' explicitly add no device to the container, eg for
6161
running a CPU-only performance comparison.
6262

63+
#### **--engine-args**=*ARG*
64+
Additional arguments to pass to the container engine (Podman or Docker).
65+
This option can be specified multiple times to add multiple arguments.
66+
67+
This is useful for passing custom container options like additional mounts,
68+
environment variables, or other container-specific flags that RamaLama doesn't
69+
directly expose.
70+
71+
**Note**: This option conflicts with `--nocontainer` and can only be used when
72+
running with a container engine.
73+
74+
The default can be overridden in the `ramalama.conf` file:
75+
76+
```toml
77+
[ramalama]
78+
engine_args = ["--read-only", "--tmpfs /tmp"]
79+
```
80+
81+
Examples:
82+
```bash
83+
# Add a custom mount
84+
ramalama run --engine-args '--mount type=bind,src=/data,dst=/data' granite
85+
86+
# Add multiple environment variables
87+
ramalama run --engine-args '--env CUSTOM_VAR=value' \
88+
--engine-args '--env ANOTHER_VAR=test' granite
89+
90+
# Combine multiple options
91+
ramalama run --engine-args '--read-only' \
92+
--engine-args '--tmpfs /tmp' granite
93+
```
94+
95+
Note: These arguments are passed directly to the container engine, so they must
96+
use the syntax expected by podman or docker.
97+
6398
#### **--env**=
6499

65100
Set environment variables inside of the container.

docs/ramalama-serve.1.md

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,36 @@ running a CPU-only performance comparison.
8585
#### **--dri**=*on* | *off*
8686
Enable or disable mounting `/dev/dri` into the container when running with `--api=llama-stack` (enabled by default). Use to prevent access to the host device when not required, or avoid errors in environments where `/dev/dri` is not available.
8787

88+
#### **--engine-args**=*ARG*
89+
Additional arguments to pass to the container engine (podman or docker).
90+
This option can be specified multiple times to add multiple arguments.
91+
92+
This is useful for passing custom container options like additional mounts,
93+
environment variables, or other container-specific flags that RamaLama doesn't
94+
directly expose.
95+
96+
**Note**: This option conflicts with `--nocontainer` and can only be used when
97+
running with a container engine.
98+
99+
The default can be overridden in the `ramalama.conf` file:
100+
101+
```toml
102+
[ramalama]
103+
engine_args = ["--read-only", "--tmpfs /tmp"]
104+
```
105+
106+
Examples:
107+
```bash
108+
# Add a custom mount
109+
ramalama serve --engine-args '--mount type=bind,src=/data,dst=/data' granite
110+
111+
# Add security options
112+
ramalama serve --engine-args '--security-opt label=disable' granite
113+
```
114+
115+
Note: These arguments are passed directly to the container engine, so they must
116+
use the syntax expected by podman or docker.
117+
88118
#### **--env**=
89119

90120
Set environment variables inside of the container.

docs/ramalama.conf

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,16 @@
5757
# Valid options (Podman, Docker)
5858
#engine = "podman"
5959

60+
# Additional arguments to pass directly to the container engine (Podman or Docker)
61+
# This allows specifying custom container engine flags that RamaLama doesn't
62+
# directly expose. Only valid when using containers (conflicts with --nocontainer)
63+
#
64+
# Examples:
65+
# engine_args = ["--read-only", "--tmpfs /tmp"]
66+
# engine_args = ["--mount type=bind,src=/data,dst=/data", "--env CUSTOM_VAR=value"]
67+
#
68+
#engine_args = []
69+
6070
# Environment variables to be added when running model within a container
6171
#
6272
#env = []

docs/ramalama.conf.5.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,26 @@ Run RamaLama using the specified container engine.
106106
Valid options are: Podman and Docker
107107
This field can be overridden by the RAMALAMA_CONTAINER_ENGINE environment variable.
108108

109+
**engine_args**=[]
110+
111+
Additional arguments to pass directly to the container engine (Podman or Docker).
112+
This option allows specifying custom container engine flags that RamaLama doesn't
113+
directly expose as CLI options. Multiple arguments can be specified as an array.
114+
Only valid when using containers (conflicts with --nocontainer).
115+
116+
Examples:
117+
```toml
118+
engine_args = ["--read-only", "--tmpfs /tmp"]
119+
```
120+
121+
Or:
122+
```toml
123+
engine_args = [
124+
"--mount type=bind,src=/data,dst=/data",
125+
"--env CUSTOM_VAR=value"
126+
]
127+
```
128+
109129
**env**=[]
110130

111131
Environment variables to be added to the environment used when running in a container engine (e.g., Podman, Docker). For example "LLAMA_ARG_THREADS=10".

ramalama/cli.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -351,6 +351,10 @@ def post_parse_setup(args):
351351
if getattr(args, "subcommand", None) == "benchmark":
352352
args.subcommand = "bench"
353353

354+
# Validate that --engine-args is only used with containers
355+
if getattr(args, "engine_args", None) and not getattr(args, "container", True):
356+
raise ValueError("--engine-args can only be used with container mode (conflicts with --nocontainer)")
357+
354358
def map_https_to_transport(input: str) -> str:
355359
if input.startswith("https://") or input.startswith("http://"):
356360
url = urlparse(input)
@@ -1060,6 +1064,16 @@ def runtime_options(parser, command):
10601064
action="store_true",
10611065
help="""pass `--group-add keep-groups` to podman.
10621066
If GPU device on host is accessible to via group access, this option leaks the user groups into the container.""",
1067+
)
1068+
parser.add_argument(
1069+
"--engine-args",
1070+
dest="engine_args",
1071+
action='append',
1072+
type=str,
1073+
default=config.engine_args,
1074+
help="""additional arguments to pass to the container engine
1075+
(e.g., '--mount type=bind,src=/path,dst=/path' or '--env VAR=value').
1076+
Only valid when using containers (conflicts with --nocontainer)""",
10631077
)
10641078
if command == "run":
10651079
parser.add_argument(

ramalama/config.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,7 @@ class BaseConfig:
250250
default_rag_image: str = DEFAULT_RAG_IMAGE
251251
dryrun: bool = False
252252
engine: SUPPORTED_ENGINES | None = field(default_factory=get_default_engine)
253+
engine_args: list[str] = field(default_factory=list)
253254
env: list[str] = field(default_factory=list)
254255
gguf_quantization_mode: GGUF_QUANTIZATION_MODES = DEFAULT_GGUF_QUANTIZATION_MODE
255256
host: str = "0.0.0.0"

ramalama/engine.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,15 @@ def handle_podman_specifics(self):
116116
if getattr(self.args, "podman_keep_groups", None):
117117
self.exec_args += ["--group-add", "keep-groups"]
118118

119+
def add_engine_args(self):
120+
"""Add custom engine arguments specified by the user."""
121+
engine_args = getattr(self.args, "engine_args", None)
122+
if engine_args:
123+
import shlex
124+
125+
for arg in engine_args:
126+
self.exec_args.extend(shlex.split(arg))
127+
119128
def add(self, newargs: Sequence[str]):
120129
self.exec_args.extend(newargs)
121130

@@ -152,6 +161,7 @@ def __init__(self, args: BaseEngineArgsType) -> None:
152161
self.add_detach_option()
153162
self.add_device_options()
154163
self.add_env_options()
164+
self.add_engine_args()
155165
self.add_port_option()
156166
self.add_tty_option()
157167

test/e2e/test_run.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,14 @@ def test_basic_dry_run():
224224
pytest.param(
225225
["--device", "none", "--pull", "never"], r".*--device.*", None, None, False, None,
226226
id="check --device with unsupported value", marks=skip_if_no_container),
227+
pytest.param(
228+
["--engine-args", "--read-only"], r".*--read-only.*", None, None, True, None,
229+
id="check --engine-args with single arg", marks=skip_if_no_container),
230+
pytest.param(
231+
["--engine-args", "--mount type=bind,src=/data,dst=/data",
232+
"--engine-args", "--env CUSTOM_VAR=value"],
233+
r".*--mount type=bind,src=/data,dst=/data.*--env CUSTOM_VAR=value.*", None, None, True, None,
234+
id="check --engine-args with multiple args", marks=skip_if_no_container),
227235
],
228236
)
229237
# fmt: on

0 commit comments

Comments
 (0)