edox-ops
Production-oriented Python CLI for preparing and operating Ubuntu 24.04 LTS, Debian 12+, and Debian derivatives (including Raspberry Pi OS) for documentation hosting with nginx, rsync deploys, and optional GitLab Runner.
Requirements
- Python 3.11+
- Target host: Ubuntu 24.04, Debian 12+, or a Debian derivative (e.g.
Raspberry Pi OS) for
bootstrap,doctor, and project operations
Install
pip install edox-ops
Pin a version (pip install edox-ops==0.1.0), use a venv, and host prerequisites:
website/docs/installation.md (published at
esysdox-ops.org/docs/installation).
Development setup
Automated (contributor venv + hooks + smoke checks):
# Linux / macOS
./scripts/setup-dev.sh
# Windows (PowerShell)
.\scripts\setup-dev.ps1
Options: --with-docs / -WithDocs, --skip-verify / -SkipVerify,
--recreate-venv / -RecreateVenv, --install-glab / -InstallGlab, --no-glab / -NoGlab.
Checks Python 3.11+ up front; can install glab after confirmation. See
Contributing.
Manual:
python -m venv .venv
source .venv/bin/activate # or .venv\Scripts\activate on Windows
pip install -e ".[dev]"
pip install pre-commit
pre-commit install
pre-commit install --hook-type commit-msg
To build and publish the edox-ops package (sdist/wheel, TestPyPI, PyPI, GitLab PyPI),
install the release extra and follow docs/guides/package-release.md:
pip install -e ".[dev,release]"
make build
make dist-check
Usage
edox-ops bootstrap --yes
edox-ops doctor
edox-ops gitlab-runner install --yes # optional CI executor on the host
export EDOX_RUNNER_TOKEN=TOKEN # preferred: avoids token in shell history
edox-ops gitlab-runner register --url https://gitlab.example.com
edox-ops project add my-docs --domain docs.example.com
edox-ops project init my-docs
edox-ops project deploy my-docs
edox-ops project enable my-docs
edox-ops project validate my-docs
Deploy backups and restore
Each deploy with existing content creates a timestamped snapshot under
/var/www/docs/.edox-ops-backups/<slug>/. List them and roll back the live tree:
edox-ops project backups list my-docs
edox-ops project restore my-docs --yes
edox-ops project restore my-docs --backup /var/www/docs/.edox-ops-backups/my-docs/20260102T120000Z --yes
restore overwrites the served directory; --yes is required (same contract as
bootstrap --yes).
HTTPS (optional)
Typical flow: enable the site over HTTP, issue a certificate, then switch to TLS.
edox-ops certs install --yes
edox-ops project add my-docs --domain docs.example.com
edox-ops project init my-docs
edox-ops project deploy my-docs
edox-ops project enable my-docs
edox-ops project certs issue my-docs --email you@example.com --yes
edox-ops project update my-docs --tls
edox-ops project enable my-docs
edox-ops certs setup-auto-renew --yes
setup-auto-renew installs Certbot, the nginx reload deploy hook, and enables
certbot.timer so certificates renew on a schedule without manual steps.
Optional host hardening:
edox-ops host harden --yes # security-updates + firewall + fail2ban
edox-ops host security-updates --yes
edox-ops host firewall --yes # use --ssh-port if sshd is not on 22
edox-ops host fail2ban --yes # sshd jail; match --ssh-port to sshd
edox-ops host ssh-harden --yes # key-based SSH only; test access first
edox-ops host logrotate --yes # rotate /var/log/edox-ops/*.log
To host this repo's documentation build on a VPS (bootstrap, harden, deploy
website/build/, TLS), see docs/guides/vps-docs-hosting.md.
doctor and project validate check that fullchain.pem and privkey.pem exist
under /etc/letsencrypt/live/<domain>/ before you enable a TLS site. certs renew
reloads nginx after a successful renewal.
Project documentation
Public documentation uses Docusaurus (website/) for guides and blog posts, and
Sphinx (docs-api/) for Python API reference. Built API HTML is embedded under
/api/ in the Docusaurus output.
pip install -e ".[docs]"
make docs-api # API reference only
make docs-dev-api-sync # preview /api/ with npm start
make docs # full static site → website/build/
cd website && npm install && npm start # local dev server (Windows nvm4w: C:\nvm4w\nodejs\npm.cmd)
See docs/documentation-architecture.md and docs/documentation-build.md.
Published docs (GitLab Pages): esysdox-ops.org on pushes to
master (when the custom domain is live); esysdox-ops-d340b4.gitlab.io
on every push to develop and as the default hostname until then.
See docs/guides/commit-messages.md for commit message rules and
docs/guides/commit-checklist.md for the pre-commit checklist.
Contributing: onboarding (GitLab access, environment, Cursor AI) —
website/docs/contributing.md (published as /docs/contributing);
index in docs/guides/how-to-contribute.md.
Cursor AI: project context in instructions.md; rules in
.cursor/rules/.
Continuous integration
GitLab (primary): .gitlab-ci.yml runs Ruff, pytest with coverage, and Docker
integration tests. On version tags (vX.Y.Z), it also builds Python packages and can
publish to GitLab PyPI, TestPyPI, and PyPI.
- First push and first pipeline:
docs/guides/gitlab-getting-started.md - SSH keys and canonical remote
git@gitlab-ai:libesys/esysdox-ops.git:docs/guides/gitlab-ssh-keys.md - Pipeline, DinD, and runners:
docs/guides/gitlab-ci.md - Package build and release:
docs/guides/package-release.md - Release pipeline (automated tag tests + publish):
docs/guides/release-pipeline.md - Release hygiene (Dependabot, audits, first tag):
docs/guides/release-hygiene.md - Agent access to CI results (
glab, API):docs/guides/gitlab-ci-agent-access.md
GitHub (optional): .github/workflows/ci.yml runs the same checks if you mirror
the repository.
Run the same checks locally:
pip install -e ".[dev]"
ruff check src tests scripts/pre_commit scripts/gitlint_rules.py
ruff format --check src tests scripts/pre_commit scripts/gitlint_rules.py
python -m pytest -q --cov=edox_ops
Integration tests
Docker-based integration tests live under tests/integration/. GitLab CI runs a full
harness on Ubuntu 24.04 and Debian 12, plus an ARM64 smoke job (Debian 12 /
Raspberry Pi proxy on native ARM runners).
# Ubuntu 24.04 (default)
bash tests/integration/run_docker.sh
# Debian 12
BASE_IMAGE=debian:12 bash tests/integration/run_docker.sh
License
Licensed under the Apache License, Version 2.0. Copyright 2026 Michel Gillet and contributors.
Metadata
Release files for edox-ops 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| edox_ops-0.1.0.tar.gz | 86.8 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| edox_ops-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 155.6 kB
Release files / edox_ops-0.1.0.tar.gz
| Download URL | edox_ops-0.1.0.tar.gz |
|---|---|
| Size | 86.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
f78c9dcb17475875dfda2f0404156fbdc8f747c9c6990d87062513e37af014b0
|
|
BLAKE2b-256 checksum How to use checksums |
2b5ca1496d8958d569c8f4a4b365b7d9b0ed0a489c92255e7feb4a9992f71a9c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.11.15
|
Release files / edox_ops-0.1.0-py3-none-any.whl
| Download URL | edox_ops-0.1.0-py3-none-any.whl |
|---|---|
| Size | 68.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
bcccd7402f26eba4d7124102cfb284a2ece87edb0d6b4aa0729c68dcdfecf0d2
|
|
BLAKE2b-256 checksum How to use checksums |
18827112abc20dae4ee51db87b01efa621202851475255c6ef17c278ce1b958c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.11.15
|
Security for edox-ops 0.1.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.