Helper functions
Find the right Core helper for a task and jump to its reference page.
Install and update scripts do not download, unpack or configure things by hand. The
engine (community-scripts/core) ships
helpers for the recurring jobs, and update_os loads them: lib/tools.func on
every distribution except Alpine, lib/alpine.func on Alpine. Do not source a helper file from a
script yourself.
This page answers "which helper do I need". Signatures, variables, return codes and
examples are on the reference pages it links to. The CI-checked list of every
function is lib/API.txt.
Reference pages
| Page | Source | Covers |
|---|---|---|
| Core | core/core.func | Messages, prompts, random_password, arch_resolve |
| Error handling | core/error_handler.func | catch_errors, exit codes, what happens when a command fails |
| Forge | lib/forge.func | Release checks and downloads from GitHub, GitLab and Codeberg |
| System | lib/system.func | Packages, APT repositories, keys, services, certificates, backups |
| Runtimes and tools | lib/runtime.func | Node.js, uv/Python, Go, Rust, Ruby, Java, .NET, PHP, Docker, FFmpeg |
| Databases | lib/db.func | PostgreSQL, MariaDB, MySQL, MongoDB, ClickHouse, MeiliSearch |
| Hardware acceleration | lib/hwaccel.func | setup_hwaccel and GPU passthrough |
| Alpine | lib/alpine.func | The helper set available in Alpine containers |
I need a ...
Database
Install the engine, then create the application's database and user. See Databases.
| Need | Call |
|---|---|
| PostgreSQL | setup_postgresql, then setup_postgresql_db |
| MariaDB | setup_mariadb, then setup_mariadb_db |
| MySQL | setup_mysql, then setup_mysql_db |
| MongoDB | setup_mongodb |
| ClickHouse | setup_clickhouse |
| MeiliSearch | setup_meilisearch |
Set the database name and user on their own lines, not as a prefix of the call, and
read the password from PG_DB_PASS / MARIADB_DB_PASS afterwards:
PG_VERSION="17" setup_postgresql
PG_DB_NAME="myapp"
PG_DB_USER="myapp"
setup_postgresql_dbFor PostgreSQL, a package and its extension are two settings: PG_MODULES on
setup_postgresql installs the package (pgvector), PG_DB_EXTENSIONS on
setup_postgresql_db creates the extension (vector).
There is no Redis or Valkey helper; install those with apt.
Runtime
Use these when the app needs a newer version than the distribution ships. See Runtimes and tools.
| Need | Call |
|---|---|
| Node.js, npm, pnpm, yarn | NODE_VERSION="24" NODE_MODULE="pnpm" setup_nodejs |
| Python | PYTHON_VERSION="3.13" setup_uv |
| Go | setup_go, optionally with GO_VERSION |
| Rust | setup_rust, optionally with RUST_CRATES |
| Ruby | RUBY_VERSION="..." setup_ruby |
| Java | JAVA_VERSION="21" setup_java |
| .NET | DOTNET_VERSION="10" DOTNET_TYPE="sdk" setup_dotnet |
| PHP, Composer | PHP_VERSION="8.4" PHP_FPM="YES" setup_php, then setup_composer |
| FFmpeg, Ghostscript, ImageMagick, yq | setup_ffmpeg, setup_gs, setup_imagemagick, setup_yq |
setup_go accepts a bare major.minor such as 1.22 and resolves it to the newest
patch release, so the go line of a go.mod can be passed as it is.
Every setup_* and fetch_and_deploy_* helper prints its own msg_info / msg_ok
lines. Do not wrap the call in another pair.
Fetching the application
Never download a release with raw curl and tar. Use a fetch_and_deploy_*
function from Forge, chosen by what upstream publishes:
| Upstream has | Call |
|---|---|
| Releases on GitHub, GitLab or Codeberg | fetch_and_deploy_gh_release, fetch_and_deploy_gl_release, fetch_and_deploy_codeberg_release |
| Tags only | fetch_and_deploy_gh_tag, fetch_and_deploy_gl_tag |
| A branch only | fetch_and_deploy_gh_branch |
| A fixed URL | fetch_and_deploy_from_url |
The release functions take a mode that has to match the asset: tarball (source),
binary (a .deb), prebuild (an archive to unpack) or singlefile (one binary).
They record the deployed version in ~/.<app>, which is what the update check reads.
A hand-rolled download breaks updates even if the install worked.
For assets named per architecture, call arch_resolve inside the asset pattern, as
lib/db.func does for MeiliSearch: "meilisearch-linux-$(arch_resolve amd64 aarch64)".
Checking for an update
In update_script(), gate the deployment on check_for_gh_release "<app>" "owner/repo"
(or check_for_gl_release, check_for_codeberg_release, check_for_gh_tag,
check_for_gh_branch). It succeeds only when a newer version exists. Calling
fetch_and_deploy_* unconditionally re-downloads and restarts the service on every
update run. See Forge.
Repository, packages or a service
See System.
| Need | Call |
|---|---|
| A third-party APT repository | setup_deb822_repo |
| A signing key on its own | download_gpg_key, verify_gpg_fingerprint |
| Packages, with retries | ensure_dependencies, install_packages_with_retry, upgrade_packages_with_retry |
| A download, with retries | curl_with_retry |
| A self-signed certificate | create_self_signed_cert |
| An nginx site switched on | nginx_enable_site (Runtimes and tools) |
Data persistence across CLEAN_INSTALL and updates
CLEAN_INSTALL=1 on a fetch_and_deploy_* call empties the target directory before
the new release is unpacked. Anything the user created in that directory is gone
afterwards, and the update still reports success. In order of preference:
- Keep persistent data outside the app directory, for example in
/opt/<app>_data. - If the data cannot be moved, name the paths to keep:
CLEAN_INSTALL_KEEP="backend/server/media"(fromct/adventurelog.sh). The value is a space-separated list of paths relative to the target. - For single files,
create_backupbefore the fetch andrestore_backupafter it.
Do not park backups in /tmp. Details are on Forge and
System.
Prompting for input
Use prompt_input, prompt_input_required, prompt_confirm or prompt_select
from Core instead of a raw read. They carry a timeout and
a default, so an unattended run does not hang.
Password or secret
random_password [length] returns an alphanumeric string, 24 characters by default.
The database helpers generate their own password when none is given. See
Core.
GPU
Set var_gpu="${var_gpu:-yes}" in the ct/ script and call setup_hwaccel in the
install script, with the service user as argument if the app does not run as root.
See Hardware acceleration.
Docker
setup_docker installs Docker Engine. ensure_docker is the precondition check for
tools/addon/*.sh scripts that ship a Compose stack. Most application
scripts install the app natively; the few whose app needs a Docker daemon, such as
install/docker-install.sh and install/cosmos-install.sh, call setup_docker. See
Runtimes and tools.
Alpine
Alpine containers get lib/alpine.func instead of lib/tools.func. It defines a
smaller set under the same names, among them fetch_and_deploy_gh_release,
check_for_gh_release, setup_yq, setup_uv, setup_java, setup_go,
setup_composer and setup_adminer. The database helpers, setup_nodejs,
setup_php and setup_hwaccel are not available there. See
Alpine.
A helper is missing
If something would be useful to many scripts, add it to Core with a test and an
updated lib/API.txt instead of copying a private version into installers.