This is a self deploying container for running a Univention Corporate Server (UCS) with the role of primary, backup, replica directory node or managed node.
This is the container environment with additional amount settings and some recommendations to store your files.
first and second start/boot ( systemctl status univention-container-mode-firstboot.service univention-container-mode-recreate.service )
The systemd service units univention-container-mode-firstboot and univention-container-mode-recreate has some start conditions to detect an old container environment.
systemctl cat univention-container-mode-firstboot.service
...
[Unit]
...
ConditionPathExists=!/var/univention-join/joined
ConditionPathExists=!/var/univention-join/status
ConditionPathExists=!/etc/univention/base.conf
...
systemctl cat univention-container-mode-recreate.service
...
[Unit]
...
ConditionPathExists=/var/univention-join/joined
ConditionPathExists=/var/univention-join/status
ConditionPathExists=!/etc/univention/base.conf
...
Based on the Dockerfile you can find some default volumes, but follow up you will find some recommendations to store your files.
There is a systemd service unit called univention-container-mode-backup. This unit will create a basic backup loop on each container stop/shutdown and once at first start/boot. Backups ( univention-container-mode.$(date --utc +%FT%T.%3NZ).xz )
older then 120 ( ${backup_clean_min_backups:-120} )
days will be removed during the shutdown automaticly. To enable this feature use the environment variable:
--env BACKUPS=(1|yes|true|YES|TRUE)
If there is a vaild backup available, you can set force an old version inside the container with the environment variable:
--env RESTORE=(force|FORCE)
This be expected to fix the problem of losing your manual changes with docker-compose pull && docker-compose up ( --force-recreate )
in future for rudimentary services like ldap, ssl, ssh ... . But remember, you can't change the ${hostname}
or ${domainname}
!
--volume ${CONTAINER-VOLUME-BACKUPS}:/var/backups:rw
Otherwise, use a volume like --volume ${DOCKER-VOLUME-BACKUP}:/var/backups/univention-container-mode:rw
to enable the feature without any backup loop. ( With this option you don't need the environment variable! )
--volume ${CONTAINER-VOLUME-BACKUP}:/var/backups/univention-container-mode:rw
--volume ${CONTAINER-VOLUME-JOINED}:/var/univention-join:rw ( optionally )
ls -1 /var/backups/univention-container-mode*
/var/backups/univention-container-mode.$(date --utc +%FT%T.%3NZ).xz
/var/backups/univention-container-mode.xz
/var/backups/univention-container-mode:
( 99 ) certificates
( 99 ) ldap *without any APPs*
( 99 ) ldap *SAMBA, CUPS, ...*
( 99 ) packages
( 99 ) registry
( 99 ) samba
( 99 ) saml
( 99 ) secrets
( 99 ) ssh
( STATUS IN PERCERNT ) package(s) synonym
To be sure that the systemd service unit univention-container-mode-backup will work well, check your default StopTimeout for minimum of 300 seconds or use the container run / container compose option --stop-timeout 300
/ --stop-grace-period 300
( docker run ... --stop-timeout 300 / docker service create ... --stop-grace-period 300 ).
Alternative just add --shutdown-timeout 300
or { ..."shutdown-timeout": 300... }
to your docker daemon or docker daemon config file.
ucr search --brief ^appcenter/apps | awk '/installed$/{ split($1,APP,"/"); print APP[3] }'
systemd-analyze blame | egrep -- univention-container-mode-recreate.service
18min 41.336s univention-container-mode-recreate.service
rm --force --recursive /var/backups/univention-container-mode/* && \
time systemctl restart univention-container-mode-backup.service
real 0m2.659s
user 0m0.014s
sys 0m0.004s
ucr search --brief ^appcenter/apps | awk '/installed$/{ split($1,APP,"/"); print APP[3] }'
cups
samba4
systemd-analyze blame | egrep -- univention-container-mode-recreate.service
29min 52.170s univention-container-mode-recreate.service
rm --force --recursive /var/backups/univention-container-mode/* && \
time systemctl restart univention-container-mode-backup.service
real 0m40.941s
user 0m0.004s
sys 0m0.016s
Expand LDAP with LDIF file(s) on a primary directory node ( legacy term: "master" ). Optionally in univention config registry template format.
cat *.ldif
dn: ...,dc=ucs,dc=example
cat *.ldif ( with ucr template format )
dn: ...,@%@ldap/base@%@
There is a temporary univention config registry key called net/get/domain/sid
to get the domains security identifier during the LDIF import. Hopefully useful, you find the max relative identifier and the well known identifiers for domain users, guests and admins too.
cat domain.users.ldif ( with ucr template format )
dn: uid=<UserID>,cn=users,@%@ldap/base@%@
changetype: add
...
uidNumber: @!@
ucr = dict(); ucr.update(configRegistry); print('%s' % ( int(ucr.get('net/get/domain/uid/max')) + 1 ))
@!@gidNumber: @%@net/get/domain/gid/users@%@
...
sambaSID: @%@net/get/domain/sid@%@-@!@
ucr = dict(); ucr.update(configRegistry); print('%s' % ( int(ucr.get('net/get/domain/rid/max')) + 1 ))
@!@sambaPrimaryGroupSID: @%@net/get/domain/sid@%@-@%@net/get/domain/rid/users@%@
...
dn: cn=Domain Users,cn=groups,@%@ldap/base@%@
changetype: modify
add: uniqueMember
uniqueMember: uid=<UserID>,cn=users,@%@ldap/base@%@
dn: cn=Domain Users,cn=groups,@%@ldap/base@%@
changetype: modify
add: memberUid
memberUid: <UserID>
cat domain.admins.ldif ( with ucr template format )
dn: uid=<AdminID>,cn=users,@%@ldap/base@%@
changetype: add
...
gidNumber: @%@net/get/domain/gid/admins@%@
...
sambaPrimaryGroupSID: @%@net/get/domain/sid@%@-@%@net/get/domain/rid/admins@%@
...
Read more about SIDs (security identifiers).
STEP 1. collect the LDIF file(s) in a directory like ${PWD}/univention-ldap-ldif
, maybe with a new ldap/ldap-backup secrect too
STEP 2. finally mount the volume read only
--volume ${CONTAINER-VOLUME-LDIF}:/usr/local/share/univention-ldap:ro
UCR TEMPORARY KEYS | DEFAULTS AND RANGES |
---|---|
net/get/domain/sid | domain security identifier |
net/get/domain/rid/admins | rID(512) domain admins |
net/get/domain/rid/users | rID(513) domain users |
net/get/domain/rid/guests | rID(514) domain guests |
net/get/domain/rid/max | rIDAllocationPool{1100..1599} |
net/get/domain/gid/admins | gidNumber(5000) domain admins |
net/get/domain/gid/users | gidNumber(5001) domain users |
net/get/domain/gid/guests | gidNumber(5002) domain guests |
net/get/domain/uid/max | uidNumber{2000..????} |
--volume ${CONTAINER-VOLUME-UNIVENTION-BACKUP}:/var/univention-backup:rw
It’s always a good idea to save your home
and/or root
directory and if you plan to use cifs
( aka: samba ).
--volume ${CONTAINER-VOLUME-CIFS}:/<YOUR PREFERRED STORAGE POINT>:rw
--volume ${CONTAINER-VOLUME-HOME}:/home:rw
--volume ${CONTAINER-VOLUME-ROOT}:/root:rw
If you plan to use Docker in Docker, try this for a small perfomance boost for any inner containers ( overlay storage inside overlay storage isn't nice ).
SETP 0.) Be sure the module xfs
is permanently loaded in your system or directly in your linux kernel.
modules=/etc/modules; module=xfs; ( lsmod; [[ -f ${modules} ]] && echo $(<${modules}) ) | egrep -- ^${module} || \
( [[ -f ${modules} ]] && echo ${module} >> ${modules}; modprobe ${module} )
STEP 1.) Create your exclusive container disk or volume. ( ATTENTION: mkfs.xfs -f
will force erase the whole disk/volume )
mkfs.xfs -f /dev/<EXCLUSIVE-CONTAINER-DISK or EXCLUSIVE-CONTAINER-VOLUME>
--device /dev/${EXCLUSIVE-CONTAINER-DISK}:/dev/storage:rw