7.5 KiB
Running media-img as a service
media-img is a normal console process: it has no dedicated config file for serve / ipc (no port in TOML/JSON inside this repo). You configure it with command-line arguments (and optionally environment variables such as VIPS_CONCURRENCY).
At startup it loads .env from the current working directory if present (dotenv-cpp), so you can set env vars without a separate “config file” for ports—though bind address and port are still CLI flags, not read from .env unless you wrap the binary.
Practical approaches:
| Approach | Use when |
|---|---|
| Flags only in the unit / wrapper | Simplest; edit the service definition when ports change. |
EnvironmentFile= (systemd) or NSSM env |
Centralize VIPS_CONCURRENCY, cache paths, etc.; still pass --port / --host in ExecStart or via a tiny wrapper script. |
| Wrapper script | Reads env or a small file and execs media-img with the right flags. |
Defaults if you omit flags: --host 127.0.0.1 -p 8080 for serve, and --host 127.0.0.1 -p 9333 for ipc (see media-img serve --help / ipc --help).
Linux: systemd (systemctl)
Install the binary somewhere stable (e.g. /usr/local/bin/media-img) and ensure libvips and its dependencies are on the system LD_LIBRARY_PATH if you did not link statically.
1. REST service (serve)
Create /etc/systemd/system/media-img-serve.service:
[Unit]
Description=media-img HTTP REST (libvips resize)
After=network.target
[Service]
Type=simple
User=mediaimg
Group=mediaimg
WorkingDirectory=/var/lib/media-img
# Optional: VIPS_CONCURRENCY, cache location, etc.
# EnvironmentFile=-/etc/default/media-img
# Or: ExecStart=/usr/local/bin/run-media-img.sh (see scripts/run-media-img.sh + /etc/default/media-img)
ExecStart=/usr/local/bin/media-img serve --host 127.0.0.1 --port 8080 --cache-dir /var/cache/media-img
Restart=on-failure
RestartSec=3
# Hardening (tune for your layout)
NoNewPrivileges=true
PrivateTmp=true
[Install]
WantedBy=multi-user.target
Create user/dirs if needed:
sudo useradd -r -s /usr/sbin/nologin -d /var/lib/media-img mediaimg
sudo mkdir -p /var/lib/media-img /var/cache/media-img
sudo chown mediaimg:mediaimg /var/lib/media-img /var/cache/media-img
Enable and start:
sudo systemctl daemon-reload
sudo systemctl enable --now media-img-serve
sudo systemctl status media-img-serve
journalctl -u media-img-serve -f
Optional /etc/default/media-img (referenced by EnvironmentFile=):
# Not used for --port unless you add a wrapper script; useful for libvips:
VIPS_CONCURRENCY=4
2. IPC service (ipc TCP or Unix socket)
Use a second unit, e.g. media-img-ipc.service, with a different ExecStart:
ExecStart=/usr/local/bin/media-img ipc --host 127.0.0.1 --port 9333 --cache-dir /var/cache/media-img
Or Unix socket on Linux:
ExecStart=/usr/local/bin/media-img ipc --unix /run/media-img/ipc.sock --cache-dir /var/cache/media-img
RuntimeDirectory=media-img
3. Firewall
If you bind beyond 127.0.0.1, open the port in firewalld / ufw as usual.
Windows: running as a service
pm-image.exe does not register with the Windows Service Control Manager by itself. Use a service wrapper that runs your command line as a service.
Option A — NSSM (Non-Sucking Service Manager)
- Install NSSM.
- Either run
pm-image.exedirectly or usescripts/run-media-img.ps1withMEDIA_IMG_*env vars (see Wrapper scripts).
Direct executable:
nssm install MediaImgServe "C:\Apps\media\pm-image.exe"
nssm set MediaImgServe AppDirectory "C:\Apps\media"
nssm set MediaImgServe AppParameters "serve --host 127.0.0.1 --port 8080 --cache-dir C:\Apps\media\cache\images"
nssm set MediaImgServe AppStdout "C:\Apps\media\logs\serve.log"
nssm set MediaImgServe AppStderr "C:\Apps\media\logs\serve.err.log"
nssm set MediaImgServe AppEnvironmentExtra "VIPS_CONCURRENCY=4"
nssm start MediaImgServe
- Ensure DLLs (libvips) are on
PATHor next to the exe, as in your dev layout.
Option B — WinSW
Use WinSW with an XML that points executable to pm-image.exe and passes serve arguments in arguments.
Option C — Task Scheduler
Not a true service, but often enough: run pm-image.exe serve ... at logon or startup with “Run whether user is logged on or not”. No SCM integration; fewer recovery options than NSSM.
Firewall
Allow the chosen TCP port in Windows Defender Firewall if clients are remote.
Wrapper scripts (ports via environment)
The repo includes small wrappers so you can set bind address, port, and cache dir from the environment (e.g. systemd EnvironmentFile, NSSM, or CI) without editing the unit XML every time:
| Script | Platform |
|---|---|
scripts/run-media-img.sh |
Linux / macOS / Git Bash |
scripts/run-media-img.ps1 |
Windows (PowerShell) |
Environment variables (both scripts):
| Variable | Meaning |
|---|---|
MEDIA_IMG_CMD |
serve (default) or ipc |
MEDIA_IMG_BIN |
Path to media-img / pm-image.exe (optional; scripts default to PATH or dist/ next to the script) |
MEDIA_IMG_HOST |
Bind address (default 127.0.0.1) |
MEDIA_IMG_PORT |
TCP port — default 8080 for serve, 9333 for ipc |
MEDIA_IMG_CACHE_DIR |
Passed as --cache-dir if set |
MEDIA_IMG_NO_CACHE |
Set to 1 to add --no-cache |
MEDIA_IMG_IPC_UNIX |
Linux .sh only: if set with MEDIA_IMG_CMD=ipc, uses --unix instead of TCP |
Install the shell script on Linux: chmod +x scripts/run-media-img.sh, copy to e.g. /usr/local/bin/, then:
EnvironmentFile=-/etc/default/media-img
ExecStart=/usr/local/bin/run-media-img.sh
Example /etc/default/media-img:
MEDIA_IMG_CMD=serve
MEDIA_IMG_HOST=127.0.0.1
MEDIA_IMG_PORT=8080
MEDIA_IMG_CACHE_DIR=/var/cache/media-img
VIPS_CONCURRENCY=4
Windows (NSSM) — point the service at PowerShell and the script, then set MEDIA_IMG_* in the NSSM GUI (Environment tab) or via nssm edit (recommended for several variables):
nssm install MediaImgServe "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe"
nssm set MediaImgServe AppDirectory "C:\Apps\media"
nssm set MediaImgServe AppParameters "-NoProfile -ExecutionPolicy Bypass -File C:\Apps\media\scripts\run-media-img.ps1"
Example environment entries: MEDIA_IMG_CMD=serve, MEDIA_IMG_PORT=8080, MEDIA_IMG_CACHE_DIR=C:\Apps\media\cache\images, VIPS_CONCURRENCY=4.
Do you need config files?
No, not for media-img itself—ports and bind addresses are normally CLI flags. The wrappers above map environment variables to those flags. Optional extras:
- systemd
EnvironmentFileforMEDIA_IMG_*andVIPS_CONCURRENCY. .envbesideWorkingDirectoryfor variablesmedia-imgloads itself (see main README); it does not set--portunless you use the wrapper.
For a database or other apps in the same repo, config/postgres.toml is unrelated to media-img HTTP/IPC ports.