Build custom container images / build (map[base_image:php:8-fpm-alpine build_args:PHP_VERSION=8
context:php8-pgsql fingerprint_command:{ apk info -v | LC_ALL=C sort; find /usr/local/lib/php/extensions /usr/local/etc/php/conf.d -type f -exec sha256sum {} + | LC_ALL=C sort; }
name:ph… (push) Successful in 47s
Build custom container images / build (map[base_image:postgres:18 build_args:PG_VERSION=18
POSTGIS_VERSION=3
VCHORD_VERSION=0.5.3
context:postgres fingerprint_command:{ dpkg-query -W -f='${binary:Package}=${Version}\n' | LC_ALL=C sort; find /usr/lib/postgresql -type f -exec sha256su… (push) Successful in 1m40s
Build custom container images / build (map[base_image:python:3 build_args:PYTHON_VERSION=3
context:python-tools fingerprint_command:{ dpkg-query -W -f='${binary:Package}=${Version}\n' | LC_ALL=C sort; pip freeze | LC_ALL=C sort; }
name:python-tools oci_labels:org.opencontainers.ima… (push) Successful in 1m18s
119 lines
5.5 KiB
Markdown
119 lines
5.5 KiB
Markdown
# Python Tools
|
|
|
|
This image is a Python 3 task runner with ExifTool and a small web control panel
|
|
for running known, mounted Python maintenance tasks. It starts the control panel
|
|
with `python -m app`.
|
|
|
|
## Control Panel
|
|
|
|
The application discovers direct `*.py` files in each non-hidden directory
|
|
under `/opt/tasks`. Each directory is a task group. Tasks in one group run
|
|
sequentially; different groups may run concurrently. It records run history and
|
|
combined output in SQLite under `/var/lib/server-maintenance`, and supports
|
|
cancellation of active task process groups.
|
|
|
|
The image contains application code only. Mount these paths at runtime:
|
|
|
|
- `/opt/tasks` read-only: reviewed task scripts and their input manifests.
|
|
- `/opt/credentials` read-only: named credential files used by those scripts.
|
|
- `/var/lib/server-maintenance`: persistent SQLite data, logs, and task state.
|
|
|
|
Task processes receive a minimal environment. To forward non-secret container
|
|
settings to tasks, list their names in `SERVER_MAINTENANCE_TASK_ENV`, separated
|
|
by commas. This allowlist prevents unrelated container configuration from
|
|
being exposed to every task; credentials should remain in `/opt/credentials`.
|
|
|
|
Tasks are never imported during discovery. Their optional description is the
|
|
first line of their module docstring. A task must not require stdin or command
|
|
line arguments, should write useful output, and must return a non-zero exit
|
|
code on failure.
|
|
|
|
## Task inputs
|
|
|
|
An optional `task-inputs.json` beside a group's task files declares the fields
|
|
for its web forms and its task order. It is parsed as data only and uses version
|
|
`1`:
|
|
|
|
```json
|
|
{
|
|
"version": 1,
|
|
"label": "Example Tasks",
|
|
"tasks": {
|
|
"task.py": {
|
|
"inputs": [
|
|
{"name": "identifier", "label": "Identifier", "type": "text", "required": true},
|
|
{"name": "attempts", "label": "Attempts", "type": "integer", "minimum": 1, "maximum": 5, "default": 2},
|
|
{"name": "mode", "label": "Mode", "type": "choice", "options": ["standard", "extended"]},
|
|
{"name": "alerts", "label": "Alerts", "type": "multi_choice", "options": ["email", "webhook"]}
|
|
]
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
Supported field types are `text`, `integer`, `date`, `datetime`, `choice`,
|
|
`multi_choice`, and `file`. Text may also define a regular-expression
|
|
`pattern`; integer fields accept `minimum`, `maximum`, and `step`. Choices may
|
|
use strings or objects with `value` and `label`. File fields accept a list of
|
|
lowercase filename extensions in `accept` and a byte limit in `maximum_bytes`.
|
|
An input can define `required` and `default`.
|
|
Set `sensitive` to `true` for a value or upload that must not appear in run
|
|
history. The form masks sensitive text, the database records `[redacted]`, and
|
|
the original value is available only through a private execution input file.
|
|
Tasks listed in the manifest appear in JSON order. A listed task may use `{}`
|
|
when it only needs ordering; unlisted scripts appear afterward in alphabetical
|
|
order. `label` is optional and overrides the group name displayed in the UI.
|
|
Set `wait_for_result` to `true` for a short task whose form should wait for its
|
|
final success or failure status. This disables the form and warns before
|
|
leaving the page while the task is running; tasks without it keep the normal
|
|
queued-run behavior.
|
|
|
|
For a task with a review-first operation, declare `execution` with the input
|
|
field and its review and execution values. The control panel generates the
|
|
mode selector attached to the submit button. A successful review run offers a
|
|
button that repeats the same saved inputs using the execution value; it does not reuse a stale filesystem
|
|
snapshot, so the task must still validate its inputs before changing anything.
|
|
|
|
The server validates every submitted value before a run is queued. It records
|
|
the validated object in the run database and writes it to a per-run file.
|
|
Sensitive fields are redacted in the database and use a private `0600`
|
|
execution file instead. Tasks read the applicable file path from
|
|
`SERVER_MAINTENANCE_INPUT`; no user value is appended to the command line. A
|
|
task without an entry in the manifest gets an empty JSON object. Uploaded files
|
|
are stored in a private per-run directory; their absolute paths are provided in
|
|
the input JSON and the files are removed when the task finishes, fails, or is
|
|
cancelled.
|
|
|
|
## Downloads
|
|
|
|
Tasks can write downloadable files to the directory named by
|
|
`SERVER_MAINTENANCE_ARTIFACTS`. Set `download_artifacts` to `true` alongside
|
|
`wait_for_result` to start the first artifact download after a successful web
|
|
run. Run-detail pages also show available downloads. The server deletes an
|
|
artifact after its HTTP transfer ends; any undownloaded artifact is removed
|
|
after 24 hours. A browser cannot confirm that a downloaded file was retained
|
|
on the client device.
|
|
|
|
## Background tasks
|
|
|
|
An optional `background-tasks.json` beside a group's task files declares
|
|
internal recurring scripts. These scripts must live below the group's
|
|
`internal/` directory, are not exposed in the UI, and are launched at most once
|
|
per configured interval. Their latest output is retained below the persistent
|
|
state directory rather than being added to normal run history.
|
|
|
|
```json
|
|
{
|
|
"version": 1,
|
|
"tasks": [
|
|
{"id": "poll", "script": "internal/poll.py", "interval_seconds": 60}
|
|
]
|
|
}
|
|
```
|
|
|
|
`compose.example.yaml` is suitable for adding the service to an existing Compose
|
|
stack. Set `PYTHON_TOOLS_VOLUME_ROOT` to the host directory that will hold
|
|
`state`, `tasks`, and `credentials`; set
|
|
`SERVER_MAINTENANCE_ALLOWED_PROXY_IPS` to the reverse proxy's direct peer
|
|
address. Keep the application behind an authenticated reverse proxy.
|