This is a first draft of a container customization howto. Due to Podman, troubleshooting or customizations need to be done inside app environments and containers which I’d like to explain in this howto.
Podman in NS8
Introduction
Podman provides rootless containers which are running as user. Most NS8 apps make use of these rootless containers.
Those apps are located in /home/
like linux users whereas rootfull apps are located in /var/lib/nethserver
.
Information about specific app customizations can be found on the GitHub page of the app, see for example SOGo.
App Environment
To enter a rootless app environment, you can use the runagent command, see Rootless vs Rootfull | NS8 dev manual
runagent -m app1
It’s also possible to append a command. In this case the command is executed in the app environment but you don’t enter it:
runagent -m app1 command
To list the running containers and their names you could use podman ps
. As root you’ll see the rootfull containers, in an app environment you’ll see the containers of the rootless app.
podman ps
With podman the containers are started via systemd, a container is a service. To stop or (re)start a container or get the status you could use systemctl, see https://community.nethserver.org/t/ns8-starting-stopping-apps/23231:
systemctl --user stop containername
systemctl --user start containername
systemctl --user restart containername
systemctl --user status containername
To run a command in the container or to enter the container you could use podman exec, see podman-exec — Podman documentation
podman exec -ti containername command
If the command is a shell you’ll enter the container, for example
podman exec -ti dovecot sh
Data and volumes
In containers the data is saved in volumes. To manage volumes you could use podman volume
, see podman-volume — Podman documentation
To list the volumes:
podman volume ls
The volumes of rootless containers of app1 are located in /home/app1/.local/share/containers/storage/volumes/
Local and container users and permissions
Usually the local app1 user is the root user in the container.
In the following example the local user roundcubemail3 is root in the container:
[root@ns8rockytest ~]# ls -l /home/roundcubemail3/.local/share/containers/storage/volumes/html/_data/
total 372
-rw-r--r--. 1 roundcubemail3 roundcubemail3 216244 Feb 8 09:47 CHANGELOG.md
-rw-r--r--. 1 roundcubemail3 roundcubemail3 12714 Feb 8 09:47 INSTALL
-rw-r--r--. 1 roundcubemail3 roundcubemail3 35147 Feb 8 09:47 LICENSE
-rw-r--r--. 1 roundcubemail3 roundcubemail3 3853 Feb 8 09:47 README.md
-rw-r--r--. 1 roundcubemail3 roundcubemail3 1049 Feb 8 09:47 SECURITY.md
drwxr-xr-x. 7 roundcubemail3 roundcubemail3 4096 Feb 8 09:47 SQL
-rw-r--r--. 1 roundcubemail3 roundcubemail3 4657 Feb 8 09:47 UPGRADING
drwxr-xr-x. 2 roundcubemail3 roundcubemail3 4096 Feb 8 09:47 bin
-rw-r--r--. 1 roundcubemail3 roundcubemail3 993 Jun 11 11:18 composer.json
-rw-r--r--. 1 roundcubemail3 roundcubemail3 1086 Feb 8 09:47 composer.json-dist
-rw-r--r--. 1 roundcubemail3 roundcubemail3 56747 May 26 09:31 composer.lock
drwxr-xr-x. 2 roundcubemail3 roundcubemail3 148 Apr 29 12:00 config
-rw-r--r--. 1 roundcubemail3 roundcubemail3 11200 Feb 8 09:47 index.php
drwxr-xr-x. 2 886464 886464 23 Feb 8 09:47 logs
drwxr-xr-x. 37 roundcubemail3 roundcubemail3 4096 Feb 8 09:47 plugins
drwxr-xr-x. 8 roundcubemail3 roundcubemail3 94 Feb 8 09:47 program
drwxr-xr-x. 3 roundcubemail3 roundcubemail3 83 Feb 8 09:47 public_html
drwxr-xr-x. 3 roundcubemail3 roundcubemail3 21 Feb 8 09:47 skins
drwxr-xr-x. 2 roundcubemail3 roundcubemail3 23 Feb 8 09:47 temp
drwxr-xr-x. 14 roundcubemail3 roundcubemail3 4096 May 26 09:31 vendor
[root@ns8rockytest ~]# runagent -m roundcubemail3 podman exec roundcubemail-app ls -l
total 372
-rw-r--r--. 1 root root 216244 Feb 8 08:47 CHANGELOG.md
-rw-r--r--. 1 root root 12714 Feb 8 08:47 INSTALL
-rw-r--r--. 1 root root 35147 Feb 8 08:47 LICENSE
-rw-r--r--. 1 root root 3853 Feb 8 08:47 README.md
-rw-r--r--. 1 root root 1049 Feb 8 08:47 SECURITY.md
drwxr-xr-x. 7 root root 4096 Feb 8 08:47 SQL
-rw-r--r--. 1 root root 4657 Feb 8 08:47 UPGRADING
drwxr-xr-x. 2 root root 4096 Feb 8 08:47 bin
-rw-r--r--. 1 root root 993 Jun 11 09:18 composer.json
-rw-r--r--. 1 root root 1086 Feb 8 08:47 composer.json-dist
-rw-r--r--. 1 root root 56747 May 26 07:31 composer.lock
drwxr-xr-x. 2 root root 148 Apr 29 10:00 config
-rw-r--r--. 1 root root 11200 Feb 8 08:47 index.php
drwxr-xr-x. 2 www-data www-data 23 Feb 8 08:47 logs
drwxr-xr-x. 37 root root 4096 Feb 8 08:47 plugins
drwxr-xr-x. 8 root root 94 Feb 8 08:47 program
drwxr-xr-x. 3 root root 83 Feb 8 08:47 public_html
drwxr-xr-x. 3 root root 21 Feb 8 08:47 skins
drwxr-xr-x. 2 root root 23 Feb 8 08:47 temp
drwxr-xr-x. 14 root root 4096 May 26 07:31 vendor
If a user doesn’t exist locally you’ll just see the UID and GID instead of a name like for the logs
directory which is owned by www-data in the container but local it has a UID/GID of 886464.
Software installation in containers
It’s possible to install packages in the containers, this could be needed for troubleshooting or to test implementing new features. Installed packages are not persistent, after restarting the container they’re not kept.
Most containers are Debian/Ubuntu or Alpine based so you could use apk (Alpine) or apt (Ubuntu/Debian) to install packages.
Debian/Ubuntu:
apt update
apt install packages
Alpine:
apk add package