Repository navigation
Installation
The supported clean-installation path is Raspberry Pi OS or Debian 12 and Python 3.11 or newer. The installer always downloads the stable OSPy master branch. Unless passwordless LAN access is deliberately selected, the login page displays a generated administrator password until it is changed in Options.
Log into the Raspberry Pi using SSH. Commands on Linux are case sensitive.
Download the installer:
wget https://raw.githubusercontent.com/martinpihrt/OSPy/master/ospy_setup.shRun it as root:
sudo bash ospy_setup.shThe installer is interactive and uses whiptail. First choose whether to install/manage OSPy or uninstall an existing OSPy installation. Installation asks which optional operating-system components should be installed, then asks for the OSPy installation directory, and finally asks how OSPy should be reachable over the network. When Local network only is selected, it also offers a deliberate passwordless mode for a trusted, isolated LAN.
Passwordless access is intended only for a trusted, isolated LAN. While it is active, every device that can reach OSPy has administrator access. Open Options, enter and confirm a new administrator password, and save. No current password is requested in this state. OSPy disables passwordless access, revokes remembered browser logins, ends the current session, and then requires the newly set password.
Run the same installer again and select Stop, disable and remove an OSPy installation. It offers only the standard locations that currently exist: /opt/OSPy and <invoking-user-home>/OSPy. Select the exact directory and type REMOVE to confirm.
The uninstaller stops and disables ospy.service only when its WorkingDirectory matches the selected installation, removes the matching service unit, removes the selected OSPy directory including its settings, logs and backups, and reloads systemd. It also removes the dedicated OSPy Cloudflare Quick Tunnel service when present. It does not uninstall shared operating-system packages, cloudflared, Tailscale, a managed Cloudflare Tunnel, or their configuration.
Default: ON
Runs:
sudo apt-get upgrade -yafter refreshing the package index. Disable this option if operating-system package upgrades are managed separately.
Default: ON
Installs i2c-tools and python3-smbus. On Raspberry Pi OS, the installer also uses raspi-config to enable I2C.
This option is useful for the I2C LCD plug-in and other OSPy plug-ins that use the Raspberry Pi I2C bus.
A reboot is recommended after installation if I2C was enabled.
Default: OFF
Installs the Mosquitto broker and Python MQTT support and enables mosquitto.service.
Enable this only if OSPy or one of its plug-ins will use a local MQTT broker.
Default: ON
Adds the user who invoked sudo to available groups:
gpio
i2c
dialout
Missing groups are skipped safely.
A reboot or a new login session is recommended before the changed group membership is used.
The core requirements installed on every clean installation include python3-holidays. OSPy uses it locally for optional public-holiday exclusions in program calendar rules; the country is detected from the configured weather location or selected with the holiday-country override. Astronomical program times remain supplied by the optional Sunrise and Sunset plug-in.
Default: OFF
Installs:
ffmpeg
pulseaudio
python3-pygame
Enable this only when plug-ins requiring audio/multimedia support are used.
The installer offers two locations:
/opt/OSPy
or:
<invoking-user-home>/OSPy
A new installation is cloned from the stable master branch.
If an existing Git checkout is found, the installer never deletes, resets or automatically updates it; it installs the service around that checkout. A non-Git OSPy path stops the installation and must be inspected manually.
OSPy serves its web interface on port 8080. A normal new installation uses local HTTP, while an existing OSPy installation may already be configured for local HTTPS.
Typical local LAN access is:
http://<Raspberry-Pi-address>:8080
If OSPy's own HTTPS is enabled, the local URL is instead similar to:
https://<Raspberry-Pi-address>:8080
Cloudflare Tunnel and Cloudflare Quick Tunnel can use either local protocol. The installer probes 127.0.0.1:8080 after OSPy starts and uses the detected HTTP or HTTPS origin. The public side remains HTTPS in both cases.
No router port forwarding is required for any of the tunnel modes below.
Recommended when OSPy does not need remote Internet access.
No Cloudflare or Tailscale software is configured.
Access OSPy directly from the local network:
http://192.168.x.x:8080
Advantages:
- simplest configuration;
- no external account;
- no public OSPy endpoint;
- no tunnel dependency.
This mode does not automatically add HTTPS.
Recommended when OSPy should be reachable through a normal public hostname such as:
https://ospy.example.com
Architecture:
Web browser
|
| HTTPS - public TLS certificate
v
Cloudflare
|
| encrypted Cloudflare Tunnel
v
cloudflared on Raspberry Pi
|
| local HTTP or HTTPS on loopback
v
http://127.0.0.1:8080
or
https://127.0.0.1:8080
|
v
OSPy
Cloudflare manages the public HTTPS connection and certificate. A public IPv4 address, DDNS and router port forwarding are not required.
Before running the OSPy installer with this option:
- Have a Cloudflare account.
- Have a domain using Cloudflare DNS.
- Create a remotely-managed Cloudflare Tunnel in the Cloudflare dashboard.
- Choose the public hostname for OSPy, for example:
ospy.example.com
- Copy the Tunnel token from the Cloudflare installation command.
The OSPy installer asks for both the public hostname and the Tunnel token on a new managed-tunnel installation. The hostname can also be entered as https://ospy.example.com; it is normalized and stored as HTTPS. Paste only the token itself, not the complete cloudflared service install ... command. If an active managed cloudflared.service already exists, the installer leaves its credentials unchanged and does not require the token again; it only updates the stored public hostname metadata.
The installer then:
- installs
cloudflaredfrom Cloudflare's official Debian package repository; - registers the tunnel as
cloudflared.serviceor leaves an already-active managed service unchanged; - detects whether OSPy responds locally over HTTP or HTTPS;
- prints the exact local origin URL to use for the Cloudflare Published application route;
- stores only the public HTTPS URL in:
/etc/ospy/cloudflare_public_url
This file contains only a public URL such as https://ospy.example.com. The Tunnel token is not written to the OSPy project or to this URL file.
Configure the Cloudflare Published application route to the origin printed by the installer. Typical HTTP origin:
http://127.0.0.1:8080
If OSPy already uses local HTTPS, use:
https://127.0.0.1:8080
For a self-signed or locally issued OSPy certificate, enable No TLS Verify in the Published application's TLS settings. This disables certificate verification only for the local cloudflared -> OSPy HTTPS hop; the browser still connects to the public hostname using normal Cloudflare HTTPS.
While cloudflared.service is active and /etc/ospy/cloudflare_public_url contains a valid HTTPS hostname, OSPy shows that address as a clickable Cloudflare Tunnel link in the footer. The managed tunnel has display priority over a Quick Tunnel if both services are temporarily active.
Cloudflare documentation:
- https://developers.cloudflare.com/tunnel/setup/
- https://developers.cloudflare.com/tunnel/downloads/
- https://developers.cloudflare.com/tunnel/advanced/origin-parameters/
Cloudflare Tunnel makes the selected hostname publicly reachable unless access is restricted separately.
For an Internet-facing OSPy installation, consider using Cloudflare Access in front of OSPy. This can provide an additional authentication layer before the OSPy login page is reached.
Always change the generated OSPy administrator password immediately after first login.
This option is intended for testing and temporary access.
No Cloudflare account and no own domain are required.
After OSPy starts, the installer probes both local protocols. For a normal HTTP origin it starts the equivalent of:
cloudflared tunnel --url http://127.0.0.1:8080If OSPy is configured for local HTTPS, it uses the equivalent of:
cloudflared tunnel --url https://127.0.0.1:8080 --no-tls-verify--no-tls-verify applies only to the local cloudflared -> OSPy connection and allows a self-signed/local OSPy certificate. The generated public trycloudflare.com endpoint still uses normal HTTPS.
The command runs as a dedicated systemd service:
ospy-cloudflared-quick.service
Cloudflare generates a temporary address similar to:
https://random-words.trycloudflare.com
The address can be shown with:
sudo journalctl -u ospy-cloudflared-quick.service -n 50 --no-pagerWhile ospy-cloudflared-quick.service is installed and active and a valid https://*.trycloudflare.com address is present in its journal, OSPy shows the current address as a clickable Cloudflare Quick Tunnel link in the footer. If a configured managed cloudflared.service is also active, the footer shows the managed Cloudflare Tunnel URL instead. If neither mode has a valid active URL, the footer does not show a Cloudflare link.
Cloudflare documents Quick Tunnels as a development/testing feature, not as a production hosting method. The generated hostname can change when the tunnel is recreated or restarted. Quick Tunnels also have service limitations, including no Server-Sent Events support; OSPy's polling fallback remains available, but use a managed Tunnel for normal production access.
Cloudflare documentation:
Recommended for private OSPy administration.
Tailscale Serve exposes OSPy over HTTPS only inside the user's Tailscale network, called a tailnet.
Architecture:
Your phone / PC
|
| Tailscale encrypted network
v
https://raspberry-pi.<tailnet>.ts.net
|
v
Tailscale Serve
|
| local HTTP
v
http://127.0.0.1:8080
|
v
OSPy
Users and devices must be allowed into the tailnet. Tailnet access-control rules also apply to Serve.
No own Internet domain, public IP address or router port forwarding is required.
The installer:
- installs Tailscale using the official Tailscale Linux installer;
- enables
tailscaled.service; - runs
tailscale upif the Raspberry Pi is not already authenticated; - runs:
sudo tailscale serve --bg http://127.0.0.1:8080The --bg configuration persists across normal reboots.
If authentication is needed, Tailscale prints a login URL. Open the URL in a browser and approve the Raspberry Pi.
Check the Serve configuration with:
tailscale serve statusTailscale documentation:
- https://tailscale.com/docs/install/linux
- https://tailscale.com/docs/features/tailscale-serve
- https://tailscale.com/docs/reference/tailscale-cli/serve
Tailscale Funnel is similar to Serve, but the resulting HTTPS service is reachable from the public Internet. Visitors do not need a Tailscale client.
The public address uses the tailnet's *.ts.net DNS name.
The installer:
- installs and authenticates Tailscale;
- runs:
sudo tailscale funnel --bg http://127.0.0.1:8080Tailscale may display a web consent URL if HTTPS, MagicDNS or Funnel permissions still need to be enabled for the tailnet.
Check the Funnel configuration with:
tailscale funnel statusTailscale Funnel currently requires the Tailscale HTTPS/MagicDNS configuration and appropriate Funnel permission. Funnel is public, so the OSPy login page is exposed to the Internet.
Tailscale documentation:
- https://tailscale.com/docs/features/tailscale-funnel
- https://tailscale.com/docs/reference/tailscale-cli/funnel
| Requirement | Recommended mode |
|---|---|
| OSPy only on the local LAN | Local network only |
| Private remote access only for administrators | Tailscale Serve |
| Public OSPy with my own domain | Cloudflare Tunnel |
| Temporary public test without a domain | Cloudflare Quick Tunnel |
Public access without my own domain using *.ts.net
|
Tailscale Funnel |
For most permanent installations:
- use Tailscale Serve when only trusted administrators need remote access;
- use Cloudflare Tunnel when OSPy needs a normal public hostname.
The tunnel software used by these installer options does not require buying a separate TLS certificate.
At the time this documentation was updated:
- Cloudflare Tunnel is available with Cloudflare's free offering for this type of self-hosted access. A custom public hostname requires a domain placed in Cloudflare DNS; domain registration itself may have an annual cost.
- Cloudflare Quick Tunnel does not require an account or domain, but is only intended for testing/development.
- Tailscale Serve and Tailscale Funnel are available on Tailscale plans that support these features; Serve/Funnel use the tailnet's
*.ts.netnaming rather than requiring your own domain.
Provider plans and limits can change. Check the current Cloudflare or Tailscale documentation before relying on a particular commercial limit.
There are two different HTTPS designs.
For a new tunnel-based installation, keeping OSPy itself on local HTTP is the simplest design:
http://127.0.0.1:8080
The browser sees HTTPS because Cloudflare or Tailscale terminates the public TLS connection:
Browser --HTTPS--> Cloudflare/Tailscale --local HTTP--> OSPy
Do not enable OSPy's own HTTPS only because a tunnel is being used. The tunnel already provides the external TLS layer.
An existing OSPy installation that already uses HTTPS does not have to be converted back to HTTP for Cloudflare. The installer detects:
https://127.0.0.1:8080
and Cloudflare can use that as the Published application origin. If the local OSPy certificate is self-signed or does not match 127.0.0.1, enable No TLS Verify for that Cloudflare origin.
The older configuration is still possible. OSPy can use its own certificate and be exposed directly through the network/router.
For Let's Encrypt, install Certbot:
sudo apt-get install certbotCheck it:
certbot --versionRequest a certificate:
sudo certbot certonly --standalone -d your_domain_nameRenew it:
sudo certbot renewCopy the certificate and private key into the ssl directory of the installed OSPy checkout, for example:
sudo cp /etc/letsencrypt/live/your.domain.com/fullchain.pem /opt/OSPy/ssl/
sudo cp /etc/letsencrypt/live/your.domain.com/privkey.pem /opt/OSPy/ssl/
sudo systemctl restart ospy.serviceIf OSPy is installed in the user's home directory, use that OSPy path instead of /opt/OSPy.
The server-side HTTPS selection is explicit: the own certificate has priority, otherwise Let's Encrypt is used. Enabling both options does not cause a silent HTTP fallback.
Direct Internet exposure normally requires correct DNS and router/firewall/NAT configuration. It is not required when Cloudflare Tunnel, Tailscale Serve or Tailscale Funnel is used.
For a manually generated self-signed certificate:
cd /path/to/OSPy/ssl
sudo openssl req -new -newkey rsa:4096 -x509 -sha256 -days 3650 -nodes \
-out fullchain.pem -keyout privkey.pem
sudo systemctl restart ospy.serviceA self-signed certificate is not automatically trusted by browsers.
The installer creates a native systemd service from the versioned:
service/ospy.service
template, reloads systemd, enables and starts OSPy, then verifies that the service is active.
If OSPy startup fails, recent service output is printed and the installation returns an error.
Useful commands:
sudo systemctl status ospy.service
sudo systemctl restart ospy.service
sudo journalctl -u ospy.service -n 50 --no-pagerA reboot is only recommended for I2C or hardware-group changes. Choosing to reboot later is still a successful installation.
The installer verifies Python's built-in SQLite support with a temporary in-memory database and an integrity check.
No SQLite server, command-line program, API key or separate Python package is installed.
OSPy settings continue to use the existing shelve/DBM files. The SQLite test only confirms that the platform is ready for the separately controlled settings migration.
After a successful settings save, OSPy also creates a verified options.sqlite3 shadow copy beside the active shelve/DBM files. The shadow is written through a temporary file and atomically replaced only after its schema, keys, values and SQLite integrity check pass.
OSPy does not read settings from this shadow file during startup. If shadow synchronization fails, the shelve/DBM save remains valid and Diagnostics reports the failure without switching the active backend.
After installation, local access is:
http://<Raspberry-Pi-address>:8080
If a tunnel mode was selected, the installer also prints the remote address or a command that shows its status. For a managed Cloudflare Tunnel it stores the configured public URL in /etc/ospy/cloudflare_public_url, which allows the active public address to be shown in the OSPy footer without storing or exposing the Tunnel token.
On the first login:
- review the generated administrator password;
- sign in;
- change the administrator password immediately;
- make an OSPy backup after the initial configuration.
When the installer uses Local network only, it offers No password. Confirm it only when every device that can reach the Raspberry Pi is trusted: it grants administrator access without a login to all devices on that LAN. The installer records the same Disable security setting available under OSPy Options and does not show or require a generated password. Enable password protection in OSPy Options before connecting OSPy to a wider, shared, wireless, routed, or public network.
Do not delete ospy/data; that would remove configuration and history.
Use the local recovery script:
cd /path/to/OSPy
sudo systemctl stop ospy.service
sudo python3 back_door.py
sudo systemctl start ospy.serviceRun it only from the Raspberry Pi console or another trusted local shell and confirm by typing RESET.
The script resets the administrator name to admin, disables passwordless access and two-factor authentication, removes the TOTP secret and backup codes, revokes remembered browser logins and active web sessions, and generates a one-time recovery password.
Irrigation settings, programs, plug-ins and logs remain intact. Change the recovery password immediately after signing in.
Using Git, without the System Update plug-in, go to the OSPy directory containing run.py.
Create an OSPy backup first. Stop the service, verify that the checkout has no local changes, and accept only a fast-forward update:
sudo systemctl stop ospy.service
sudo git status --short
sudo git pull --ff-only
sudo systemctl start ospy.serviceIf git status --short prints files, do not discard them automatically. Review or back up the changes before updating.
The System Update plug-in remains the preferred update path because it creates a verified safety backup and uses the external rollback watchdog.
- Install a supported Raspberry Pi OS or Debian 12 image: https://www.raspberrypi.com/software/operating-systems/
- Configure a secure account/password.
- Enable SSH and I2C in
raspi-configif required. - Install OSPy using Git.
A setup file is also available for the older manual installation path.
Go to the directory containing setup.py:
cd /path/to/OSPyRefresh packages:
sudo apt-get updateOptionally upgrade the operating system:
sudo apt-get upgradeRun the historical setup procedure:
sudo python3 setup.py installFollow the prompts shown by the script.
This option supports automatic updating.
Ensure Git is installed and clone the stable branch:
git clone -b master https://github.com/martinpihrt/OSPyThen follow the manual setup procedure used by the project.
This option does not support automatic updating.
Download:
https://github.com/martinpihrt/OSPy/archive/master.zip
and extract it to the chosen installation directory.
If I2C was not enabled by the installer:
sudo raspi-configEnable the I2C interface and reboot:
sudo rebootOSPy repository · Releases · Plug-ins · Issues · Discussions