Difference between revisions of "Docker Apps/Image Based"

From Univention Wiki

Jump to: navigation, search
Line 1: Line 1:
As stated in [[App_Center/Dev/Docker_Apps#Two_kinds_of_Docker_Apps]] there are two types of Docker Apps: Apps that base upon a stand-alone Docker image
+
As stated in [[App_Center/Dev/Docker_Apps#Two_kinds_of_Docker_Apps]] there are two types of Docker Apps: Apps that base upon a stand-alone Docker image and Apps that install packages in a UCS based container.
and Apps that install packages in a UCS based container.
 
  
 
This chapter covers Apps that base upon a stand-alone Docker image.
 
This chapter covers Apps that base upon a stand-alone Docker image.
Line 6: Line 5:
 
= Use case =
 
= Use case =
  
A Docker App that is based upon a ready-to-use Docker image is fairly easy to create. All it needs is the
+
A Docker App that is based upon a ready-to-use Docker image is fairly easy to create. All it needs is the Docker image and the meta files. See [[App_Center/Dev/Meta_files]]. (Technically, only the ini file is required)
Docker image and the meta files. See [[App_Center/Dev/Meta_files]]. (Technically, only the ini file is required)
 
  
 
These Apps are useful when you already have a working image.
 
These Apps are useful when you already have a working image.
Line 13: Line 11:
 
= Life cycle =
 
= Life cycle =
  
The life cycle of such a Docker App is straight forward. This is what happens when installing the App in
+
The life cycle of such a Docker App is straight forward. This is what happens when installing the App in simplified code:
simplified code:
 
  
 
<pre>
 
<pre>
Line 30: Line 27:
 
</pre>
 
</pre>
  
There are a couple of scripts that the App may be bundled with (or that are already installed in the container).
+
There are a couple of scripts that the App may be bundled with (or that are already installed in the container). These scripts are explained in detail in [[App_Center/Dev/Docker_Apps_-_Package_based_Apps#Docker_Apps:_Scripts]].
These scripts are explained in detail in Section 6.3
 
  
The docker image is downloaded and started. After that some scripts are run to setup the container, restore data
+
The docker image is downloaded and started. After that some scripts are run to setup the container, restore data that has been previously backed up (there will be no backup when installing, but technically the scripts run).
that has been previously backed up (there will be no backup when installing, but technically the scripts run).
 
  
 
When the App is uninstalled, this is basically happening:
 
When the App is uninstalled, this is basically happening:
Line 45: Line 40:
 
backup=$(docker commit $container)
 
backup=$(docker commit $container)
 
docker stop $container || exit 1
 
docker stop $container || exit 1
mv /var/lib/univention-appcenter/apps/$app/data /var/lib/univention-
+
mv /var/lib/univention-appcenter/apps/$app/data /var/lib/univention-appcenter/backups/$backup/data
appcenter/backups/$backup/data
+
mv /var/lib/univention-appcenter/apps/$app/conf /var/lib/univention-appcenter/backups/$backup/conf
mv /var/lib/univention-appcenter/apps/$app/conf /var/lib/univention-
 
appcenter/backups/$backup/conf
 
 
docker rm $container
 
docker rm $container
 
if [ -e $app.unjoin ]; then $app.unjoin; fi
 
if [ -e $app.unjoin ]; then $app.unjoin; fi
 
</pre>
 
</pre>
  
The container is committed (as a backup), stopped and removed. A script has been run to backup any data of
+
The container is committed (as a backup), stopped and removed. A script has been run to backup any data of the App. As this is the uninstallation, this backup is moved to another directory.
the App. As this is the uninstallation, this backup is moved to another directory.
 
  
 
;''NOTE'': There is no easy tool to restore a backup. But the principal data is there, so it should be possible to get the App back running to the state before uninstallation. Again: This is not really supported, but present for convenience.
 
;''NOTE'': There is no easy tool to restore a backup. But the principal data is there, so it should be possible to get the App back running to the state before uninstallation. Again: This is not really supported, but present for convenience.
Line 60: Line 52:
 
= Upgrading an image based Docker App =
 
= Upgrading an image based Docker App =
  
When you want to release a new version of your Docker App, you need a new ini file. This ini file may be a
+
When you want to release a new version of your Docker App, you need a new ini file. This ini file may be a copy of your old file. But at least the <tt>Version</tt> needs to be greater than before. You probably also want to change <tt>DockerImage</tt>, as the new version will come with a new, updated image.
copy of your old file. But at least the <tt>Version</tt> needs to be greater than before.
 
You probably also want to change <tt>DockerImage</tt>, as the new version will come with a new, updated image.
 
  
This image needs to have a new name, too. Otherwise the App Center will not recognize that it needs to
+
This image needs to have a new name, too. Otherwise the App Center will not recognize that it needs to exchange the image.
exchange the image.
 
  
 
;''NOTE'': That's why you cannot simply name the <tt>DockerImage</tt> ''myapp:latest''.
 
;''NOTE'': That's why you cannot simply name the <tt>DockerImage</tt> ''myapp:latest''.
  
When this new ini file is released, the user may upgrade the Docker App. This is basically an uninstallation,
+
When this new ini file is released, the user may upgrade the Docker App. This is basically an uninstallation, followed by an installation. But the data is not moved during uninstallation, just copied, so that it is still there for the restore scripts.
followed by an installation. But the data is not moved during uninstallation, just copied, so that it is still there
 
for the restore scripts.
 
  
Also, only the app.preinst is run, not the prerm. And no app.unjoin is run. The app.join on the
+
Also, only the app.preinst is run, not the prerm. And no app.unjoin is run. The app.join on the other hand is run, but stops immediately unless the <tt>VERSION</tt> increased or it did not succeed yet with the previous App version. See also [[App_Center/Dev/Integration_with_UCS#Domain-Join_and_Unjoin]] for the join script.
other hand is run, but stops immediately unless the <tt>VERSION</tt> increased or it did not succeed yet with the
 
previous App version. See also Section 8.3 for the join script.
 
  
For a description of the scripts that run inside the container like app.store_data, please refer to Sec-
+
For a description of the scripts that run inside the container like app.store_data, please refer to [[App_Center/Dev/Docker_Apps_-_Package_based_Apps#Docker_Apps:_Scripts]]. It makes more sense to explain them there as they may not be needed in a imaged based Docker App.
tion 6.3. It makes more sense to explain them there as they may not be needed in a imaged based Docker App.
 
  
 
= Example =
 
= Example =
  
You have already seen an example that is nearly functional: [[App_Center/Dev/Meta_files#The_ini_file]]. Note the following variables
+
You have already seen an example that is nearly functional: [[App_Center/Dev/Meta_files#The_ini_file]]. Note the following variables in this ini file:
in this ini file:
 
  
;DockerScriptInit: Explicitely set empty. This also holds for DockerScriptStoreData, etc. This is done because these variables have default values which are overwritten this way. Otherwise the App Center complains about missing scripts.
+
;DockerScriptInit: Explicitely set empty. This also holds for <tt>DockerScriptStoreData</tt>, etc. This is done because these variables have default values which are overwritten this way. Otherwise the App Center complains about missing scripts.
  
 
;WebinterfacePortHTTP: Set to 8080 because the container starts Jenkins on that port. The container does not have any certificates, thus it does not provide a dedicated <tt>WebinterfacePortHTTPS</tt>. One could configure the container to do that by copying certificates and so on, but it is much easier to use 8080 for <tt>WebinterfacePortHTTPS</tt>, too.
 
;WebinterfacePortHTTP: Set to 8080 because the container starts Jenkins on that port. The container does not have any certificates, thus it does not provide a dedicated <tt>WebinterfacePortHTTPS</tt>. One could configure the container to do that by copying certificates and so on, but it is much easier to use 8080 for <tt>WebinterfacePortHTTPS</tt>, too.
  
;WebinterfaceProxy: The Webinterface integration is described in Section 8.5.2. In a nutshell, the container's port <tt>WebinterfacePortHTTP</tt> is exposed as some port between 40000 and 41000 on the host and this port is used by Apache's mod_proxy to connect to the container. By default, it uses HTTP for HTTP requests and HTTPS for HTTPS requests in the mod_proxy configuration. Setting WebinterfaceProxy to http, Apache connects through HTTP to the container also for external HTTPS requests. Even though the Jenkins container does not speak HTTPS, we can now connect to https://docker-host/jenkins/.
+
;WebinterfaceProxy: The Webinterface integration is described in Section 8.5.2. In a nutshell, the container's port <tt>WebinterfacePortHTTP</tt> is exposed as some port between 40000 and 41000 on the host and this port is used by Apache's mod_proxy to connect to the container. By default, it uses HTTP for HTTP requests and HTTPS for HTTPS requests in the mod_proxy configuration. Setting <tt>WebinterfaceProxy</tt> to http, Apache connects through HTTP to the container also for external HTTPS requests. Even though the Jenkins container does not speak HTTPS, we can now connect to https://docker-host/jenkins/.
  
;RequiredUCSVersion: Apps are released for one minor version of UCS (e.g. 4.1). Every UCS 4.1 may install such an App regardless which exact version is installed. Besides minor and major version of UCS, we also release Errata updates (security fixes, but also usability improvements and, to a certain extent, new features). We have greatly improved the support for image based Docker Apps since the release of UCS 4.1. We strongly suggest putting at least 4.1-1 as RequiredUCSVersion for any image based Docker App. Actually, it is a good idea to check http://errata.software-univention.de/ucs/4.1/ and just put the latest errata level into the ini file (especially those errata updates concerning the App Center package), just to save users from running into subtle bugs.
+
;RequiredUCSVersion: Apps are released for one minor version of UCS (e.g. 4.1). Every UCS 4.1 may install such an App regardless which exact version is installed. Besides minor and major version of UCS, we also release Errata updates (security fixes, but also usability improvements and, to a certain extent, new features). We have greatly improved the support for image based Docker Apps since the release of UCS 4.1. We strongly suggest putting at least 4.1-1 as <tt>RequiredUCSVersion</tt> for any image based Docker App. Actually, it is a good idea to check http://errata.software-univention.de/ucs/4.1/ and just put the latest errata level into the ini file (especially those errata updates concerning the App Center package), just to save users from running into subtle bugs.
  
The App will not work with only that ini file. First of all, the web interface can only be accessed at "/" by
+
The App will not work with only that ini file. First of all, the web interface can only be accessed at "/" by default. This does not work with the App Center's Apache integration. Secondly, the App does not save its data between App upgrades. Everything is wiped once the container is removed.
default. This does not work with the App Center's Apache integration. Secondly, the App does not save its
 
data between App upgrades. Everything is wiped once the container is removed.
 
  
 
Therefore, we use the jenkins.env file:
 
Therefore, we use the jenkins.env file:
Line 104: Line 85:
 
</pre>
 
</pre>
  
These variables are passed over to the container upon creation. They are supported by the Docker image itself
+
These variables are passed over to the container upon creation. They are supported by the Docker image itself and fix our issues. The web interface is accessible at "/jenkins" (compare to WebInterface) and the data is stored in a special directory. It is created on the Docker Host and mounted into every Docker Container. Thus, it survives an image exchange. See [[App_Center/Dev/Docker_Apps_-_Package_based_Apps#Docker_Apps:_Directories]] for the directories. See [[App_Center/Dev/Docker_Apps_-_Package_based_Apps#Docker_Apps:_Files]] for all files you may provide to support your Docker image in a UCS environment.
and fix our issues. The web interface is accessible at "/jenkins" (compare to WebInterface) and the data
 
is stored in a special directory. It is created on the Docker Host and mounted into every Docker Container.
 
Thus, it survives an image exchange. See Section 6.5 for the directories. See Section 6.4 for all files you may
 
provide to support your Docker image in a UCS environment.
 
  
 
= What the App Center does not support =
 
= What the App Center does not support =
  
Image based Docker Apps may only consist of one Docker image. Currently, the App Center does not support
+
Image based Docker Apps may only consist of one Docker image. Currently, the App Center does not support multiple containers linked together. It does not support docker-compose. There is only one <tt>DockerImage</tt> and this has to provide the full software stack.
multiple containers linked together. It does not support docker-compose. There is only one DockerImage and this has to provide the full software stack.
 
  
Depending on DockerVolumes, the image is created with the -v option. Depending on PortsExclu-
+
Depending on DockerVolumes, the image is created with the -v option. Depending on <tt>PortsExclusive</tt> and <tt>PortsRedirection</tt>, the image is created with the -p option. Depending on the env and the univention-config-registry-variables file, the image is created with the -e option. But other than that, the actual docker create command cannot be adapted by the App provider. The App Center does not support --cap-add, nor does it support --net.
sive and PortsRedirection, the image is created with the -p option. Depending on the env and the
 
univention-config-registry-variables file, the image is created with the -e option. But other
 
than that, the actual docker create command cannot be adapted by the App provider. The App Center
 
does not support --cap-add, nor does it support --net.
 
  
If your App needs a feature that the App Center does not (yet) provide, contact us. We will try to find a
+
If your App needs a feature that the App Center does not (yet) provide, contact us. We will try to find a workaround or maybe we add it in a software update.
workaround or maybe we add it in a software update.
 
  
 
[[Category:App Center Dev Doc]]
 
[[Category:App Center Dev Doc]]

Revision as of 15:19, 14 September 2016

As stated in App_Center/Dev/Docker_Apps#Two_kinds_of_Docker_Apps there are two types of Docker Apps: Apps that base upon a stand-alone Docker image and Apps that install packages in a UCS based container.

This chapter covers Apps that base upon a stand-alone Docker image.

Use case

A Docker App that is based upon a ready-to-use Docker image is fairly easy to create. All it needs is the Docker image and the meta files. See App_Center/Dev/Meta_files. (Technically, only the ini file is required)

These Apps are useful when you already have a working image.

Life cycle

The life cycle of such a Docker App is straight forward. This is what happens when installing the App in simplified code:

if [ -e $app.preinst ]; then $app.preinst || exit 1; fi
image=$(univention-app get $app DockerImage)
docker pull $image
container=$(docker create $image) # with some -p ports -v volumes -e env
docker start $container || exit 1
if [ -e $app.restore_data_before_setup ]; then docker exec $container
  $app.restore_data_before_setup || exit 1; fi
if [ -e $app.setup ]; then docker exec $container $app.setup || exit 1; fi
if [ -e $app.restore_data_after_setup ]; then docker exec $container
  $app.restore_data_after_setup || exit 1; fi
if [ -e $app.join ]; then $app.join; fi

There are a couple of scripts that the App may be bundled with (or that are already installed in the container). These scripts are explained in detail in App_Center/Dev/Docker_Apps_-_Package_based_Apps#Docker_Apps:_Scripts.

The docker image is downloaded and started. After that some scripts are run to setup the container, restore data that has been previously backed up (there will be no backup when installing, but technically the scripts run).

When the App is uninstalled, this is basically happening:

if [ -e $app.prerm ]; then $app.prerm || exit 1; fi
container=$(ucr get appcenter/apps/$app/container)
docker start $container || exit 1 # just in case
if [ -e $app.store_data ]; then docker exec $container $app.store_data || exit 1; fi
backup=$(docker commit $container)
docker stop $container || exit 1
mv /var/lib/univention-appcenter/apps/$app/data /var/lib/univention-appcenter/backups/$backup/data
mv /var/lib/univention-appcenter/apps/$app/conf /var/lib/univention-appcenter/backups/$backup/conf
docker rm $container
if [ -e $app.unjoin ]; then $app.unjoin; fi

The container is committed (as a backup), stopped and removed. A script has been run to backup any data of the App. As this is the uninstallation, this backup is moved to another directory.

NOTE
There is no easy tool to restore a backup. But the principal data is there, so it should be possible to get the App back running to the state before uninstallation. Again: This is not really supported, but present for convenience.

Upgrading an image based Docker App

When you want to release a new version of your Docker App, you need a new ini file. This ini file may be a copy of your old file. But at least the Version needs to be greater than before. You probably also want to change DockerImage, as the new version will come with a new, updated image.

This image needs to have a new name, too. Otherwise the App Center will not recognize that it needs to exchange the image.

NOTE
That's why you cannot simply name the DockerImage myapp:latest.

When this new ini file is released, the user may upgrade the Docker App. This is basically an uninstallation, followed by an installation. But the data is not moved during uninstallation, just copied, so that it is still there for the restore scripts.

Also, only the app.preinst is run, not the prerm. And no app.unjoin is run. The app.join on the other hand is run, but stops immediately unless the VERSION increased or it did not succeed yet with the previous App version. See also App_Center/Dev/Integration_with_UCS#Domain-Join_and_Unjoin for the join script.

For a description of the scripts that run inside the container like app.store_data, please refer to App_Center/Dev/Docker_Apps_-_Package_based_Apps#Docker_Apps:_Scripts. It makes more sense to explain them there as they may not be needed in a imaged based Docker App.

Example

You have already seen an example that is nearly functional: App_Center/Dev/Meta_files#The_ini_file. Note the following variables in this ini file:

DockerScriptInit
Explicitely set empty. This also holds for DockerScriptStoreData, etc. This is done because these variables have default values which are overwritten this way. Otherwise the App Center complains about missing scripts.
WebinterfacePortHTTP
Set to 8080 because the container starts Jenkins on that port. The container does not have any certificates, thus it does not provide a dedicated WebinterfacePortHTTPS. One could configure the container to do that by copying certificates and so on, but it is much easier to use 8080 for WebinterfacePortHTTPS, too.
WebinterfaceProxy
The Webinterface integration is described in Section 8.5.2. In a nutshell, the container's port WebinterfacePortHTTP is exposed as some port between 40000 and 41000 on the host and this port is used by Apache's mod_proxy to connect to the container. By default, it uses HTTP for HTTP requests and HTTPS for HTTPS requests in the mod_proxy configuration. Setting WebinterfaceProxy to http, Apache connects through HTTP to the container also for external HTTPS requests. Even though the Jenkins container does not speak HTTPS, we can now connect to https://docker-host/jenkins/.
RequiredUCSVersion
Apps are released for one minor version of UCS (e.g. 4.1). Every UCS 4.1 may install such an App regardless which exact version is installed. Besides minor and major version of UCS, we also release Errata updates (security fixes, but also usability improvements and, to a certain extent, new features). We have greatly improved the support for image based Docker Apps since the release of UCS 4.1. We strongly suggest putting at least 4.1-1 as RequiredUCSVersion for any image based Docker App. Actually, it is a good idea to check http://errata.software-univention.de/ucs/4.1/ and just put the latest errata level into the ini file (especially those errata updates concerning the App Center package), just to save users from running into subtle bugs.

The App will not work with only that ini file. First of all, the web interface can only be accessed at "/" by default. This does not work with the App Center's Apache integration. Secondly, the App does not save its data between App upgrades. Everything is wiped once the container is removed.

Therefore, we use the jenkins.env file:

JENKINS_OPTS=--prefix=/jenkins
JENKINS_HOME=/var/lib/univention-appcenter/apps/jenkins/data/jenkins_home

These variables are passed over to the container upon creation. They are supported by the Docker image itself and fix our issues. The web interface is accessible at "/jenkins" (compare to WebInterface) and the data is stored in a special directory. It is created on the Docker Host and mounted into every Docker Container. Thus, it survives an image exchange. See App_Center/Dev/Docker_Apps_-_Package_based_Apps#Docker_Apps:_Directories for the directories. See App_Center/Dev/Docker_Apps_-_Package_based_Apps#Docker_Apps:_Files for all files you may provide to support your Docker image in a UCS environment.

What the App Center does not support

Image based Docker Apps may only consist of one Docker image. Currently, the App Center does not support multiple containers linked together. It does not support docker-compose. There is only one DockerImage and this has to provide the full software stack.

Depending on DockerVolumes, the image is created with the -v option. Depending on PortsExclusive and PortsRedirection, the image is created with the -p option. Depending on the env and the univention-config-registry-variables file, the image is created with the -e option. But other than that, the actual docker create command cannot be adapted by the App provider. The App Center does not support --cap-add, nor does it support --net.

If your App needs a feature that the App Center does not (yet) provide, contact us. We will try to find a workaround or maybe we add it in a software update.

Personal tools