synology-app.yaml reference
synology-app.yaml sits next to compose.yaml in a project made with synopkgland init -t compose. synopkgland check validates it. Unknown top-level keys are accepted by the schema, but only the fields below have an effect. The task-first walkthrough is in Container apps.
Fields
Section titled “Fields”| Field | Type | Required | Default | Description |
|---|---|---|---|---|
schema | integer | Yes | None | Must be 1. |
package | string | Yes | None | Package identifier. Up to 32 characters (CONTRACT_PACKAGE_TOO_LONG); over 28 gives PACKAGE_IDENTITY_TOO_LONG because deploy --dev adds .dev. |
version | string | Yes | None | Package version. -0001 is appended when there is no -<number> suffix. |
displayname | string | Yes | None | Name shown in Package Center. |
description | string | Yes | None | Package description. |
maintainer | string | Yes | None | Maintainer name. |
os_min_ver | string | Yes | None | Minimum DSM version, for example "7.2.1-69057". The container floor is 7.2.1-69057. |
adminprotocol | string | No | None | Protocol for the package’s web entry. Not used when the app goes through the gateway. |
adminport | integer | No | None | Host port of the web UI. It must equal exactly one published TCP host port. Leave it out for a headless app. |
adminurl | string | No | None | Path appended to the web entry. |
install | map | No | None | Installation wizard settings, keyed by name. |
install.<name>.type | string | Yes | None | One of string, boolean, secret, shared_folder, dsm_user, homes, posix_all_shares. |
install.<name>.default | string, boolean | No | None | Default value. Not allowed for homes and posix_all_shares. |
install.<name>.generate | boolean | No | None | Generate a value at install time. |
integration | map | No | None | How the app integrates with DSM. Only web is allowed. |
integration.web | map | No | None | Web entry settings. Requires adminport. |
integration.web.launch | string | No | dsm-window | dsm-window (DSM main-menu and desktop entry that opens a new browser tab) or new-page (Package Center Open only). |
integration.web.cookies | list of strings | No | None | Cookies to forward through Web Station. Only meaningful with access: public; the gateway drops all cookies. id and did are never forwarded. |
integration.web.access | string | No | dsm-users | dsm-users, dsm-admins, dsm-groups or public. |
integration.web.groups | list of strings | Only with dsm-groups | None | DSM group names (at least one). |
integration.web.portal | map | No | None | Not available. A Compose app has no executor; check fails with CONTRACT_PORTAL_REQUIRES_EXECUTOR. An administrator can set up a reverse proxy in DSM instead. |
permissions | none | No | None | Always rejected. |
privilege | map | No | None | Accepted so the error is clear; every flag below is always rejected. |
privilege.privileged | boolean | No | None | Always rejected (COMPOSE_PRIVILEGED_FORBIDDEN). |
privilege.host_network | boolean | No | None | Always rejected (COMPOSE_HOST_NETWORK_FORBIDDEN). |
privilege.host_pid | boolean | No | None | Always rejected (COMPOSE_HOST_PID_FORBIDDEN). |
privilege.host_ipc | boolean | No | None | Always rejected (COMPOSE_HOST_IPC_FORBIDDEN). |
privilege.devices | boolean | No | None | Always rejected (COMPOSE_DEVICES_FORBIDDEN). |
privilege.cap_add | boolean | No | None | Always rejected (COMPOSE_CAP_ADD_FORBIDDEN). |
icon | string | No | SDK default icon | Square PNG of at least 256×256 inside the project, or a directory of icon_<size>.png with icon_256.png. Used for Package Center and the DSM window (CONTRACT_ICON_INVALID). |
reproducible | object | No | None | Settings for build --verify-reproducible; see reproducible builds. |
reproducible.inputs | string[] | No | None | Dependency files, relative to the project, whose SHA-256 forms the fingerprint, for example compose.yaml. At most 64. |
reproducible.clean | string[] | No | None | Paths removed before the second build. May use {arch}. At most 64. |
i18n | map | No | None | Translations. Only info is allowed (CONTRACT_I18N_INVALID). |
i18n.info | map | No | None | Keyed by zh-TW, zh-CN, ja, ko, de, fr, es or it; English stays in displayname and description. Writes INFO displayname_<lang> and description_<lang>; with launch: dsm-window it also localizes the DSM main-menu and desktop label. |
i18n.info.<name>.displayname | string | No | displayname | One line without " or \. Once any translation exists, the top-level displayname and description follow the same rule. |
i18n.info.<name>.description | string | No | description | One line without " or \. |
metadata | map | No | None | Package Center listing details. No other keys are allowed. |
metadata.changelog | string, map | No | None | Up to 16000 characters, or a map of up to 32 locales. |
metadata.contact_email | string | No | None | Email address. |
metadata.support_email | string | No | None | Email address. |
metadata.homepage | string | No | None | URL starting with http:// or https://. |
metadata.source_url | string | No | None | URL starting with http:// or https://. |
metadata.issues_url | string | No | None | URL starting with http:// or https://. |
metadata.license | string | No | None | License name. |
metadata.maintainer_url | string | No | None | URL starting with http:// or https://. |
metadata.distributor | string | No | None | Distributor name. |
metadata.distributor_url | string | No | None | URL starting with http:// or https://. |
metadata.support_url | string | No | None | URL starting with http://, https:// or mailto:. |
metadata.helpurl | string | No | None | URL starting with http:// or https://. |
metadata.long_description | string, map | No | None | Up to 16000 characters, or a map of up to 32 locales. |
metadata.screenshots | list of strings | No | None | Up to 12 http:// or https:// URLs, each up to 2048 characters. |
The string fields package, version, displayname, description, maintainer and os_min_ver must not be empty, contain control characters or contain ${ (CONTRACT_INVALID_STRING). capabilities is not a field of a container app (CAPABILITY_UNSUPPORTED).
Install setting types
Section titled “Install setting types”Reference a setting in compose.yaml as ${<name>}. A name matches ^[A-Za-z_][A-Za-z0-9_]*$.
type | Wizard field | Rules |
|---|---|---|
string | Text field, not blank | Default up to 256 characters, no control characters, no ${ (INSTALL_STRING_TOO_LONG, INSTALL_STRING_INVALID). |
boolean | Checkbox | Value is true or false. |
shared_folder | Shared Folder picker | Use as a bind source. |
dsm_user | User picker | At most one (CONTRACT_DSM_USER_DUPLICATE). Adds <name>_UID, <name>_GID and <name>_GROUP_1 to <name>_GROUP_8. The build sets user on every service. |
posix_all_shares | None | No default or value allowed. Use as a whole bind source with no suffix. Only deploy can fill it. |
homes | None | check warns (CONTRACT_HOMES_UNSUPPORTED); deploy refuses it. No path or default allowed. |
secret | None | check warns (CONTRACT_SECRET_UNSUPPORTED); deploy refuses it. |
A string, boolean, shared_folder, homes or posix_all_shares setting that Compose never references gives INSTALL_PARAMETER_UNREFERENCED. Declaring a shared_folder without a dsm_user gives DSM_USER_REQUIRED (a warning for your own builds, an error for a Community listing).
Compose rules
Section titled “Compose rules”| Rule | Code |
|---|---|
No build: | COMPOSE_BUILD_FORBIDDEN |
No privileged: true | COMPOSE_PRIVILEGED_FORBIDDEN |
No network_mode: host | COMPOSE_HOST_NETWORK_FORBIDDEN |
No pid: host or ipc: host | COMPOSE_HOST_PID_FORBIDDEN, COMPOSE_HOST_IPC_FORBIDDEN |
No devices or cap_add | COMPOSE_DEVICES_FORBIDDEN, COMPOSE_CAP_ADD_FORBIDDEN |
No socket mounts (/var/run/docker.sock, the Container Manager socket, any */docker.sock) | COMPOSE_SOCKET_MOUNT_FORBIDDEN |
No host paths; ./sub inside the project is allowed | COMPOSE_HOST_BIND_FORBIDDEN |
Bind sources: ${SYNOPKG_PKGVAR}, ${SYNO_APP_SECRETS_DIR}, or a shared_folder, homes or posix_all_shares setting | COMPOSE_BIND_SOURCE_FORBIDDEN, COMPOSE_BIND_SOURCE_UNDECLARED |
Sub-path after ${X} matches (/[A-Za-z0-9._-]+)+ | COMPOSE_BIND_SUFFIX_INVALID |
Named volumes are declared under top-level volumes: | COMPOSE_NAMED_VOLUME_UNDECLARED |
user: is not set when a dsm_user exists | COMPOSE_USER_CONFLICTS_DSM_USER |
No user: 0, 0:0 or root when a shared_folder exists | COMPOSE_USER_ROOT_FORBIDDEN |
No numeric user: | COMPOSE_USER_NUMERIC_FORBIDDEN |
The adminport host port is published on 127.0.0.0/8 or ::1 | COMPOSE_GATEWAY_PORT_EXPOSED |
No pure-number string in command or entrypoint lists | COMPOSE_NUMERIC_COMMAND_ARG_FORBIDDEN |
No top-level secrets: or configs:; every ${NAME} is declared | COMPOSE_DYNAMIC_ROUTE_UNSUPPORTED |
depends_on names an existing service | COMPOSE_SERVICE_NOT_FOUND |
Images that are not pinned by digest are reported as a risk. synopkgland images pin pins them. See Errors for what each code means.