A REST API server for printing labels on Dymo labelwriters via CUPS.
- Rust (installed automatically if not present)
- CUPS system with Dymo labelwriter configured
- Dymo labelwriter connected via USB
-
Ensure your Dymo labelwriter is connected and configured in CUPS:
lpstat -p # List available printers -
Build and run the server:
cargo run
The server will start on http://0.0.0.0:3000
The server includes a web interface accessible at http://localhost:3000 that provides:
- 4 text input fields for label content
- Label format selection dropdown (default: 99012)
- Print button with status feedback
- Clean, responsive design for easy label printing
GET /
GET /health
Returns server status and version.
GET /printers
Returns a list of available printers.
POST /print
Content-Type: application/json
{
"line1": "John Doe", // Required - First line of text
"line2": "123 Main Street", // Optional - Second line of text
"line3": "Anytown, NY 12345", // Optional - Third line of text
"line4": "USA", // Optional - Fourth line of text
"printer_name": "DYMO_LabelWriter_450", // Optional
"label_size": "30252" // Optional - Dymo label size code
}
line1is required and cannot be emptyline2,line3, andline4are optional- Empty lines are automatically filtered out when printing
- If
printer_nameis not specified, the server will automatically find the first available Dymo printer - If
label_sizeis not specified, it defaults to "30252" (standard Dymo address label)
30252- Address labels (1-1/8" x 3-1/2")30256- Shipping labels (2-5/16" x 4")30321- Large address labels (1-4/10" x 3-1/2")30330- Return address labels (3/4" x 2")99012- Large address labels (3-1/2" x 1-1/8")
# Check server health
curl http://localhost:3000/health
# List available printers
curl http://localhost:3000/printers
# Print a simple one-line label
curl -X POST http://localhost:3000/print \
-H "Content-Type: application/json" \
-d '{"line1": "Hello, World!"}'
# Print a complete address label
curl -X POST http://localhost:3000/print \
-H "Content-Type: application/json" \
-d '{
"line1": "John Doe",
"line2": "123 Main Street",
"line3": "Anytown, NY 12345",
"line4": "USA"
}'
# Print to specific printer
curl -X POST http://localhost:3000/print \
-H "Content-Type: application/json" \
-d '{
"line1": "Jane Smith",
"line2": "456 Oak Avenue",
"printer_name": "DYMO_LabelWriter_450"
}'
# Print with custom label size (shipping label)
curl -X POST http://localhost:3000/print \
-H "Content-Type: application/json" \
-d '{
"line1": "URGENT DELIVERY",
"line2": "ABC Company",
"line3": "789 Business Blvd",
"label_size": "30256"
}'
# Print return address with small label size
curl -X POST http://localhost:3000/print \
-H "Content-Type: application/json" \
-d '{
"line1": "From: My Company",
"line2": "PO Box 123",
"printer_name": "DYMO_LabelWriter_450",
"label_size": "30330"
}'The server uses default Dymo label size (30252) when no label_size is specified in the request. You can override this per-request by including a label_size parameter in your print requests.
For production deployment on a Raspberry Pi or Debian-based system, you can set up the label server as a systemd service to automatically start on boot and restart on crashes.
-
Install CUPS and Dymo drivers:
sudo apt update sudo apt install cups cups-client printer-driver-dymo
-
Configure CUPS to accept connections:
sudo usermod -a -G lpadmin pi sudo systemctl enable cups sudo systemctl start cups -
Connect and configure your Dymo printer via CUPS web interface:
# Access CUPS web interface at http://your-pi-ip:631 # Or configure via command line: sudo lpadmin -p DYMO_LabelWriter_450 -E -v usb://DYMO/LabelWriter%20450 -m dymo_lw450.ppd
Detailed Setup Guide: For a comprehensive step-by-step guide on setting up a Raspberry Pi as a print server for Dymo label printers, including CUPS configuration and troubleshooting, see: Configure a Raspberry Pi as a Print Server for Dymo Label Printers
- Build the optimized release binary:
cd /path/to/labelserver cargo build --release
If you're building on a different architecture (e.g., x86_64) to deploy on Raspberry Pi 2 with 32-bit Debian Bookworm:
-
Install cross-compilation tools:
# Install Rust ARM target (musl for better compatibility) rustup target add arm-unknown-linux-musleabihf # Install ARM cross-compiler (on Ubuntu/Debian) sudo apt install gcc-arm-linux-gnueabihf
-
Create cargo cross-compilation config:
mkdir -p .cargo echo '[target.arm-unknown-linux-musleabihf] linker = "arm-linux-gnueabihf-gcc"' > .cargo/config.toml
-
Build for ARM:
cargo build --release --target arm-unknown-linux-musleabihf
The ARM binary will be located at:
target/arm-unknown-linux-musleabihf/release/labelserverNote: This uses musl libc for static linking, making it compatible with older glibc versions on Raspberry Pi systems.
Create installation directory:
sudo mkdir -p /opt/labelserver/staticFor x86_64 deployment:
sudo cp target/release/labelserver /opt/labelserver/
sudo cp static/index.html /opt/labelserver/static/
sudo chmod +x /opt/labelserver/labelserverFor Raspberry Pi 2 deployment:
sudo cp target/arm-unknown-linux-musleabihf/release/labelserver /opt/labelserver/
sudo cp static/index.html /opt/labelserver/static/
sudo chmod +x /opt/labelserver/labelserverSet ownership and create symlink:
# Set ownership
sudo chown -R labelserver:labelserver /opt/labelserver
# Create symlink for easy access (optional)
sudo ln -sf /opt/labelserver/labelserver /usr/local/bin/labelserversudo useradd --system --shell /bin/false --home /opt/labelserver labelserver-
Create the service file:
sudo nano /etc/systemd/system/labelserver.service
-
Add the following configuration:
[Unit] Description=Label Server - Dymo Label Printer REST API Documentation=https://github.com/your-repo/labelserver After=network-online.target cups.service Wants=network-online.target Requires=cups.service [Service] Type=simple User=labelserver Group=lp ExecStart=/opt/labelserver/labelserver WorkingDirectory=/opt/labelserver Environment=RUST_LOG=info # Restart policy Restart=always RestartSec=5 # Security settings NoNewPrivileges=yes PrivateTmp=yes ProtectSystem=strict ProtectHome=yes ReadWritePaths=/opt/labelserver # Resource limits LimitNOFILE=1024 [Install] WantedBy=multi-user.target
-
Reload systemd and enable the service:
sudo systemctl daemon-reload sudo systemctl enable labelserver.service -
Start the service:
sudo systemctl start labelserver.service
-
Check service status:
sudo systemctl status labelserver.service
-
View service logs:
# View recent logs sudo journalctl -u labelserver.service -f # View logs since boot sudo journalctl -u labelserver.service --since today # View last 50 log entries sudo journalctl -u labelserver.service -n 50
-
Stop or restart the service:
sudo systemctl stop labelserver.service sudo systemctl restart labelserver.service
-
Disable auto-start (if needed):
sudo systemctl disable labelserver.service
-
Check if the service is running:
sudo systemctl is-active labelserver.service
-
Check if the service is enabled for boot:
sudo systemctl is-enabled labelserver.service
-
Test the binary manually:
/opt/labelserver/labelserver
-
Check CUPS dependencies:
sudo systemctl status cups.service lpstat -p # Should show your Dymo printer -
Verify network connectivity:
curl http://localhost:3000/health
-
Check service permissions:
# Ensure the labelserver user can access CUPS groups labelserver # Should include 'lp' group
When updating the label server:
-
Stop the service:
sudo systemctl stop labelserver.service
-
Update the binary and static files:
For x86_64:
cargo build --release sudo cp target/release/labelserver /opt/labelserver/ sudo cp static/index.html /opt/labelserver/static/
For Raspberry Pi 2:
cargo build --release --target arm-unknown-linux-musleabihf sudo cp target/arm-unknown-linux-musleabihf/release/labelserver /opt/labelserver/ sudo cp static/index.html /opt/labelserver/static/
-
Start the service:
sudo systemctl start labelserver.service
- Ensure CUPS is running:
systemctl status cups - Check printer status:
lpstat -p - Verify printer queues:
lpq -P your_printer_name