Defaults and install modes
Default Install, Advanced Install, User Defaults and App Defaults, the files behind them, and which value wins.
A container script can take its settings four ways. The install menu offers
them by name; mode= on the command line selects one without the menu.
| Menu entry | mode= | Settings come from |
|---|---|---|
| Default Install | default | The script, overridden by var_* on the command line |
| Advanced Install | advanced | The wizard, which starts from the same values |
| User Defaults | mydefaults | default.vars, shared by every script on the host |
| App Defaults | appdefaults | defaults/<app>.vars, for one app |
The code is in
ui/defaults.func
and install_script in
ui/menu.func.
Every variable is listed in the
configuration reference.
Where the files live
Both files sit in the state directory that community_scripts_dir returns:
| Situation | State directory |
|---|---|
COMMUNITY_SCRIPTS_STATE_DIR is set | that directory |
| Running as root (always the case on Proxmox VE) | /usr/local/community-scripts |
Non-root on Incus, and /usr/local/community-scripts is writable or can be created | /usr/local/community-scripts |
| Non-root on Incus otherwise | $XDG_CONFIG_HOME/community-scripts, by default ~/.config/community-scripts |
| File | Path in the state directory |
|---|---|
| User Defaults | default.vars |
| App Defaults | defaults/<app>.vars |
| Diagnostics choice | diagnostics |
<app> is the script's APP in lower case without spaces: defaults/jellyfin.vars
for ct/jellyfin.sh, defaults/adguard.vars for ct/adguard.sh.
User Defaults looks for default.vars in this order and uses the first that
exists: the state directory, /usr/local/community-scripts/default.vars,
$HOME/.config/community-scripts/default.vars, ./default.vars.
File format
# comment
var_brg=vmbr1
var_ssh=yes
var_timezone="Europe/Berlin"
var_mount_fs=nfs,cifs # an unquoted value ends at the #load_vars_file reads the file line by line and never executes it:
- only
var_name=valuelines count; anything else is ignored; - one pair of surrounding quotes is removed, and an unquoted value ends at
#; - each engine setting is validated; a bad value prints a warning such as
Invalid VLAN tag '5000' in <file> (must be 1-4094), ignoringand the run continues without it; - when a file is applied the script prints
Loading defaults from <file>andLoaded <file>.
Which value wins
Default Install
var_*from the command line- the script's own defaults
- the engine's built-in defaults
No .vars file is loaded. default.vars is only consulted for the storage
selection (see Storage).
Advanced Install
The wizard starts from the same values as Default Install, and what you answer replaces them. A few fields start blank whatever was set before; the wizard page names them.
User Defaults
var_*from the command line- values the script sets itself
default.vars- the engine's built-in defaults
A key in default.vars is applied only when nothing has set that variable
yet. Scripts set var_os, var_version, var_tags, var_unprivileged and
their resources at the top of the file, so default.vars does not change the
first four. The resources are the exception, described next.
If no default.vars exists, User Defaults creates one from a commented
template and asks for the two storages while doing so.
App Defaults
defaults/<app>.varsvar_*from the command line- the script's own defaults
The app's file is loaded with force: its values replace what the script and
the command line set. It also carries the app's own settings (for
ct/docker.sh, var_docker_compose and the like), which default.vars
cannot hold.
How resources are floored
variables records the script's var_cpu, var_ram and var_disk as
APP_DEFAULT_CPU, APP_DEFAULT_RAM and APP_DEFAULT_DISK before any file is
read. base_settings then uses the larger of that record and the current
value. The effect:
| Where the value comes from | Result |
|---|---|
default.vars or defaults/<app>.vars, higher than the script | the file's value |
default.vars or defaults/<app>.vars, lower than the script | the script's value |
| Command line, higher or lower | the command-line value |
| Advanced Install wizard | what you typed |
Example with ct/jellyfin.sh, which declares 2 cores, 2048 MiB and 16 GB:
default.varswithvar_ram=1024andmode=mydefaultsgives 2048 MiB;default.varswithvar_ram=4096gives 4096 MiB;var_ram=1024on the command line gives 1024 MiB, because the script'svar_ram="${var_ram:-2048}"never replaces a value that is already set, so 1024 is what gets recorded as the floor.
Whatever the source, less than 128 MiB of RAM is refused before the container is created.
Storage
var_container_storage and var_template_storage name the storages. When
they are missing:
- a host with exactly one storage for that content uses it without asking;
- otherwise the
Storage Poolsdialog asks, and the answer is written to the file of the chosen mode (default.varsfor Default Install, Advanced Install and User Defaults, the app's file for App Defaults).
Default Install does not load default.vars, so on a host with several
storages it shows the dialog on every run unless the two variables are on the
command line; while default.vars lacks the two lines it asks once even then.
User Defaults reads them from the file and does not ask again.
On Incus there is no template storage; only the pool for the container is
needed.
Saving App Defaults from the wizard
After Advanced Install, maybe_offer_save_app_defaults builds a new app file
from your answers and compares it with the saved one.
- No file yet: a yes/no dialog asks
Save these advanced settings as defaults for <app>?and names the path it would create. - File exists and nothing differs: nothing is asked.
- File exists and differs: the
APP DEFAULTSmenu opens.
| Entry | Effect |
|---|---|
Update Defaults | Replaces the file with the new values |
Keep Current | Leaves the file as it is |
View Diff | Shows the differences and returns to the menu |
Cancel (or Esc) | Leaves the file as it is |
The diff lists ~ name for a changed value with its old and new value,
- name for a line only in the saved file, and + name for a new one.
What the saved file contains:
- type, CPU, RAM, disk, bridge, IPv4 and gateway, MTU, VLAN, MAC, DNS, search domain, IPv6 method, SSH and key, APT cacher, proxy, host CA, the feature switches, protection, console mode, timezone, tags, verbose, hostname, SDN vnet, both storages and the post-install hook;
- the app's own
var_*settings, taken from the existing file and from the variables exported in this run.
What it leaves out: the root password, var_os, var_version,
var_github_token, a static IPv6 address, and everything in
What never comes from a file. A value
containing ;, &, $(, a backtick or <( is written empty, which includes
a var_tags list with more than one tag.
The wizard saves your hostname and a static var_net too. Remove those lines
if the file should serve more than one container.
File modes
| File | Written by | Mode |
|---|---|---|
defaults/<app>.vars | the wizard (install -m 0600) | 0600 |
default.vars | User Defaults, when it creates the file | 0644 |
default.vars | Default or Advanced Install, when the file is missing (touch) | the shell's umask, normally 0644 |
| either | the shell snippet from the website generator | 0600 |
The files are plain text. var_pw, var_github_token and an app's secrets are
stored as written, so restrict a default.vars that holds one:
chmod 600 /usr/local/community-scripts/default.varsWhat never comes from a file
| Variables | Behaviour |
|---|---|
var_arm64, var_bridge, var_ctid, var_external_installer, var_force_breaking_update, var_ignore_breaking_changes, var_ignore_disable, var_ignore_os_mismatch, var_install, var_ipv6_static, var_testurl | VAR_RESERVED. Skipped in every file with the warning ... is ignored: set it on the command line of the run that needs it. |
var_appversion, var_full_verbose, var_unattended | VAR_PER_RUN. Not read from default.vars and never written by the wizard. An app file loads them if you add the line by hand. |
| an app's own settings | Not read from default.vars; they belong in the app's file. |
Writing the files yourself
By hand:
mkdir -p /usr/local/community-scripts
cat <<'EOF' >>/usr/local/community-scripts/default.vars
var_brg=vmbr1
var_ssh=yes
var_container_storage=local-lvm
var_template_storage=local
EOFlocal-lvm and local are the storages of a default Proxmox VE installation;
use the names from pvesm status on your host.
From the menu: Settings has Edit Default.vars, and Edit App.vars once
an app file exists.
On the website: Host defaults builds default.vars,
and the generator builds an app file when step 3 is switched to
App defaults. Both give the file text and a shell snippet that replaces
the keys it sets, keeps the rest and leaves a .bak copy.
Then run with the matching mode:
mode=mydefaults bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/ct/debian.sh)"mode=appdefaults bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/ct/jellyfin.sh)"The second command exits with No App Defaults available for Jellyfin until
/usr/local/community-scripts/defaults/jellyfin.vars exists.