This guide provides a robust, generalized configuration for Debian, Fedora, and Arch-based systems to run LM Studio as a true server without a graphical interface. It covers headless execution, autostart, auto-restart, and automatic updates.
While LM Studio is excellent for desktop use, running it as a true server presents several challenges:
- Existing solutions are incomplete: Most guides assume you have a GUI or don't address auto-updates
- Official docs are GUI-focused: LM Studio's documentation primarily covers graphical installations
- No comprehensive systemd integration: Community solutions lack proper service management, auto-restart, and update mechanisms
- Fragmented information: Setup instructions are scattered across forums, GitHub issues, and partial blog posts
This guide uniquely provides:
- β True headless operation (no GUI required)
- β Automatic service recovery on crashes
- β Automated weekly updates with zero downtime strategy
- β Multi-distribution support (Debian/Ubuntu, Fedora, Arch)
- β Production-ready systemd integration
- β Comprehensive troubleshooting and security guidance
Terms of Service: LM Studio is free for both personal and work use. This guide involves automated downloads of LM Studio, which is permitted under their terms. Review LM Studio's Terms of Service if you have specific compliance concerns.
Security Notice: This setup exposes LM Studio's API server on your network. Ensure you:
- Run this on a trusted/protected network
- Consider implementing authentication via a reverse proxy (nginx/traefik)
- Use a firewall to restrict access to authorized IP addresses only
- Avoid exposing port 1234 directly to the internet without proper security measures
Acknowledgments: This guide was inspired by community efforts, including work by Angelo Artuso and the run.tournament.org.il project, but provides a more comprehensive and automated solution for true headless deployments.
Testing Status: This guide has been tested on Ubuntu 24.04, Fedora 43, and Arch Linux. Report issues via GitHub Issues.
Resource Requirements:
- Minimum 16GB RAM (32GB+ recommended for larger models)
- GPU with adequate VRAM for your target models (8GB+ recommended)
- At least 50GB free storage for models and updates
- x86_64 processor with AVX2 support
Before configuring Systemd, you need wget (for downloads) and Xvfb (Virtual Frame Buffer) to simulate a display, which is required by the Electron backend.
Execute the command corresponding to your distribution:
| Distribution | Command |
|---|---|
| Fedora | sudo dnf install wget xorg-x11-server-Xvfb |
| Debian/Ubuntu | sudo apt install wget xvfb |
| Arch Linux | sudo pacman -S wget xorg-server-xvfb |
If you want to jump right in:
# 1. Clone this repository
git clone https://github.com/sterlenjohnson/Headless-LMStudio-Server.git
cd Headless-LMStudio-Server
# 2. Install dependencies (choose your distribution)
# Debian/Ubuntu:
sudo apt install wget xvfb
# Fedora:
sudo dnf install wget xorg-x11-server-Xvfb
# Arch:
sudo pacman -S wget xorg-server-xvfb
# 3. Follow the detailed setup steps below to:
# - Copy scripts to /opt/lmstudio/
# - Copy systemd files to /etc/systemd/system/
# - Replace <YOUR_USERNAME> placeholders
# - Download and extract LM StudioWe will use /opt/lmstudio as the INSTALL_DIR and replace <YOUR_USERNAME> with your actual Linux username throughout this guide.
<YOUR_USERNAME> with your actual Linux username in all commands and configuration files below.
# Create the main installation directory
sudo mkdir -p /opt/lmstudio
# Give your user ownership of the directory
sudo chown <YOUR_USERNAME>:<YOUR_USERNAME> /opt/lmstudioIf you cloned this repository, copy the scripts to the installation directory:
# From within the cloned repository directory
cp scripts/lmstudio-run.sh /opt/lmstudio/
cp scripts/update-lmstudio.sh /opt/lmstudio/
# Make them executable
chmod +x /opt/lmstudio/lmstudio-run.sh
chmod +x /opt/lmstudio/update-lmstudio.sh
# Edit the scripts to replace <YOUR_USERNAME> with your actual username
sed -i 's/<YOUR_USERNAME>/'"$USER"'/g' /opt/lmstudio/lmstudio-run.sh
sed -i 's/<YOUR_USERNAME>/'"$USER"'/g' /opt/lmstudio/update-lmstudio.shThe service relies on the file being present and extracted. Download the latest version now:
cd /opt/lmstudio
wget -O LM-Studio-latest.AppImage https://lmstudio.ai/download/latest/linux/x64
chmod +x LM-Studio-latest.AppImage./LM-Studio-latest.AppImage --appimage-extractThis creates a squashfs-root directory with the actual application.
This wrapper script launches the extracted AppImage binary using xvfb-run. This is what the Systemd service will execute.
If you copied the script from the repository in Step 1, it's already in place at /opt/lmstudio/lmstudio-run.sh. Otherwise, create it manually:
Create: /opt/lmstudio/lmstudio-run.sh
#!/bin/bash
# Set Home to the service user's home (essential for configs)
export HOME=/home/<YOUR_USERNAME>
# Navigate to the extracted folder
cd /opt/lmstudio/squashfs-root || exit 1
# Launch with xvfb-run to simulate a display, and use --headless for server mode
exec xvfb-run --auto-servernum --server-args='-screen 0 1024x768x24' \
./lm-studio --no-sandbox --headlessMake it executable:
chmod +x /opt/lmstudio/lmstudio-run.shThis is the core unit file that starts your server at boot.
If you cloned the repository, copy the systemd file and update the username:
# Copy from repository to system location
sudo cp systemd/lmstudio.service /etc/systemd/system/
# Edit to replace <YOUR_USERNAME> with your actual username
sudo sed -i 's/<YOUR_USERNAME>/'"$USER"'/g' /etc/systemd/system/lmstudio.serviceOr create it manually:
Create: /etc/systemd/system/lmstudio.service
[Unit]
Description=LM Studio Headless Service
# Start only after network is ready
After=network-online.target
Wants=network-online.target
[Service]
# Run as your specific user, not root
User=<YOUR_USERNAME>
Group=<YOUR_USERNAME>
# The script that runs the application
ExecStart=/opt/lmstudio/lmstudio-run.sh
# Restart automatically if it crashes
Restart=always
RestartSec=10
# Set timeout for startup (models can take time to load)
TimeoutStartSec=300
[Install]
# CRUCIAL: Starts at boot before any user logs in
WantedBy=multi-user.targetSince the download URL is stable, we can create a Systemd Timer to handle periodic updates.
This script downloads the new file, performs the necessary extraction (which overwrites the squashfs-root folder), and fixes permissions.
If you copied from the repository in Step 1, the script is already at /opt/lmstudio/update-lmstudio.sh. Otherwise, create it manually:
Create: /opt/lmstudio/update-lmstudio.sh
#!/bin/bash
SERVICE_USER="<YOUR_USERNAME>"
INSTALL_DIR="/opt/lmstudio"
DOWNLOAD_URL="https://lmstudio.ai/download/latest/linux/x64"
NEW_FILE="LM-Studio-latest.AppImage"
echo "$(date): Starting Update..." | tee -a "$INSTALL_DIR/update.log"
cd "$INSTALL_DIR" || exit 1
# 1. Download latest
echo "Downloading latest version..."
wget -q --show-progress -O "$NEW_FILE.tmp" "$DOWNLOAD_URL"
if [ $? -ne 0 ]; then
echo "$(date): Download failed." | tee -a "$INSTALL_DIR/update.log"
rm -f "$NEW_FILE.tmp"
exit 1
fi
# 2. Stop Service
echo "Stopping LM Studio service..."
systemctl stop lmstudio.service
# 3. Backup & Replace
echo "Creating backup and replacing AppImage..."
rm -rf squashfs-root.bak
mv squashfs-root squashfs-root.bak 2>/dev/null
mv "$NEW_FILE.tmp" "$NEW_FILE"
chmod +x "$NEW_FILE"
# 4. Extract (Crucial for headless execution)
echo "Extracting AppImage..."
./"$NEW_FILE" --appimage-extract > /dev/null
# 5. Fix Permissions
echo "Fixing permissions..."
chown -R $SERVICE_USER:$SERVICE_USER "$INSTALL_DIR"
# 6. Restart Service
echo "Restarting LM Studio service..."
systemctl start lmstudio.service
echo "$(date): Update Complete." | tee -a "$INSTALL_DIR/update.log"Make it executable:
sudo chmod +x /opt/lmstudio/update-lmstudio.shIf you cloned the repository, copy the systemd files:
# Copy update service and timer from repository
sudo cp systemd/lmstudio-update.service /etc/systemd/system/
sudo cp systemd/lmstudio-update.timer /etc/systemd/system/Or create them manually:
Update Service (/etc/systemd/system/lmstudio-update.service):
[Unit]
Description=LM Studio Auto-Update Runner
[Service]
Type=oneshot
ExecStart=/opt/lmstudio/update-lmstudio.sh
User=root
StandardOutput=journal
StandardError=journalUpdate Timer (/etc/systemd/system/lmstudio-update.timer - runs weekly):
[Unit]
Description=Weekly Timer for LM Studio Updates
[Timer]
# Runs every Monday at 4:00 AM
OnCalendar=Mon *-*-* 04:00:00
Persistent=true
Unit=lmstudio-update.service
[Install]
WantedBy=timers.target# Reload systemd
sudo systemctl daemon-reload
# Enable main service and start it immediately
sudo systemctl enable --now lmstudio.service
# Enable the weekly update timer
sudo systemctl enable --now lmstudio-update.timer# Check service status
systemctl status lmstudio.service
# View recent logs
journalctl -u lmstudio.service -n 50 -fExpected output should show Active: active (running).
The LM Studio server runs on TCP port 1234 by default. You must open this port to access the API server from outside the host machine.
| Distribution | Command |
|---|---|
| Fedora | sudo firewall-cmd --add-port=1234/tcp --permanentsudo firewall-cmd --reload |
| Debian/Ubuntu | sudo ufw allow 1234/tcp |
| Arch Linux (Using UFW) | sudo ufw allow 1234/tcp |
For production use, consider restricting to specific IP addresses:
# UFW example - allow only from specific subnet
sudo ufw allow from 192.168.1.0/24 to any port 1234If you use the desktop GUI frequently, you can install a "Hybrid" launcher that automatically stops the headless service when you open the GUI and restarts it when you close it.
-
Copy the launcher script:
sudo cp scripts/launch-gui.sh /opt/lmstudio/ sudo chmod +x /opt/lmstudio/launch-gui.sh
-
Install the Icon:
# Create the icon directory if it doesn't exist sudo mkdir -p /usr/share/icons/hicolor/scalable/apps/ # Copy the icon sudo cp systemd/lm-studio.svg /usr/share/icons/hicolor/scalable/apps/
-
Install the Desktop Shortcut:
# Copy the .desktop file to your applications folder sudo cp systemd/lm-studio-gui.desktop /usr/share/applications/ -
Use it: Search for "LM Studio (Hybrid)" in your application menu. When you click it:
- It will ask for your password (to stop the service).
- It will open LM Studio.
- When you close LM Studio, it will automatically restart the background service.
For users who need to run multiple instances of LM Studio simultaneously (e.g., a CPU-only model and a GPU-intensive model), this repository now includes an advanced launcher script.
The scripts/lms-launcher.sh script provides a powerful, interactive way to manage single or dual instances in either GUI or Headless mode.
- Interactive Menu: Simply run the script to get a menu of launch options.
- Dual Instance Support: Launch two instances of LM Studio at once.
- Profile Isolation: The secondary instance runs in a separate environment, preventing settings, models, and UI state from conflicting with the primary instance.
- GUI & Headless Modes: Choose the mode for each launch scenario.
- Persistent Configuration: All paths and ports are configured in
scripts/lms-launcher.conf. - Systemd Conflict Management: Automatically detects and offers to stop the default
lmstudio.serviceto prevent conflicts. - Direct Launch Arguments: Bypass the interactive menu to directly launch a specific configuration, ideal for desktop shortcuts or other scripts.
All settings for the launcher are controlled in scripts/lms-launcher.conf. This allows you to easily change ports and paths without editing the main script.
# scripts/lms-launcher.conf
# Path to the LM Studio AppImage.
APPIMAGE_PATH="/opt/lmstudio/LM-Studio-latest.AppImage"
# The port for the primary ("Instance 1") instance.
PRIMARY_PORT="1234"
# The port for the secondary ("Instance 2") instance.
SECONDARY_PORT="1235"
# The name of the directory for the isolated "Secondary" instance.
SECONDARY_HOME_NAME="lms-secondary-home"
# Path to your shared models folder for on-screen instructions.
DEFAULT_MODEL_PATH="~/.cache/lm-studio/models"Navigate to the repository directory and run the script.
cd Headless-LMStudio-Server
./scripts/lms-launcher.shThis will present a menu with all available launch options.
You can also launch a configuration directly by providing an argument. This is used by the new .desktop and .service files.
Example: Launch the dual GUI configuration directly.
./scripts/lms-launcher.sh --dual-guiAvailable arguments include:
--primary-gui--secondary-gui--primary-headless--secondary-headless--dual-gui--dual-headless
The launcher is integrated with new systemd and .desktop files, which you can optionally install:
systemd/lm-studio-dual-gui.desktop: A desktop shortcut that directly launches the dual GUI mode.systemd/lmstudio-primary.service: A systemd service to run only the primary headless instance on boot.systemd/lmstudio-secondary.service: A systemd service to run only the secondary headless instance on boot.
These services include a Conflicts directive, so enabling one (e.g., lmstudio-primary.service) will automatically disable the others (like lmstudio.service and lmstudio-secondary.service).
# Live log tail
journalctl -u lmstudio.service -f
# Last 100 lines
journalctl -u lmstudio.service -n 100
# Logs since last boot
journalctl -u lmstudio.service -b# View timer status
systemctl status lmstudio-update.timer
# List next scheduled run
systemctl list-timers lmstudio-update.timer# Run update manually
sudo /opt/lmstudio/update-lmstudio.sh
# Or trigger via systemd
sudo systemctl start lmstudio-update.service-
Check permissions:
ls -la /opt/lmstudio/ # Ensure <YOUR_USERNAME> owns all files -
Verify Xvfb is running:
ps aux | grep Xvfb -
Check for port conflicts:
sudo netstat -tlnp | grep 1234 # Or sudo ss -tlnp | grep 1234
-
Increase timeout if models are large: Edit
/etc/systemd/system/lmstudio.serviceand increaseTimeoutStartSec=600
Configure models via the LM Studio CLI before enabling headless mode:
# List available models
~/.cache/lm-studio/bin/lms ls
# Load a specific model
~/.cache/lm-studio/bin/lms load <model-identifier>
### Conflict with Desktop GUI
If you are running this on a desktop Linux environment, you cannot run the LM Studio GUI and this headless service simultaneously.
- **Symptom**: The GUI won't open, or the window keeps popping to the foreground.
- **Solution**: Stop the service before opening the GUI: `sudo systemctl stop lmstudio.service`.
- **Note**: The service is configured with `Restart=on-failure` to prevent restart loops if the GUI is already running.curl http://localhost:1234/v1/modelscurl http://localhost:1234/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "your-model-name",
"messages": [{"role": "user", "content": "Hello!"}],
"temperature": 0.7
}'From another machine on your network:
curl http://<server-ip>:1234/v1/models- Application:
/opt/lmstudio/squashfs-root/ - Models:
~/.cache/lm-studio/models/ - Configuration:
~/.config/LM-Studio/ - Update logs:
/opt/lmstudio/update.log - Service logs:
journalctl -u lmstudio.service
-
Use a reverse proxy (nginx/Caddy) with authentication:
location /api { auth_basic "LM Studio API"; auth_basic_user_file /etc/nginx/.htpasswd; proxy_pass http://localhost:1234; }
-
Restrict firewall to known IPs only
-
Enable HTTPS using Let's Encrypt with your reverse proxy
-
Monitor resource usage:
# Add to crontab for alerts watch -n 60 'free -h && nvidia-smi'
-
Regular backups of your model configurations
Edit /opt/lmstudio/lmstudio-run.sh and add:
export LMS_SERVER_PORT=8080For multi-GPU systems, specify which GPU to use:
export CUDA_VISIBLE_DEVICES=0 # Use first GPU onlyAdd to /etc/systemd/system/lmstudio.service under [Service]:
MemoryMax=24G
CPUQuota=400% # Use 4 CPU cores maxThis guide is released under the MIT License. Feel free to modify and distribute.
MIT License
Copyright (c) 2025 Sterlen Johnson
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
Found an issue or have an improvement? Please open an issue or pull request on GitHub.
- Report Issues: Found a bug or compatibility issue? Open an issue
- Submit Improvements: Have a better approach? Submit a pull request
- Share Your Setup: Tested on a different distribution? Let us know!
- Improve Documentation: Found something unclear? Help make it better
- Test your changes on at least one Linux distribution
- Update the "Testing Status" section if you verify compatibility
- Follow the existing markdown formatting style
- Add troubleshooting entries for any issues you solve
Contributors will be acknowledged in the README. Thank you for helping improve this guide!
- LM Studio Official Documentation
- LM Studio Discord Community
- Systemd Documentation
- LM Studio Terms of Service
After completing all steps:
- β Service starts automatically on boot
- β Service recovers from crashes
- β Updates run weekly without intervention
- β API accessible from network (if firewall configured)
- β Logs are being captured by systemd
You now have a production-ready, 24/7 LLM server! π