Run it on a server
This page sets up Spark on a Linux server as a systemd service, with a reverse proxy for TLS. The examples use spark.example.com. Replace it with your own domain. To run Spark in Docker instead, see Run it in Docker.
Spark serves plain HTTP. For anything reachable beyond your own network, put a reverse proxy that terminates TLS in front of it, such as Caddy, nginx or your load balancer. Keep SPARK_REQUIRE_API_KEY on, which is the default.
1. Install
Create a user for the service. Its home folder holds Spark's data and models:
sudo useradd --system --user-group --create-home --home-dir /var/lib/spark spark
Install the program into /opt/curiosity:
curl -fsSL https://raw.githubusercontent.com/curiosity-ai/spark/refs/heads/main/install.sh \
| sudo env SPARK_INSTALL=/opt/curiosity SPARK_NO_MODIFY_PATH=1 sh
2. Configure
Put the settings in /etc/spark.env, readable by root only, since it holds the console password:
sudo install -m 600 /dev/null /etc/spark.env
sudo nano /etc/spark.env
SPARK_ADMIN_PASSWORD=choose-a-long-password
SPARK_STORAGE=/var/lib/spark
SPARK_PORT=8080
Every other setting is in Settings. Put it in the same file.
3. Start the service
Create /etc/systemd/system/spark.service:
[Unit]
Description=Curiosity Spark
Wants=network-online.target
After=network-online.target
[Service]
User=spark
Group=spark
EnvironmentFile=/etc/spark.env
WorkingDirectory=/var/lib/spark
ExecStart=/opt/curiosity/spark/spark
Restart=on-failure
RestartSec=10
# Spark saves the live KV caches and stops its runners on SIGTERM.
TimeoutStopSec=60
[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reload
sudo systemctl enable --now spark
journalctl -u spark -f
4. Put TLS in front
With Caddy, which gets and renews a certificate from Let's Encrypt on its own, /etc/caddy/Caddyfile is:
spark.example.com {
reverse_proxy 127.0.0.1:8080
}
Set SPARK_RESTRICT_LOCALHOST=true so that Spark listens on loopback only and nobody can bypass the proxy. The proxy's forwarding headers name the client in the request log. Loopback and private addresses are trusted by default (SPARK_TRUSTED_PROXIES).
Streaming responses are server-sent events. If your proxy buffers responses, turn buffering off for /v1/, or streams arrive in one piece.
Upgrade
Run the install command again, then restart the service:
curl -fsSL https://raw.githubusercontent.com/curiosity-ai/spark/refs/heads/main/install.sh \
| sudo env SPARK_INSTALL=/opt/curiosity SPARK_NO_MODIFY_PATH=1 sh
sudo systemctl restart spark
GPU hosts
On a Linux host with an NVIDIA GPU, install the driver and cuBLAS 12 (libcublas.so.12). The installer warns when cuBLAS is missing. See Runners and placement for the device settings.
Security
- Console sign-in is a single user. A session lasts
SPARK_SESSION_HOURS(168). - The inference endpoints need an API key unless you turn
SPARK_REQUIRE_API_KEYoff. Do not turn it off on a network you do not control. SPARK_STORAGEholds the API key hashes, the request log, and the fleet key. Protect it like a secret. Snapshots inSPARK_KV_CACHE_FOLDERhold prompt token ids.- Images by URL are fetched from public addresses only by default (
SPARK_IMAGE_URLS). A request can make the server fetch a URL, so keep the default on a server that can reach internal systems. - Body size is limited by
SPARK_MAX_BODY_SIZE(64 MB). Images in base64 count against it.