Skip to content

Deploying Fluidd

Introduction

Fluidd is a lightweight, modern web interface for the Klipper 3D printer firmware. Built with Vue.js, Fluidd provides an intuitive, responsive dashboard for monitoring and controlling your 3D printer from any device with a web browser. It’s designed to be fast, clean, and user-friendly while offering powerful features for both beginners and advanced users.

Fluidd is characterized by:

  • Modern Interface: Clean, responsive design that works seamlessly on desktop, tablet, and mobile devices
  • Real-Time Monitoring: Live camera feeds, temperature graphs, and print progress tracking
  • Klipper Integration: Native support for Klipper firmware features and configuration
  • Lightweight: Optimized for performance with minimal resource requirements
  • Customizable: Extensive theming options and layout customization
  • G-Code Management: Upload, organize, and preview G-code files with metadata
  • Multi-Printer Support: Connect and manage multiple printers from a single interface

Key features include:

  • Temperature Control: Set and monitor hotend, bed, and chamber temperatures
  • Motion Control: Manual movement controls with customizable increments
  • Print Management: Start, pause, resume, and cancel prints with one click
  • File Browser: Organize and preview G-code files with thumbnails
  • Console: Direct G-code terminal access for advanced commands
  • Macros: Quick access to custom Klipper macros
  • Camera Support: Multiple camera feed integration
  • Power Control: Manage printer power and connected devices
  • History: Track completed prints with statistics and previews

Deploying Fluidd on Klutch.sh gives you a reliable, always-accessible web interface for your Klipper-powered 3D printer. This guide covers the complete installation process, from setting up the Dockerfile to configuring Moonraker integration and persistent storage.


Prerequisites

Before deploying Fluidd to Klutch.sh, ensure you have:

  • A Klutch.sh account
  • A GitHub account with a repository for your Fluidd project
  • Docker installed locally for testing (optional but recommended)
  • A Klipper installation running on your 3D printer with Moonraker API enabled
  • Network access from your Klutch.sh deployment to your printer’s Moonraker instance
  • Basic understanding of Klipper firmware and 3D printer operation
  • Your printer’s Moonraker API URL and port (typically port 7125)

Important Note: Fluidd is a frontend interface that requires a separate Moonraker API backend running on your printer. Fluidd itself does not control the printer directly—it communicates with Moonraker, which in turn interfaces with Klipper firmware.


Understanding the Fluidd Architecture

Before deploying, it’s important to understand how Fluidd works:

  1. Klipper: The firmware that runs on your 3D printer’s control board
  2. Moonraker: The API server that exposes Klipper functionality over HTTP/WebSocket
  3. Fluidd: The web frontend (what we’re deploying) that talks to Moonraker

When deployed on Klutch.sh, Fluidd serves as a static web application that connects to your local Moonraker instance. You’ll configure Fluidd to point to your printer’s Moonraker API endpoint.


Installation and Setup

Step 1: Create Your Project Directory

Create a new directory for your Fluidd deployment:

Terminal window
mkdir fluidd-klutch
cd fluidd-klutch
git init

Step 2: Create the Dockerfile

Fluidd is a static web application, so we’ll use Nginx to serve it. Create a Dockerfile in your project root:

# Stage 1: Download and prepare Fluidd
FROM alpine:latest as downloader
# Install required tools
RUN apk add --no-cache curl unzip
# Set Fluidd version (check https://github.com/fluidd-core/fluidd/releases for latest)
ENV FLUIDD_VERSION=v1.28.1
# Download and extract Fluidd
WORKDIR /tmp
RUN curl -L -o fluidd.zip \
https://github.com/fluidd-core/fluidd/releases/download/${FLUIDD_VERSION}/fluidd.zip && \
unzip fluidd.zip -d /fluidd && \
rm fluidd.zip
# Stage 2: Create production image with Nginx
FROM nginx:alpine
# Copy Fluidd files from downloader stage
COPY --from=downloader /fluidd /usr/share/nginx/html
# Create custom Nginx configuration
RUN echo 'server { \
listen 80; \
server_name _; \
\
# Serve Fluidd static files \
location / { \
root /usr/share/nginx/html; \
index index.html; \
try_files $uri $uri/ /index.html; \
} \
\
# Disable access logs for performance \
access_log off; \
error_log /var/log/nginx/error.log error; \
\
# Security headers \
add_header X-Frame-Options "SAMEORIGIN" always; \
add_header X-Content-Type-Options "nosniff" always; \
add_header X-XSS-Protection "1; mode=block" always; \
\
# Compression \
gzip on; \
gzip_vary on; \
gzip_proxied any; \
gzip_comp_level 6; \
gzip_types text/plain text/css text/xml text/javascript application/json application/javascript application/xml+rss application/rss+xml font/truetype font/opentype application/vnd.ms-fontobject image/svg+xml; \
}' > /etc/nginx/conf.d/default.conf
# Expose HTTP port
EXPOSE 80
# Start Nginx
CMD ["nginx", "-g", "daemon off;"]

Dockerfile Explanation:

  • Multi-stage build: Downloads Fluidd in one stage, then copies to a clean Nginx image
  • Version pinning: Uses a specific Fluidd version for consistency (update as needed)
  • Nginx configuration: Optimized for serving static files with compression and security headers
  • Port 80: Fluidd serves on standard HTTP port

Step 3: Create a .dockerignore File

Create a .dockerignore file to keep your Docker build clean:

.git
.github
.gitignore
README.md
*.log
.env
node_modules

Step 4: Create a Configuration Guide (README.md)

Create a README.md to document your Moonraker connection settings:

# Fluidd Deployment on Klutch.sh
This Fluidd instance connects to your local Moonraker API.
## Configuration Steps
After deploying, you'll need to configure Fluidd to connect to your printer:
1. Open your Fluidd URL (example-app.klutch.sh)
2. Click the settings icon (gear) in the top right
3. Navigate to "Printer" settings
4. Add your Moonraker instance:
- Name: My Printer
- URL: http://your-printer-ip:7125
- Save the configuration
## Moonraker Requirements
Ensure your Moonraker configuration allows CORS from your Fluidd domain:
```yaml
[authorization]
cors_domains:
https://example-app.klutch.sh
http://example-app.klutch.sh
[octoprint_compat]

Replace example-app.klutch.sh with your actual Klutch.sh app URL.

### Step 5: Test Locally (Optional)
Test your Fluidd Docker image locally before deploying:
```bash
# Build the Docker image
docker build -t fluidd-klutch .
# Run the container locally
docker run -d \
--name fluidd-test \
-p 8080:80 \
fluidd-klutch
# Check if Fluidd is accessible
curl -I http://localhost:8080
# View logs
docker logs fluidd-test
# Open in browser
open http://localhost:8080

You should see the Fluidd interface load. Note that it won’t be able to connect to a printer yet—that requires Moonraker configuration.

Cleanup after testing:

Terminal window
docker stop fluidd-test
docker rm fluidd-test

Step 6: Push to GitHub

Commit your project files to GitHub:

Terminal window
git add Dockerfile .dockerignore README.md
git commit -m "Add Fluidd Dockerfile for Klutch.sh deployment"
git branch -M main
git remote add origin https://github.com/yourusername/fluidd-klutch.git
git push -u origin main

Deploying to Klutch.sh

Now that your Fluidd project is ready and available on GitHub, follow these steps to deploy it on Klutch.sh.

Deployment Steps

    1. Log in to Klutch.sh

      Navigate to klutch.sh/app and sign in to your account.

    2. Create a New Project

      Go to Create Project and name it something like “3D Printer Interface” or “Fluidd Dashboard”.

    3. Create a New App

      Navigate to Create App to begin configuring your Fluidd deployment.

    4. Select Your Repository

      • Choose GitHub as your Git source
      • Select the repository containing your Fluidd Dockerfile
      • Choose the branch you want to deploy (typically main)

      Klutch.sh will automatically detect the Dockerfile in your repository root and use it for the build.

    5. Configure Traffic Type

      • Traffic Type: Select HTTP (Fluidd is a web application)
      • Internal Port: Set to 80 (the port Nginx serves Fluidd on)

      This configuration routes HTTP traffic from your Klutch.sh app URL to the Fluidd web interface running inside the container.

    6. Set Environment Variables (Optional)

      Fluidd itself doesn’t require environment variables for basic operation, but you can set:

      • TZ: Your timezone (e.g., America/New_York, Europe/London) for accurate timestamp logging
      • NGINX_WORKER_PROCESSES: Number of Nginx worker processes (default: auto)

      These are optional and Fluidd will work without them.

    7. Configure Persistent Volumes (Recommended)

      While Fluidd itself is stateless (configuration is stored in browser localStorage), you may want persistent storage for:

      • Custom themes or modifications
      • Nginx logs for troubleshooting

      To add persistent storage:

      Volume for Custom Files (Optional):

      • Mount Path: /usr/share/nginx/html/config
      • Size: 1 GB (minimal storage needed)

      This allows you to add custom configuration files or themes that persist across deployments.

    8. Configure Additional Settings

      • Region: Select the region closest to your physical location for optimal latency to your printer
      • Compute Resources:
        • Recommended: 0.5 CPU, 512MB RAM (Fluidd is very lightweight)
        • Minimum: 0.25 CPU, 256MB RAM
      • Instances: 1 instance is sufficient (Fluidd is a simple static site)
    9. Deploy Your Application

      Click “Create” to start the deployment. Klutch.sh will:

      • Automatically detect and build from your Dockerfile
      • Download the specified Fluidd release
      • Configure Nginx to serve the static files
      • Start your Fluidd container
      • Assign a URL for accessing your Fluidd interface
    10. Note Your Fluidd URL

      Once deployment completes, you’ll receive a URL like example-app.klutch.sh. This is your Fluidd web interface URL. Save this URL—you’ll need it for Moonraker CORS configuration.


Configuring Moonraker for Fluidd

After deploying Fluidd, you need to configure your printer’s Moonraker instance to accept connections from your Klutch.sh deployment.

Step 1: Update Moonraker Configuration

SSH into your printer (Raspberry Pi, etc.) and edit the Moonraker configuration file:

Terminal window
nano ~/printer_data/config/moonraker.conf

Add or update the following sections:

[authorization]
cors_domains:
https://example-app.klutch.sh
http://example-app.klutch.sh
trusted_clients:
10.0.0.0/8
127.0.0.0/8
169.254.0.0/16
172.16.0.0/12
192.168.0.0/16
FE80::/10
::1/128
[octoprint_compat]
[history]
[file_manager]
enable_object_processing: True

Important: Replace example-app.klutch.sh with your actual Klutch.sh app URL.

Configuration Explanation:

  • cors_domains: Allows your Fluidd instance to make API requests to Moonraker
  • trusted_clients: IP ranges that can connect without authentication
  • octoprint_compat: Enables OctoPrint-compatible API endpoints
  • history: Tracks print job history
  • file_manager: Enables G-code file management and analysis

Step 2: Restart Moonraker

After saving the configuration, restart Moonraker:

Terminal window
sudo systemctl restart moonraker

Verify Moonraker is running:

Terminal window
sudo systemctl status moonraker

Step 3: Test Moonraker Connection

From any computer on your network, test the Moonraker API:

Terminal window
curl http://your-printer-ip:7125/server/info

You should receive a JSON response with server information. If you get a connection error, check:

  • Moonraker is running (systemctl status moonraker)
  • Port 7125 is open in your firewall
  • Your printer has a static IP or DHCP reservation

Connecting Fluidd to Your Printer

Now that both Fluidd and Moonraker are configured, connect them:

Step 1: Open Fluidd

Navigate to your Fluidd URL: https://example-app.klutch.sh

Step 2: Add Your Printer

On first launch, Fluidd will prompt you to add a printer:

  1. Click “Add Printer” or the settings gear icon
  2. Navigate to “Printer” in the left sidebar
  3. Click “Add Printer”
  4. Fill in the details:
    • Name: My 3D Printer (or any name you prefer)
    • URL: http://your-printer-ip:7125
    • Port: Leave blank (already in URL)
  5. Click “Save”

Network Note: Your Klutch.sh deployment needs network access to your printer’s Moonraker API. If your printer is behind a home router:

  • Use your public IP or set up a VPN to access your home network
  • Consider port forwarding port 7125 (not recommended for security reasons)
  • Better option: Use a reverse proxy or VPN solution like Tailscale or WireGuard

Step 3: Verify Connection

Once configured, Fluidd should connect to your printer and display:

  • Current temperatures
  • Printer status
  • Available G-code files
  • Camera feed (if configured)

If connection fails, check:

  • Moonraker is running on your printer
  • CORS domains include your Fluidd URL
  • Network connectivity between Klutch.sh and your printer
  • Firewall rules allow traffic on port 7125

Getting Started with Fluidd

Now that Fluidd is connected to your printer, here’s how to use its key features:

Temperature Control

Setting Temperatures:

# Via Fluidd UI:
# Click the temperature widget and enter desired temperature
# Or via Console (G-code):
M104 S210 # Set hotend to 210°C
M140 S60 # Set bed to 60°C
M109 S210 # Wait for hotend to reach 210°C
M190 S60 # Wait for bed to reach 60°C

Cooling Down:

M104 S0 # Turn off hotend
M140 S0 # Turn off bed

Manual Movement

Use the control panel to move the print head:

# Via Console:
G28 # Home all axes
G0 Z10 # Move Z axis to 10mm
G0 X100 Y100 F3000 # Move to X100 Y100 at 3000mm/min

Starting a Print

    1. Upload G-code:

      • Click “Jobs” tab
      • Click “Upload” button
      • Select your G-code file
      • Wait for upload and analysis
    2. Review Print Info:

      • Filament usage
      • Estimated print time
      • Layer height
      • First layer temperature
    3. Start Print:

      • Click the print icon next to your file
      • Monitor progress in the main dashboard
    4. During Print:

      • Adjust print speed (flow rate)
      • Monitor temperatures
      • View live camera feed
      • Pause/resume as needed

Using Macros

Fluidd displays Klipper macros as quick-access buttons. Common macros include:

# Sample macros in your printer.cfg:
[gcode_macro START_PRINT]
gcode:
G28 # Home all axes
G0 Z20 F3000 # Raise Z
M140 S{BED_TEMP} # Set bed temperature
M104 S{EXTRUDER_TEMP} # Set hotend temperature
M190 S{BED_TEMP} # Wait for bed
M109 S{EXTRUDER_TEMP} # Wait for hotend
G92 E0 # Reset extruder
G1 E10 F300 # Prime extruder
[gcode_macro END_PRINT]
gcode:
M104 S0 # Turn off hotend
M140 S0 # Turn off bed
G91 # Relative positioning
G0 Z10 F3000 # Raise Z
G90 # Absolute positioning
G0 X0 Y200 F3000 # Present print
M84 # Disable motors

These macros will appear as buttons in Fluidd’s interface.

Camera Integration

To add a camera feed:

  1. Navigate to Settings > Cameras
  2. Click “Add Camera”
  3. Enter camera details:
    • Name: Bed Camera
    • URL: http://your-printer-ip:8080/?action=stream (for mjpeg-streamer)
    • Service: mjpeg-streamer or ustreamer
  4. Click “Save”

The camera feed will appear on your dashboard.


Sample Code: Moonraker API Integration

While Fluidd provides a complete UI, you might want to integrate Moonraker API calls into other applications:

Python Example

import requests
import json
class MoonrakerClient:
def __init__(self, base_url):
self.base_url = base_url.rstrip('/')
def get_printer_info(self):
"""Get printer information"""
response = requests.get(f'{self.base_url}/printer/info')
return response.json()
def get_printer_status(self):
"""Get current printer status"""
response = requests.get(f'{self.base_url}/printer/objects/query?heater_bed&extruder&print_stats')
return response.json()
def set_temperature(self, heater, target):
"""Set heater temperature"""
data = {
'heater': heater,
'target': target
}
response = requests.post(f'{self.base_url}/printer/gcode/script',
params={'script': f'SET_HEATER_TEMPERATURE HEATER={heater} TARGET={target}'})
return response.json()
def run_gcode(self, gcode):
"""Execute G-code command"""
response = requests.post(f'{self.base_url}/printer/gcode/script',
params={'script': gcode})
return response.json()
def get_file_list(self):
"""List available G-code files"""
response = requests.get(f'{self.base_url}/server/files/list')
return response.json()
def start_print(self, filename):
"""Start printing a file"""
response = requests.post(f'{self.base_url}/printer/print/start',
json={'filename': filename})
return response.json()
# Usage example
client = MoonrakerClient('http://your-printer-ip:7125')
# Get printer info
info = client.get_printer_info()
print(f"Printer: {info['result']['hostname']}")
# Get current status
status = client.get_printer_status()
print(f"Bed temp: {status['result']['status']['heater_bed']['temperature']}°C")
# Run G-code
client.run_gcode('G28') # Home all axes
print("Homing complete")
# List files
files = client.get_file_list()
for file in files['result']:
print(f"File: {file['filename']}")

JavaScript/Node.js Example

const axios = require('axios');
class MoonrakerClient {
constructor(baseUrl) {
this.baseUrl = baseUrl.replace(/\/$/, '');
this.client = axios.create({
baseURL: this.baseUrl,
timeout: 10000
});
}
async getPrinterInfo() {
const response = await this.client.get('/printer/info');
return response.data;
}
async getPrinterStatus() {
const response = await this.client.get('/printer/objects/query', {
params: {
heater_bed: null,
extruder: null,
print_stats: null
}
});
return response.data;
}
async runGcode(gcode) {
const response = await this.client.post('/printer/gcode/script', null, {
params: { script: gcode }
});
return response.data;
}
async setTemperature(heater, target) {
return this.runGcode(`SET_HEATER_TEMPERATURE HEATER=${heater} TARGET=${target}`);
}
async getFileList() {
const response = await this.client.get('/server/files/list');
return response.data;
}
async startPrint(filename) {
const response = await this.client.post('/printer/print/start', {
filename: filename
});
return response.data;
}
}
// Usage example
(async () => {
const client = new MoonrakerClient('http://your-printer-ip:7125');
try {
// Get printer info
const info = await client.getPrinterInfo();
console.log(`Printer: ${info.result.hostname}`);
// Get current status
const status = await client.getPrinterStatus();
console.log(`Bed temp: ${status.result.status.heater_bed.temperature}°C`);
// Home all axes
await client.runGcode('G28');
console.log('Homing complete');
// List files
const files = await client.getFileList();
files.result.forEach(file => {
console.log(`File: ${file.filename}`);
});
} catch (error) {
console.error('Error:', error.message);
}
})();

cURL Examples

Terminal window
# Get printer info
curl http://your-printer-ip:7125/printer/info
# Get current temperatures
curl 'http://your-printer-ip:7125/printer/objects/query?heater_bed&extruder'
# Run G-code command
curl -X POST 'http://your-printer-ip:7125/printer/gcode/script?script=G28'
# Set bed temperature
curl -X POST 'http://your-printer-ip:7125/printer/gcode/script?script=M140%20S60'
# List files
curl http://your-printer-ip:7125/server/files/list
# Start a print
curl -X POST http://your-printer-ip:7125/printer/print/start \
-H 'Content-Type: application/json' \
-d '{"filename": "test_print.gcode"}'
# Pause print
curl -X POST http://your-printer-ip:7125/printer/print/pause
# Resume print
curl -X POST http://your-printer-ip:7125/printer/print/resume
# Cancel print
curl -X POST http://your-printer-ip:7125/printer/print/cancel

Production Best Practices

Security Recommendations

  • VPN Access: Instead of exposing Moonraker to the internet, use a VPN like Tailscale or WireGuard to securely access your printer network
  • Authentication: Consider enabling Moonraker authentication for additional security
  • HTTPS Only: Use HTTPS for your Fluidd deployment on Klutch.sh (enabled by default)
  • Firewall Rules: Only allow necessary traffic to your printer on port 7125
  • Network Segmentation: Place your printer on a separate VLAN if possible
  • Regular Updates: Keep Klipper, Moonraker, and Fluidd updated with security patches
  • Strong Passwords: Use strong passwords for SSH access to your printer’s host system

Performance Optimization

  • Static IP: Assign a static IP or DHCP reservation to your printer for reliable connections
  • Network Quality: Ensure stable, low-latency network connection between Klutch.sh and your printer
  • Camera Optimization: Use appropriate resolution and frame rate for camera streams (640x480 @ 15fps is often sufficient)
  • Browser Cache: Fluidd leverages browser caching—clear cache if you experience outdated UI issues
  • Gzip Compression: The Dockerfile enables Nginx gzip compression for faster page loads

Monitoring and Maintenance

Monitor your Fluidd deployment for:

  • API Latency: High latency between Fluidd and Moonraker can cause UI lag
  • Connection Stability: Frequent disconnections indicate network issues
  • Print History: Review completed prints for patterns in failures
  • Temperature Graphs: Monitor for anomalies in heating behavior
  • Error Logs: Check Nginx logs and Moonraker logs for issues

Regular maintenance tasks:

  • Update to latest Fluidd releases for new features and bug fixes
  • Review and optimize Klipper configuration
  • Clean printer cameras and check feed quality
  • Test emergency stop and pause functionality
  • Verify backup of Klipper configurations

Backup and Recovery

Configuration Backups:

  • Keep backups of your Klipper printer.cfg and Moonraker moonraker.conf
  • Export Fluidd settings from the UI (Settings > Backup & Restore)
  • Version control your Dockerfile and deployment configuration

Printer Configuration Management:

Terminal window
# Backup Klipper configuration
cd ~/printer_data/config
tar -czf ~/klipper-backup-$(date +%Y%m%d).tar.gz *.cfg moonraker.conf
# Restore from backup
tar -xzf ~/klipper-backup-20240101.tar.gz -C ~/printer_data/config
sudo systemctl restart klipper moonraker

Troubleshooting

Fluidd Won’t Load

  • Verify your app is running in the Klutch.sh dashboard
  • Check deployment logs for Nginx errors
  • Ensure internal port is set to 80
  • Confirm HTTP traffic type is selected
  • Try accessing from a different browser or incognito mode

Cannot Connect to Printer

  • Verify Moonraker is running: systemctl status moonraker
  • Check Moonraker CORS configuration includes your Fluidd URL
  • Test direct API access: curl http://your-printer-ip:7125/server/info
  • Verify network connectivity from Klutch.sh to your printer
  • Check firewall rules on your printer’s host system
  • Ensure port 7125 is open and accessible

Camera Feed Not Working

  • Verify camera service is running on your printer
  • Check camera URL is correct in Fluidd settings
  • Test camera stream directly in browser: http://your-printer-ip:8080/?action=stream
  • Ensure camera service allows connections from external IPs
  • Try different camera services (mjpeg-streamer vs ustreamer)
  • Check printer is not in error state
  • Verify G-code file uploaded successfully and was analyzed
  • Ensure heaters can reach target temperatures
  • Check Klipper logs for error messages: ~/printer_data/logs/klippy.log
  • Verify home position is correct before starting

UI Performance Issues

  • Check network latency between Klutch.sh and your printer
  • Reduce camera resolution or frame rate
  • Clear browser cache and reload Fluidd
  • Disable browser extensions that might interfere
  • Check if multiple clients are connected to Moonraker simultaneously

Updates Not Reflected

  • If you update the Dockerfile, trigger a new deployment in Klutch.sh
  • Clear browser cache after Fluidd updates
  • Check that you’re using the correct Fluidd version in Dockerfile
  • Verify deployment completed successfully in Klutch.sh logs

Additional Resources


Conclusion

Deploying Fluidd on Klutch.sh provides a reliable, accessible web interface for your Klipper-powered 3D printer from anywhere with internet access. The containerized deployment ensures consistent performance, while the lightweight nature of Fluidd keeps resource usage minimal. By following this guide, you’ve set up a production-ready Fluidd instance that connects securely to your printer’s Moonraker API, giving you full control over your 3D printing workflow from any device with a web browser.