Production deployment

This deployment guide covers running Looona in production using systemd for automatic startup, process management, and a reverse proxy for HTTPS.

Essential setup

This minimal configuration gets Looona running as a system service with automatic restart and boot startup.

1. Setup directory structure

Create a dedicated directory for Looona and move the executable there:

# Create directory
sudo mkdir -p /opt/looona

# Move the executable
sudo mv looona /opt/looona/

# Make it executable
sudo chmod +x /opt/looona/looona

Note

You can use any directory you prefer (e.g., /usr/local/bin, /home/looona), but make sure to update the paths in the systemd service file accordingly.

2. Create a system user

For security, run Looona as a dedicated system user rather than root:

# Create a system user for Looona
sudo useradd -r -s /bin/false looona

# Set ownership of the Looona directory
sudo chown -R looona:looona /opt/looona

The -r flag creates a system user, and -s /bin/false prevents shell login for security.

3. Create systemd service

Create a systemd service file to manage Looona as a system service:

sudo nano /etc/systemd/system/looona.service

Add the following configuration:

[Unit]
Description=Looona Feedback Management Server
After=network.target

[Service]
Type=simple
User=looona
Group=looona
WorkingDirectory=/opt/looona
ExecStart=/opt/looona/looona serve -p 3030

# Restart configuration
Restart=on-failure
RestartSec=5s

# Security settings
NoNewPrivileges=true
PrivateTmp=true
ProtectSystem=strict
ProtectHome=true
ReadWritePaths=/opt/looona

# Logging
StandardOutput=journal
StandardError=journal
SyslogIdentifier=looona

[Install]
WantedBy=multi-user.target

Configuration explained:

  • After=network.target — Ensures network is available before starting
  • User=looona — Runs as the dedicated looona user
  • WorkingDirectory — Sets the working directory for data storage
  • Restart=on-failure — Automatically restarts if the service crashes
  • ProtectSystem=strict — Security hardening (read-only system directories)

4. Enable and start service

Reload systemd, enable the service to start on boot, and start it:

# Reload systemd to recognize the new service
sudo systemctl daemon-reload

# Enable Looona to start on boot
sudo systemctl enable looona

# Start the Looona service
sudo systemctl start looona

# Check the status
sudo systemctl status looona

Success!

If everything is configured correctly, you should see active (running) in green. Looona is now running and will automatically start when your server reboots.

5. Managing the service

sudo systemctl status looonaCheck service status
sudo systemctl stop looonaStop the service
sudo systemctl restart looonaRestart the service
sudo journalctl -u looona -fView live logs
sudo systemctl disable looonaDisable auto-start on boot

Optional: Production hardening

These additional configurations are recommended if you're exposing Looona to the internet or need enhanced security and reliability.

HTTPS with reverse proxy

For production use with public access, it's recommended to run Looona behind a reverse proxy for automatic HTTPS support and additional security.

Why use a reverse proxy?

  • Automatic HTTPS certificates via Let's Encrypt
  • Professional domain access (e.g., feedback.company.com)
  • Security headers and SSL/TLS termination
  • Better performance with caching and compression

Option 1: Caddy (recommended for simplicity)

Caddy automatically handles HTTPS certificates with zero configuration. Install Caddy:

# Install Caddy (Debian/Ubuntu)
sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | sudo tee /etc/apt/sources.list.d/caddy-stable.list
sudo apt update
sudo apt install caddy

Edit the Caddyfile:

sudo nano /etc/caddy/Caddyfile

Add this configuration:

looona.example.com {
    reverse_proxy localhost:3030
}

Reload Caddy:

sudo systemctl reload caddy

📚 Caddy documentation

Option 2: Nginx

Nginx is a popular choice with more configuration options. Install Nginx:

sudo apt install nginx

Create a new Nginx configuration:

sudo nano /etc/nginx/sites-available/looona

Add this configuration:

server {
    listen 80;
    server_name looona.example.com;

    location / {
        proxy_pass http://localhost:3030;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_cache_bypass $http_upgrade;
    }
}

Enable the configuration:

# Create symbolic link
sudo ln -s /etc/nginx/sites-available/looona /etc/nginx/sites-enabled/

# Test configuration
sudo nginx -t

# Reload Nginx
sudo systemctl reload nginx

Install SSL certificate with Certbot:

# Install Certbot
sudo apt install certbot python3-certbot-nginx

# Get SSL certificate (automatic Nginx configuration)
sudo certbot --nginx -d looona.example.com

# Auto-renewal is configured automatically

📚 Nginx documentationCertbot documentation

Firewall configuration

Protect your server by only allowing necessary network traffic.

Using UFW (Ubuntu/Debian)

# With reverse proxy (recommended)
sudo ufw allow 80/tcp    # HTTP
sudo ufw allow 443/tcp   # HTTPS
sudo ufw allow 22/tcp    # SSH (if needed)

# Or direct access to Looona (without reverse proxy)
sudo ufw allow 3030/tcp

# Enable firewall
sudo ufw enable

# Check status
sudo ufw status

Using firewalld (CentOS/RHEL)

# With reverse proxy
sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https

# Or direct access to Looona
sudo firewall-cmd --permanent --add-port=3030/tcp

# Reload firewall
sudo firewall-cmd --reload

# Check status
sudo firewall-cmd --list-all

📚 UFW documentationfirewalld documentation

Automated backups

Set up automated database backups using cron to prevent data loss.

sudo crontab -e -u looona

Add this line to run backups daily at 2 AM:

0 2 * * * /opt/looona/looona db-backup backup-$(date +\%Y\%m\%d-\%H\%M\%S).sqlite

Or create a backup script for more control:

#!/bin/bash
# /opt/looona/backup.sh

BACKUP_DIR="/opt/looona/looona_data/backups"
BACKUP_FILE="looona-backup-$(date +%Y%m%d-%H%M%S).sqlite"
RETENTION_DAYS=30

# Create backup
/opt/looona/looona db-backup "$BACKUP_FILE"

# Remove backups older than 30 days
find "$BACKUP_DIR" -name "looona-backup-*.sqlite" -type f -mtime +$RETENTION_DAYS -delete
# Make script executable
sudo chmod +x /opt/looona/backup.sh

# Add to crontab
sudo crontab -e -u looona
0 2 * * * /opt/looona/backup.sh >> /var/log/looona-backup.log 2>&1

📚 Crontab Guru (cron expression editor)

Troubleshooting

Service fails to start

Check the logs:

sudo journalctl -u looona -n 50 --no-pager

Common issues:

  • Incorrect file paths in the service file
  • Wrong permissions on the executable or data directory
  • Port already in use by another service

Permission denied errors

Ensure the looona user has proper permissions:

sudo chown -R looona:looona /opt/looonasudo chmod +x /opt/looona/looona

Cannot connect to the server

  • Check if the service is running: sudo systemctl status looona
  • Verify firewall rules allow traffic on the correct port
  • If using a reverse proxy, check its configuration and status
  • Check logs for binding errors: sudo journalctl -u looona

You're all set!

Your Looona instance is now running in production. Integrate it into your app to start collecting feedback.

Feedback