Der PcFreak, this is OUTSTANDING.

Thank you very much.

On Mon, Oct 28, 2024 at 11:13 AM Der PCFreak <[email protected]>
wrote:

> Hi,
>
> Does anyone have notes or a guide to setup Guacamole as Rootless in Podman?
>
> I have an issue with the Database communicating with the Guacamole
> Container
>
> I have Guacamole running with podman rootless. It works like a charm. I
> use Quadlets to define the containers and the network. Through the quadlets
> I gave the conatiners specific names and did not even export any ports
> except for the web-frontend. Because of the internal podman networking
> bridge connectivity between the containers it just works.
>
> I try to summarize my setup here (should work on Alma, Rocky or RHEL):
> OS Level
>
>    1. Installed container tools using
>
> dnf -y install container-tools
>
>
>    2. Create a non privileged user named podrunner with uid 2000
>
> # as root or with sudo# create the user podrunner with UID 2000
> useradd -u 2000 -m -s /sbin/nologin -d /home/podrunner -c "rootless user to 
> run containers" podrunner
>
>
>    3. Enable Lingering for the user (keeps the containers started even
>    user logs out)
>
> # as root or with sudo# enable lingering to allow services of this user to 
> persist even user is not logged in# the user does not need a shell since it 
> will never login directly
> loginctl enable-linger podrunner
>
>
>    4. Fix XDG_RUNTIME_DIR for podrunner user
>
> sudo su -l podrunner -s /bin/bash# as user podrunnermkdir -p ~/.bashrc.decho 
> "export XDG_RUNTIME_DIR=/run/user/$(id -u)" > ~/.bashrc.d/systemdmkdir -p 
> ~/.config/containers/systemd
>
>
>    5. Create the folder structure for podman quadlets with systemd
>
> # become user podrunner first (sudo su -l podrunner -s /bin/bash)# as user 
> podrunner create folder structure for user systemd services/quadletsmkdir -p 
> ~/.config/containers/systemd# become user podrunner first (sudo su -l 
> podrunner -s /bin/bash)# as user podrunner create folder structure for user 
> systemd services/quadletsln -s ~/.config/containers/systemd ~/quadlets
>
>
>    6. Create alias podrunner
>
> # as your sudo user NOT ROOT# User specific environment and startup 
> programsalias podrunner='sudo su -l podrunner -s /bin/bash'alias 
> containers='echo "Containers for user podrunner";sudo systemd-run 
> --machine=podrunner@ --quiet --user --collect --pipe --wait podman container 
> ps --all'
>
> If you now execute the command podrunner as your sudo user you
> immediately will become the user podrunner and land in its home directory.
>
>    7. Verify the setup
>
> # become user podrunner first (sudo su -l podrunner -s /bin/bash)# as user 
> podrunner run
> podman run --rm --rmi quay.io/podman/hello
>
> The output should look like this:
>
> Trying to pull quay.io/podman/hello:latest...
>
> Getting image source signatures
> Copying blob 81df7ff16254 done   |
> Copying config 5dd467fce5 done   |
> Writing manifest to image destination
> !... Hello Podman World ...!
>
>          .--"--.
>        / -     - \
>       / (O)   (O) \
>    ~~~| -=(,Y,)=- |
>     .---. /`  \   |~~
>  ~/  o  o \~~~~.----. ~~
>   | =(X)= |~  / (O (O) \
>    ~~~~~~~  ~| =(Y_)=-  |
>   ~~~~    ~~~|   U      |~~
>
> Project:   https://github.com/containers/podman
> Website:   https://podman.io
> Desktop:   https://podman-desktop.io
> Documents: https://docs.podman.io
> YouTube:   https://youtube.com/@Podman
> X/Twitter: @Podman_io
> Mastodon:  @[email protected]
>
> Quadlets and environment files
>
> Now the quadlets (alle located in
> /home/podrunner/.config/containers/systemd)
> Network
>
> # 
> ~/.config/containers/systemd/guacamole-net.network###############################################################
>  systemd specific 
> section##############################################################
> [Unit]Description=guacamole-net
> [Install]WantedBy=default.target#############################################################################################################################
>  podman specific 
> section##############################################################
> [Network]Label=guacamole-netDisableDNS=false##############################################################
>
> # as podrunner
> systemctl --user daemon-reload
> systemclt --user start guacamole-net-network.service
>
> This does bring up the docker network bridge named systemd-guacamole-net.
> This is a one shot service so it will stop automatically and its purpose
> is just to bring up the network.
> PostgreSQL
>
> Environment file
> /home/podrunner/containers/guacamole/guacamole-pgdb-environment
>
> POSTGRES_USER=guacamolePOSTGRES_PASSWORD=<your strong 
> password>POSTGRES_DB=guacamole# must be a subfolder of 
> /var/lib/postgresql/dataPGDATA=/var/lib/postgresql/data/guacamole
>
> Quadlet file for PostgreSQL
>
> # 
> ~/.config/containers/systemd/guacamole-pgdb.container###############################################################
>  systemd specific 
> section##############################################################
> [Unit]Description=guacamole-pgdb
> [Service]# Restart service if it failsRestart=always# generate initdb.sql if 
> not already existsExecStartPre=/bin/sh -c 'if ! [ -f dbinit/initdb.sql ]; 
> then podman run --name "temp-guacamole-generatedbscript" --rm 
> "docker.io/guacamole/guacamole:1.5.5" /opt/guacamole/bin/initdb.sh 
> --postgresql > "/home/%u/containers/guacamole/dbinit/initdb.sql"; fi'# Extend 
> Timeout to allow time to pull the imageTimeoutStartSec=900
> [Install]# Start by default on 
> bootWantedBy=default.target#############################################################################################################################
>  podman specific 
> section##############################################################
> [Container]# override default name of containerContainerName=guacamole-pgdb# 
> Volumes for 
> postgresVolume=/home/%u/containers/guacamole/data:/var/lib/postgresql/data:Z# 
> Volume for database initialization# PostgreSQL container will look for .sql 
> files in docker-entrypoint-initdb.d# if not database is present. This 
> mechanism is used to initialize the database.# If a database is already 
> present, the .sql files will not be applied and# nothing 
> happens.Volume=/home/%u/containers/guacamole/dbinit:/docker-entrypoint-initdb.d:Z#
>  create or join a network# if the name of the network ends with .network, a 
> Podman network called systemd-$name# is used, and the generated systemd 
> service contains a dependency on the 
> $name-network.serviceNetwork=guacamole-net.network# What image to 
> useImage=docker.io/library/postgres:17.0# Environment variables for 
> posgresEnvironmentFile=/home/%u/containers/guacamole/guacamole-pgdb-environment#
>  since we run a rootless container we# want to keep the current user 
> idRemapUsers=keep-id# What to execute. If not defined it uses# the default 
> from the image#Exec=sleep 
> 60##############################################################
>
> Reload systemd unit files and start the container
>
> # as user podrunner
> systemctl --user daemon-reload
> systemctl --user start guacamole-pgdb.service
>
> Your Guacamole PostgreSQL database should run now (no port exposed since
> it is available inside the podman network bridge we created).
> Guacd
>
> Environment file
>
> #/home/podrunner/containers/guacamole/guacamole-guacd-environment# configure 
> environment for guacd hereRECORDING_SEARCH_PATH=/drives_rec
>
> Quadlet
>
> # 
> ~/.config/containers/systemd/guacamole-guacd.container###############################################################
>  systemd specific 
> section##############################################################
> [Unit]Description=guacamole-guacdAfter=guacamole-pgdb
> [Service]# Restart service if it failsRestart=always# Extend Timeout to allow 
> time to pull the imageTimeoutStartSec=900
> [Install]# Start by default on 
> bootWantedBy=default.target#############################################################################################################################
>  podman specific 
> section##############################################################
> [Container]# override default name of containerContainerName=guacamole-guacd# 
> Volumes for guacd# These are the volumes for the users file transfer 
> folder(s) (drives)# and the users session recordings 
> (recordings)Volume=/home/%u/containers/guacamole/drives:/drives:rw,ZVolume=/home/%u/containers/guacamole/drives_rec:/drives_rec:rw,z#
>  create or join a network# if the name of the network ends with .network, a 
> Podman network called systemd-$name# is used, and the generated systemd 
> service contains a dependency on the 
> $name-network.serviceNetwork=guacamole-net.network# What image to 
> useImage=docker.io/guacamole/guacd:1.5.5# Environment variables for 
> posgresEnvironmentFile=/home/%u/containers/guacamole/guacamole-guacd-environment#
>  since we run a rootless container we have to make sure our current user id# 
> will be correctly mapped to the userid of the user guacd (1000) in the 
> container# want to keep the current user idUserNS=keep-id:uid=1000,gid=1000# 
> What to execute. If not defined it uses# the default from the 
> image#Exec=sleep 
> 60##############################################################
>
> Make sure you have the relevant local folders and recognize the lower and
> upper-case “z/Z” which makes SELinux happy and allows “z”
> to share the recording path between multiple containers (Guacamole
> Webfrontend needs it too to let you show recordings!)
> Again reload systemd unit files and start the container
>
> # as user podrunner
> systemctl --user daemon-reload
> systemctl --user start guacamole-guacd
>
> ! No ports have been exposed but tcp/4822 is available inside the
> Guacamole network !
> Guacamole Container (Web Frontend)
>
> Environment file
>
> # environment for guacamole-guacamole to connect to PostgreSQL# make sure 
> POSTGRES_* variable values match your postgres 
> setup!POSTGRESQL_USER=guacamolePOSTGRESQL_PASSWORD=<your strong 
> password>POSTGRESQL_DATABASE=guacamolePOSTGRESQL_HOSTNAME=guacamole-pgdb# 
> environment to find GUACD container and 
> recordingsGUACD_HOSTNAME=guacamole-guacdGUACD_PORT=4822WEBAPP_CONTEXT=ROOTRECORDING_SEARCH_PATH=/drives_rec#
>  Generic Guacamole 
> debug#LOGBACK_LEVEL=error#LOGBACK_LEVEL=warn#LOGBACK_LEVEL=debug#LOGBACK_LEVEL=trace#LOGBACK_LEVEL=infoLOGBACK_LEVEL=info
>
> Quadlet
>
> # 
> ~/.config/containers/systemd/guacamole-guacamole.container###############################################################
>  systemd specific 
> section##############################################################
> [Unit]Description=guacamole-guacamole# Service 
> DependenciesAfter=guacamole-guacdAfter=guacamole-pgdb
> [Service]# Restart service if it failsRestart=always# Extend Timeout to allow 
> time to pull the imageTimeoutStartSec=900
> [Install]# Start by default on 
> bootWantedBy=default.target#############################################################################################################################
>  podman specific 
> section##############################################################
> [Container]# override default name of 
> containerContainerName=guacamole-guacamole# Volumes for guacd# These are the 
> volumes for the users file transfer folder(s) (drives)# and the users session 
> recordings 
> (recordings)Volume=/home/%u/containers/guacamole/drives_rec:/drives_rec:rw,z# 
> create or join a network# if the name of the network ends with .network, a 
> Podman network called systemd-$name# is used, and the generated systemd 
> service contains a dependency on the 
> $name-network.serviceNetwork=guacamole-net.network# Published 
> PortsPublishPort=0.0.0.0:8081:8080# when using nginx in front it might be 
> necessary to activate# the next line and comment out the line above!# 
> PublishPort=<real IP of server>:8081:8080# What image to use (must match with 
> guacamole-guacd.container unit 
> file)Image=docker.io/guacamole/guacamole:1.5.5# Environment variables for 
> posgresEnvironmentFile=/home/%u/containers/guacamole/guacamole-guacamole-environment#
>  since we run a rootless container we# want to keep the current user 
> idUserNS=keep-id:uid=1001,gid=1001# What to execute. If not defined it uses# 
> the default from the image#Exec=sleep 60# Enable 
> Debugging#GlobalArgs=--log-level=debug##############################################################
>
> Again reload systemd unit files and start the container
>
> # as user podrunner
> systemctl --user daemon-reload
> systemctl --user start guacamole-guacamole
>
> This container exposes one port to the web-frontend 0.0.0.0:8081:8080.
> You can put any reverse proxy in front of it. All the internal
> connectivity only happens inside the podman network bridge!
> I am currently running this setup in production using SAML authentication
> in front (EntraID). No problems so far.
> podman ps -a
>
> podman ps -a
> CONTAINER ID  IMAGE                                    COMMAND               
> CREATED      STATUS                PORTS                     NAMES
> dda23745edae  docker.io/guacamole/guacd:1.5.5          /bin/sh -c /opt/g...  
> 2 hours ago  Up 2 hours (healthy)                            guacamole-guacd
> 0b781a0eb30e  docker.io/guacamole/guacamole:1.5.5      /opt/guacamole/bi...  
> 2 hours ago  Up 2 hours            127.0.0.1:8081->8080/tcp  
> guacamole-guacamole
> 3caca1d8d89b  docker.io/library/postgres:17.0          postgres              
> 2 hours ago  Up 2 hours                                      guacamole-pgdb
>
> I hope I could help you and sorry for the very long mail.
> Regards
> Peter
> &#8203;
>

Reply via email to