Deployment patterns¶
plotsrv can be used in several modes:
- attached to a local Python process
- as a separate server alongside scripts or jobs
- on a VM or internal server
- inside a container
- behind a reverse proxy
- as part of a managed platform
Not every deployment pattern is mature yet - this is an ongoing piece of work! (sections marked TODO are not yet mature)
Note
The examples below use ps.publish_view() but can be substituted with the decorator approach using @view.
Simple development¶
From an interactive Python session, notebook, or short local script.
import plotsrv as ps
ps.publish_view(
{"status": "ok"},
label="summary",
section="demo",
launch_server=True,
)
This starts an attached plotsrv server inside the current Python process.
Open:
Useful for:
- quick local exploration
- testing whether plotsrv is installed correctly
- publishing one or two objects during development
- demos and small experiments
It is not the best pattern for long-running scripts, scheduled jobs, or shared access.
For those, use the server workflow.
Server workflow¶
For scripts, pipelines, batch jobs, and scheduled processes, start plotsrv separately and publish to it from Python.
Example:
In a seperate terminal using Python:
import plotsrv as ps
ps.publish_view(
{"status": "complete"},
label="status",
section="daily pipeline",
host="127.0.0.1",
port=8000,
)
This pattern keeps the plotsrv UI running independently of the script that publishes output.
It is useful for:
- ETL jobs
- batch scripts
- model training runs
- scheduled reporting jobs
- headless or remote development
- lightweight internal monitoring
VM or internal server¶
A common deployment pattern is to run plotsrv on a VM or internal Linux server.
The server might run:
- as a foreground process during development
- inside
tmuxorscreen - as a
systemdservice - behind a reverse proxy such as Caddy or Nginx
For private/internal access, SSH port forwarding is often the safest first option.
For public internet access, avoid binding plotsrv directly to a public interface. Prefer keeping plotsrv bound to 127.0.0.1 and exposing only selected routes through a reverse proxy. The Caddy section below shows this pattern.
Warning
plotsrv is designed primarily for trusted development, internal, and controlled environments.
Public internet exposure should be treated carefully. Only expose non-sensitive demo data, avoid enabling traceback views publicly, and block write/control endpoints such as /publish and /shutdown.
Running manually¶
For a simple internal setup:
Then publish to it from scripts running on the same server:
If accessing the UI remotely, SSH port forwarding is usually the safest first option:
Then open locally:
Running with systemd¶
For a persistent internal server, plotsrv can be run with systemd.
Example service file:
[Unit]
Description=plotsrv server
After=network.target
[Service]
Type=simple
User=plotsrv
WorkingDirectory=/opt/plotsrv-project
ExecStart=/opt/plotsrv-project/.venv/bin/plotsrv run ./src --host 127.0.0.1 --port 8000 --config plotsrv.yaml
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
Then:
sudo systemctl daemon-reload
sudo systemctl enable plotsrv
sudo systemctl start plotsrv
sudo systemctl status plotsrv
This pattern works well when plotsrv is used as an internal observability surface for jobs running on the same machine.
Reverse proxy with Caddy¶
Caddy can expose plotsrv through a public or internal hostname while keeping the plotsrv server itself bound to localhost.
With this setup:
This is safer than binding plotsrv directly to a public network interface because Caddy controls which routes are exposed.
When to use this pattern¶
Use this pattern when:
- plotsrv is running on a VM or server
- the UI needs a friendly URL
- HTTPS should be handled automatically
- only selected read-only routes should be exposed publicly
For private workflows, SSH tunnelling or an authenticated internal reverse proxy is usually preferable.
For public demos, expose only non-sensitive content and block write/control routes.
Start plotsrv on localhost¶
Run plotsrv bound to 127.0.0.1:
This means plotsrv is only reachable locally on the server.
Caddy will handle external access.
Use a strict read-only Caddyfile¶
Edit the Caddyfile:
Use an allow-list so only the routes needed for viewing the UI are public:
demo.plotsrv.com {
@public {
path / /plot /table/data /artifact /status /history /table/export /static/* /assets/*
}
handle @public {
reverse_proxy 127.0.0.1:8000
}
respond 404
}
This configuration means:
- selected UI routes are proxied to plotsrv
- all other routes return
404 - write/control routes such as
/publishand/shutdownare not publicly reachable - new or unexpected routes are blocked by default
This pattern is suitable for a public read-only demo where trusted code running on the server publishes the displayed content.
Validate and reload Caddy¶
Validate the configuration:
Reload Caddy:
Check the service:
Test the deployment¶
First test plotsrv locally on the server:
Then test the public hostname:
Blocked routes should return 404:
curl -I https://demo.plotsrv.com/publish
curl -I https://demo.plotsrv.com/shutdown
curl -I https://demo.plotsrv.com/openapi.json
Security considerations¶
Before exposing plotsrv beyond localhost, consider:
- who can access the UI
- whether the data is safe to publish
- whether tracebacks are enabled
- whether watched files may contain sensitive data
- whether published tables or objects contain sensitive data
- whether write/control endpoints are blocked
- whether the reverse proxy provides authentication
- whether the service is reachable from the public internet
For public demos, prefer:
- binding plotsrv to
127.0.0.1 - exposing it through a reverse proxy
- using HTTPS
- allowing only read-only UI routes
- blocking everything else by default
- publishing only non-sensitive demo data
Docker¶
TODO
Kubernetes¶
TODO
Cloud-based deployment¶
TODO
Posit Connect¶
TODO