Deployment
Production deployment strategies including reverse proxy configuration, HTTPS, systemd services, and security hardening.
Reverse Proxy & HTTPS
In production, you should place Needlework Studio behind a reverse proxy that terminates SSL/TLS. This gives you HTTPS with automatic certificate management, and lets you serve the application on standard ports (80/443) alongside other services.
When running behind an SSL-terminating proxy, set the HTTPS=true environment variable so that session cookies are marked as Secure and only transmitted over encrypted connections.
Caddy (Recommended)
Caddy is a modern web server that automatically provisions and renews Let's Encrypt certificates. It requires minimal configuration and is the simplest way to add HTTPS to your deployment.
Create a docker-compose.yml that runs both Caddy and Needlework Studio:
services:
caddy:
image: caddy:latest
ports:
- "80:80"
- "443:443"
volumes:
- ./Caddyfile:/etc/caddy/Caddyfile
- caddy-data:/data
- caddy-config:/config
restart: unless-stopped
needlework-studio:
image: ghcr.io/greenglasst/needleworkstudio:latest
volumes:
- needlework-data:/data
environment:
- HTTPS=true
restart: unless-stopped
volumes:
needlework-data:
caddy-data:
caddy-config:
Create a Caddyfile in the same directory:
needlework.example.com {
reverse_proxy needlework-studio:6969
}
Replace needlework.example.com with your actual domain name. Caddy will automatically obtain an SSL certificate from Let's Encrypt and handle renewals. No additional port mapping is needed for the Needlework Studio container because Caddy communicates with it over the internal Docker network.
Other Reverse Proxies
Needlework Studio works with any reverse proxy (Nginx, Apache, Traefik, etc.). The key requirements are:
- Proxy all traffic to the application on port
6969. - Forward the
Host,X-Forwarded-For, andX-Forwarded-Protoheaders. - Set
HTTPS=trueon the Needlework Studio container when terminating SSL at the proxy.
Systemd Service
For manual (non-Docker) installations on Linux, you can run Needlework Studio as a systemd service so it starts automatically on boot and restarts on failure.
Create a unit file at /etc/systemd/system/needlework-studio.service:
[Unit]
Description=Needlework Studio
After=network.target
[Service]
Type=simple
User=needlework
Group=needlework
WorkingDirectory=/opt/needlework-studio
ExecStart=/opt/needlework-studio/venv/bin/gunicorn -w 1 --threads 4 -b 0.0.0.0:6969 app:app
Restart=on-failure
RestartSec=5
Environment=HTTPS=true
Environment=NEEDLEWORK_DATA_DIR=/opt/needlework-studio/data
[Install]
WantedBy=multi-user.target
Enable and start the service:
sudo systemctl daemon-reload
sudo systemctl enable needlework-studio
sudo systemctl start needlework-studio
Check that the service is running:
sudo systemctl status needlework-studio
View application logs:
sudo journalctl -u needlework-studio -f
Docker with Auto-Restart
The Docker Compose examples in this documentation include restart: unless-stopped, which ensures the container automatically restarts after a crash or a host reboot. This is the simplest way to achieve high availability with Docker.
The container will restart in all of the following scenarios:
- The application process crashes or exits with a non-zero code.
- The Docker daemon restarts.
- The host machine reboots.
The only time the container will not restart is if you explicitly stop it with docker compose down or docker stop. If you want the container to restart even after an explicit stop, use restart: always instead.
Security Notes
Needlework Studio includes several built-in security measures. Understanding these will help you configure your deployment securely.
CSRF Protection
All state-changing requests are protected by CSRF tokens. These tokens are automatically included in forms rendered by the application and validated on the server for every POST, PUT, and DELETE request.
Password Hashing
User passwords are hashed using Argon2, the winner of the Password Hashing Competition. Argon2 is resistant to GPU-based and ASIC-based brute-force attacks and is considered the current best practice for password storage.
Rate Limiting
The application enforces rate limits to prevent abuse:
- Login attempts: 5 requests per minute per IP address. This mitigates brute-force password attacks.
- Thread inventory updates: 60 requests per minute per user. This prevents accidental or automated flooding of the API.
Rate limiting is implemented in-memory, which is why a single Gunicorn worker (-w 1) is required. See Installation > Production with Gunicorn for details.
HTTP Security Headers
Needlework Studio sets the following security headers on all responses:
- Content-Security-Policy (CSP): Restricts the sources from which scripts, styles, images, and other resources can be loaded, mitigating cross-site scripting (XSS) attacks.
- Strict-Transport-Security (HSTS): Instructs browsers to only access the application over HTTPS, preventing protocol downgrade attacks.
- X-Frame-Options: Prevents the application from being embedded in iframes on other sites, protecting against clickjacking attacks.
Secure Cookies
When HTTPS=true is set, all session cookies are marked with the Secure flag, ensuring they are never transmitted over unencrypted HTTP connections. Cookies also use the HttpOnly and SameSite attributes to prevent JavaScript access and cross-site request attachment.
Upload Limits
To protect against denial-of-service through large file uploads:
- File size limit: 25 MB maximum per upload. Requests exceeding this size are rejected before the file is saved to disk.
- Decompression bomb protection: Image processing is capped at 50 megapixels. This prevents malicious images with extreme dimensions from consuming excessive memory during processing.