Docker Apps/Container Scripts
From Univention Wiki
For every Docker App, the App Center server may hold several scripts that do not need to be packaged. Even for package based Docker Apps, it is possible to integrate it without needing to build an additional integration package (like univention-app.deb). That being said, with increasing complexity, it is advised to build such a package nonetheless. Furthermore, not everything can be achieved easily with these scripts. There are interfaces rarely used that the App Center does not support. Should your Docker App require these interfaces, it may be necessary to create a package to (also) ship the scripts mentioned below.
We need to distinguish between outer scripts and inner scripts. An outer script is called on the Docker Host, inner scripts are called inside the running Docker Container.
All scripts are called with root privileges. For inner scripts this means the local root of the Docker Container. Some scripts may get LDAP credentials. Normally, these credentials are those of the Administrator account.
- The following list assumes that a package based Docker App is used as it is more important for these to have the scripts. Anyway, all of these scripts may also be used in image based Docker Apps. Normally, image based Docker Apps do not ship these scripts in the container itself. In this case, it is possible to upload them to the App Center server along with other meta files. They will be downloaded by the App Center and copied into the container right before execution. Package based Docker Apps already have these scripts in place. But even these Apps may upload scripts to the App Center server. These files will also be downloaded and copied, thus giving you the option to further enhance the functionality provided by default. It is strongly advised to not overwrite the existing scripts (which is possible), but instead copy them to another place and call the original script as the default behaviour is very likely important. For example, if you want to enhance the store_data script of a Docker App that is based on ucs-appbox, just change DockerScriptStoreData to somewhere in, say, /opt/app/ and call "/usr/share/univention-docker-container-mode/store_data $@" before or after your own logic.
Installation / uninstallation
The following scripts are for installation and uninstallation. Upgrades use these scripts, too, if (and only if) the upgrade includes an image exchange (i.e. the new version with the new ini file specifies a different DockerImage). In that case the old App is uninstalled and the new App is installed.
- These scripts may also be useful for image based Docker Apps. Especially inst, uinst, store_data, restore_data_after_setup.
- An outer script called before the Docker Container is initialized, even before the image is downloaded. Its purpose is to check whether installation may be successful. For example, the preinst may fail if certain hardware requirements are not met. Any exit code other than 0 will result in cancellation of the installation process. If the installation of an App is the result of an image exchange (and thus more of an upgrade) the preinst is also called. This script may also be used to setup the Host environment for the App before container creation, e.g., creating an outer directory with proper permissions.
- An inner script called before setup is called, right after the container is started. Its purpose is to restore those bits that may be needed to successfully run the setup script. May be useful in an upgrade process where one needs to restore the state the old container was in instead of setting up the container as if it were fresh.
- An inner script and heart of the whole installation process. By default it joins the system, (a script called univention-join provided by Univention), adds the repository that was created on the App Center server and installs DefaultPackages specified in the ini file. After that it once again joins, running all scripts that may have been installed during the App installation. If the script fails (exit code != 0) the installation is aborted.
- An inner script called after setup is called. Its purpose is to actually restore the data that may have been saved in store_data – now that the App is up and running but the database is still empty.
- Also called join script. An outer script called after the Docker Container is configured. Think of it as a postinst of the App. See the Developer Reference for how to write a join script. If the join script runs successfully, the join script may save this information in a status file. If this does not happen, the user is constantly reminded to re-run the join script. So the join script does not need to run successfully. The installation will not be aborted at this point. But of course at some point it should run through successfully. The main purpose of the join script is to set up the domain for the new App, e.g. by adding a domain user that can be used as the LDAP binddn that your App may need to authenticate against the central user management of UCS.
- An outer script called before the Docker Container is removed. Its purpose is to check whether an uninstallation may be successful. But it may be used to somehow prepare the system for the uninstallation. For example, the prerm may fail if other software still depends on it. Any exit code other than 0 will result in cancellation of the uninstallation process.
- An inner script called before removing the Docker Container. In fact the App is not really uninstalled. The container is just thrown away. This also happens during image upgrades: The current image is thrown away and a new image is set up. Therefore it is important to store the data of the current App to be able to start into exactly that state when the container was removed. You may call any App specific commands like myapp-backup --full or just copy the important files. The App Center always mounts the following directory into the container, which can be used to store the data (and later restore the data from there as the very same directory will be mounted into the new container): /var/lib/univention-appcenter/apps/$APPID/data/.
- Also called unjoin script. An outer script called after the Docker Container is removed. Think of it as a postrm of the App. See the Developer Reference for how to write an unjoin script. It should somehow revert most (if not all) changes done in the inst script (or join script). With the notable exception of schema registration. An LDAP schema extension should never be removed once it was registered.
Upgrade within the container
The following scripts are for upgrading the software within the Docker Container. Three possible scenarios have to be covered:
- Upgrade of system packages (security fixes, UCS calls them Errata Updates)
- Upgrade of the operating system (a new patchlevel release or even a minor/major update of UCS (4.1-1 or 4.2-0))
- Upgrade of App packages, i.e. a new version (with the same DockerImage) was released
- These scripts are useful for a Docker Container to run indefinitely and never be replaced. As such, they are probably not important to image based Docker Apps.
- An inner script called when the App Center wants to find out whether the container may install package updates or release updates. By default, this is done automatically once a day. It can be triggered manually, too, though. The script needs to echo the result: packages if mere package updates are available. These include security fixes for operating system packages. release: RELEASE if a new version of the operating itself is available. RELEASE can be anything, it is just presented to the user. Note that the script does not search for App updates, nor does it search for a change in the DockerImage! This is done by the "outer" App Center.
- An inner script called when (all) updates of existing packages shall be installed.
- An inner script called when a new version of the operating system shall be installed.
- An inner script called when a new version of the App packages shall be installed. This script is different from update_packages. This has technical reasons, because for normal UCS based Docker images, this requires a new repository to be registered. But it also has usability reasons: First, users may want to distinguish between necessary, stability improving package updates and (potentially) ground-shaking App updates; second, at least the UCS containers are configured to install security / stability updates automatically.