YENRA LINUX WEB-SERVICE EXAMPLE
September 5, 2026
https://yenra.com/linux-web-applications/

Purpose: an inspectable, read-only Python WSGI teaching application on a dedicated
Debian 13 test host, using packaged Gunicorn, systemd, and Caddy. It has no login,
database, uploads, or personal data. Do not treat it as a complete production
application or security template. The archive contains no automatic installer.

Files may be copied, modified, and reused; attribution to Yenra is appreciated.
No warranty is provided. Review the files and adapt them to your environment.

PREPARATION
Use a fresh test host with administrator access. Review existing listeners,
firewall rules, repositories, and any existing web-server configuration. Keep a
console/recovery path. Do not overwrite unrelated services or Caddy site blocks.

Run these commands individually as an administrator after reviewing their output:
sudo apt update
sudo apt install python3 gunicorn caddy curl

Package installation may start Caddy's default site. On a shared host, resolve
existing web-port use before installation. Confirm executable paths with:
command -v python3
command -v gunicorn
command -v caddy

CREATE THE APPLICATION ACCOUNT AND INSTALL REVIEWED FILES
The account name must be unused. If it already exists, inspect it and choose an
appropriate account deliberately, updating the unit consistently.

sudo useradd --system --user-group --no-create-home --home-dir /nonexistent --shell /usr/sbin/nologin yenra-web-demo
sudo install -d -o root -g root -m 0755 /opt/yenra-web-demo

From the directory containing the extracted, reviewed sample files:
sudo install -o root -g root -m 0644 app.py /opt/yenra-web-demo/app.py
sudo install -o root -g root -m 0644 yenra-web-demo.service /etc/systemd/system/yenra-web-demo.service
sudo systemd-analyze verify /etc/systemd/system/yenra-web-demo.service

Fix verification errors before continuing. The supplied unit uses the Debian
packaged executable /usr/bin/gunicorn. An isolated virtual environment needs a
different ExecStart path and its own reviewed dependency/update plan.

START AND TEST LOCALLY
sudo systemctl daemon-reload
sudo systemctl enable --now yenra-web-demo
sudo systemctl status yenra-web-demo --no-pager
curl --fail http://127.0.0.1:8000/healthz
curl --head http://127.0.0.1:8000/
sudo ss -ltnp
sudo journalctl -u yenra-web-demo -n 50 --no-pager

Expected: /healthz returns status 200 with "ok" plus a newline. / returns the
greeting. HEAD returns the corresponding headers and no body. /missing returns
404. POST returns 405 with Allow: GET, HEAD. The application listener must be
127.0.0.1:8000, not a public interface. Gunicorn uses two gthread workers with
four threads each as an illustrative starting configuration, not a sizing rule.

PROXY AND HTTPS
Review Caddyfile.example. Replace app.example.com with a hostname you control.
On a fresh host, back up the default /etc/caddy/Caddyfile, then install the reviewed
site configuration there. On a shared host, integrate the block without replacing
existing sites or global settings. Caddy must be able to read its configuration.

Point DNS A/AAAA records to the intended server. Ensure any published IPv6 address
works. Configure host/network firewalls for the required public web traffic and
Caddy's certificate challenge; keep port 8000 private. Public HTTP/HTTPS typically
uses TCP 80 and 443. Preserve your separate administrative access rules.

sudo caddy validate --config /etc/caddy/Caddyfile --adapter caddyfile
sudo systemctl reload caddy
sudo journalctl -u caddy -n 50 --no-pager

Test https://YOUR-HOSTNAME/healthz from another machine. Do not use the literal
placeholder. A valid config does not prove DNS, firewall, certificate issuance,
or backend availability. Inspect logs if the public test fails.

ON-HOST ACCEPTANCE
Test normal GET, HEAD, unknown path, and unsupported method behavior through the
public proxy. Test service restart and a controlled reboot. Confirm monitoring
detects a stopped app, then restore it. Verify permissions and loopback binding.
For a real app, evaluate timeouts, client buffering, concurrency, input limits,
authentication, logging/privacy, dependency health, backups, and capacity.

UPDATE AND ROLLBACK
Keep a known-good copy of the code and service/proxy configuration. For a simple
stateless replacement, schedule the interruption, stop yenra-web-demo, install
the reviewed code, start it, and repeat health and behavior tests. Restore the
known-good code if those tests fail. Database changes require a separate,
data-aware rollback plan; this sample has no database. Apply host/runtime updates
through the chosen distribution/support process and review release changes.

VALIDATION SCOPE FOR THIS DOWNLOAD
The Python application was exercised with a WSGI test server, including status,
body, header, HEAD, query-string, unknown-path and unsupported-method behavior.
A real Caddy 2.11.4 reverse-proxy process was tested locally on Windows, and the
example Caddyfile was validated. This does not test Debian's package build,
Gunicorn/systemd startup, sandbox enforcement, reboot, or public TLS issuance.
Complete the on-host acceptance checks before exposing your deployment.

PRIMARY REFERENCES
https://gunicorn.org/deploy/
https://manpages.debian.org/trixie/systemd/systemd.exec.5.en.html
https://caddyserver.com/docs/caddyfile/directives/reverse_proxy
https://caddyserver.com/docs/automatic-https
https://caddyserver.com/docs/command-line
