@@ -140,26 +140,86 @@ __handle_docker() {
140140 local exitstatus
141141 local var
142142 local regex
143+ local message
144+ local use_podman=0
145+ local use_docker=0
143146
144147 set +e
145148 if [[ " ${__distro} " =~ (debian| ubuntu) ]]; then
146- systemctl status docker > /dev/null
147- exitstatus=$?
148- if [[ ! " ${exitstatus} " -eq 0 ]] && ! docker system info --format ' {{json .SecurityOptions}}' | grep -qi rootless; then
149- echo " The Docker daemon is not running. Please check Docker installation."
150- echo " \" sudo systemctl status docker\" and \" sudo journalctl -fu docker\" will be helpful."
149+ if dpkg-query -W -f=' ${Status}' docker-ce 2> /dev/null | grep -q " ok installed" \
150+ || dpkg-query -W -f=' ${Status}' docker.io 2> /dev/null | grep -q " ok installed" ; then
151+ use_docker=1
152+ fi
153+ if dpkg-query -W -f=' ${Status}' podman 2> /dev/null | grep -q " ok installed" ; then
154+ use_podman=1
155+ fi
156+
157+ # If both are installed:
158+ # If DOCKER_SOCK is set to podman.sock, assume the user prefers podman
159+ # If service podman.socket is running, assume the user prefers podman
160+ # Otherwise, default to Docker
161+ if [[ " ${use_docker} " -eq 1 && " ${use_podman} " -eq 1 ]]; then
162+ echo " Both Docker and Podman are installed"
163+ echo " Guessing at user preference by \" DOCKER_SOCK\" in \" .env\" and status of service podman.socket"
164+ var=DOCKER_SOCK
165+ __get_value_from_env " ${var} " " ${__env_file} " " __value"
166+ if [[ " ${__value} " =~ podman.sock ]] || systemctl --user status podman.socket > /dev/null 2>&1 || systemctl status podman.socket > /dev/null 2>&1 ; then
167+ echo " Preferring Podman"
168+ echo
169+ use_docker=0
170+ else
171+ echo " Preferring Docker"
172+ echo
173+ use_podman=0
174+ fi
175+ fi
176+
177+ if [[ " ${use_docker} " -eq 1 ]]; then
178+ if ${__docker_exe} system info --format ' {{json .SecurityOptions}}' | grep -qi rootless; then
179+ systemctl --user status docker > /dev/null 2>&1
180+ exitstatus=$?
181+ message=" \" systemctl --user status docker\" and \" journalctl --user -fu docker\" will be helpful."
182+ else
183+ systemctl status docker > /dev/null 2>&1
184+ exitstatus=$?
185+ message=" \" systemctl status docker\" and \" sudo journalctl -fu docker\" will be helpful."
186+ fi
187+ if [[ ! " ${exitstatus} " -eq 0 ]]; then
188+ echo " The Docker daemon is not running. Please check Docker installation."
189+ echo " ${message} "
190+ echo " Aborting."
191+ exit 1
192+ fi
193+ elif [[ " ${use_podman} " -eq 1 ]]; then
194+ __docker_exe=podman
195+ __compose_exe=" podman compose"
196+ if systemctl status podman.socket > /dev/null 2>&1 ; then # User has enabled system socket, run podman with sudo.
197+ __docker_sudo=" sudo"
198+ else
199+ systemctl --user status podman.socket > /dev/null 2>&1
200+ exitstatus=$?
201+ if [[ ! " ${exitstatus} " -eq 0 ]]; then
202+ echo " The Podman socket service is not running. Please check Podman installation."
203+ echo " \" systemctl --user status podman.socket\" and \" journalctl --user -fu podman.socket\" will be helpful."
204+ echo " Aborting."
205+ exit 1
206+ fi
207+ fi
208+ else
209+ echo " Neither docker-ce, docker.io nor podman appear to be installed."
210+ echo " One of those is required to run ${__project_name} ."
151211 echo " Aborting."
152212 exit 1
153213 fi
154214 fi
155215 set -e
156216
157- __docker_version=$( docker --version | awk ' { gsub(/,/, "", $3); print $3 }' )
217+ __docker_version=$( ${__docker_exe} --version | awk ' { gsub(/,/, "", $3); print $3 }' )
158218 __docker_major_version=$( echo " ${__docker_version} " | awk ' { split($1, version, "."); print version[1]; }' )
159219 __docker_minor_version=$( echo " ${__docker_version} " | awk ' { split($1, version, "."); print version[2]; }' )
160220 __docker_patch_version=$( echo " ${__docker_version} " | awk ' { split($1, version, "."); print version[3]; }' )
161221
162- if [[ " ${__docker_major_version} " -lt 23 ]]; then
222+ if [[ " ${use_docker} " -eq 1 && " ${ __docker_major_version}" -lt 23 ]]; then
163223 # Debian 11 and Debian 12 have docker.io 20.10. From Debian 13, it's >= 26
164224 # Ubuntu has docker.io>= 27 from 22.04
165225 # The code to detect old docker.io can be removed when Debian 12 goes EOL in 2028
@@ -174,27 +234,40 @@ __handle_docker() {
174234 __oldish_docker=1
175235 fi
176236
177- if ! docker images > /dev/null 2>&1 ; then
237+ if ! ${__docker_exe} images > /dev/null 2>&1 ; then
178238 if [[ " ${__cannot_sudo} " -eq 1 ]]; then
179239 echo " Cannot call Docker and cannot use sudo. Please make your user part of the docker group"
180240 exit 1
181241 fi
182242 echo " Will use sudo to access Docker"
183243 __docker_sudo=" sudo"
184244 fi
245+
185246 if [[ -f " ${__env_file} " && " ${__distro} " =~ (debian| ubuntu) ]]; then
186- DOCKER_ROOT=$( __dodocker system info --format ' {{.DockerRootDir}}' )
247+ if [[ " ${__docker_exe} " = " podman" ]]; then
248+ DOCKER_ROOT=$( __dodocker system info --format ' {{.Store.GraphRoot}}' )
249+ else
250+ DOCKER_ROOT=$( __dodocker system info --format ' {{.DockerRootDir}}' )
251+ fi
187252 var=DOCKER_ROOT
188253 __get_value_from_env " ${var} " " ${__env_file} " " __value"
189254 if [[ " ${DOCKER_ROOT} " != " ${__value} " ]]; then
190255 __update_value_in_env " ${var} " " ${! var} " " ${__env_file} "
191256 fi
192257
193258 # on macOS, user would set this manually to Colima or Docker Desktop value
194- if __dodocker system info --format ' {{json .SecurityOptions}}' | grep -qi rootless; then
195- DOCKER_SOCK=/run/user/$( id -u) /docker.sock
259+ if [[ " ${__docker_exe} " = " podman" ]]; then
260+ if [[ " $( __dodocker system info --format ' {{.Host.Security.Rootless}}' ) " = " true" ]]; then
261+ DOCKER_SOCK=/run/user/$( id -u) /podman/podman.sock
262+ else
263+ DOCKER_SOCK=/run/podman/podman.sock
264+ fi
196265 else
197- DOCKER_SOCK=/var/run/docker.sock
266+ if __dodocker system info --format ' {{.SecurityOptions}}' | grep -qi rootless; then
267+ DOCKER_SOCK=/run/user/$( id -u) /docker.sock
268+ else
269+ DOCKER_SOCK=/var/run/docker.sock
270+ fi
198271 fi
199272 var=DOCKER_SOCK
200273 __get_value_from_env " ${var} " " ${__env_file} " " __value"
@@ -538,8 +611,8 @@ __check_compose_version() {
538611# Compose V1 is in Ubuntu 22.04 and 24.04. The Compose version check can be removed when Ubuntu 24.04 goes EOL in 2029.
539612
540613# Check for Compose V2+ (docker compose) vs Compose V1 (docker-compose)
541- if docker compose version > /dev/null 2>&1 ; then
542- __compose_version=$( ${__docker_sudo} docker compose version | sed -n -E -e " s/.*version [v]?([0-9.-]*).*/\1/ip" )
614+ if ${__docker_sudo} ${__docker_exe} compose version > /dev/null 2>&1 ; then
615+ __compose_version=$( ${__docker_sudo} ${__docker_exe} compose version | sed -n -E -e " s/.*version [v]?([0-9.-]*).*/\1/ip" )
543616 __compose_major=${__compose_version%% .* }
544617 __compose_minor=${__compose_version#* .}
545618 __compose_minor=${__compose_minor%% .* }
@@ -548,12 +621,16 @@ __check_compose_version() {
548621 elif [[ " ${__compose_major} " -eq 2 && " ${__compose_minor} " -lt 18 ]]; then
549622 __old_compose=1
550623 fi
551- else
624+ elif ${__docker_sudo} docker-compose --version > /dev/null 2>&1 ; then
552625 __old_compose=1
553626 __compose_version=$( ${__docker_sudo} docker-compose --version | sed -n -E -e " s/.*version [v]?([0-9.-]*).*/\1/ip" )
554627 __compose_major=${__compose_version%% .* }
555628 __compose_minor=${__compose_version#* .}
556629 __compose_minor=${__compose_minor%% .* }
630+ else
631+ echo " Unable to find ${__docker_exe} compose. Please be sure it's installed"
632+ echo " Aborting"
633+ exit 1
557634 fi
558635 if [[ " ${__compose_major} " -gt 1 ]]; then
559636 return
@@ -826,7 +903,11 @@ __optimize_host() {
826903 local memtotal
827904
828905 echo
829- docker_root=$( __dodocker system info --format ' {{.DockerRootDir}}' )
906+ if dpkg-query -W -f=' ${Status}' podman 2> /dev/null | grep -q " ok installed" ; then
907+ docker_root=$( __dodocker system info --format ' {{.Store.GraphRoot}}' )
908+ else
909+ docker_root=$( __dodocker system info --format ' {{.DockerRootDir}}' )
910+ fi
830911 if command -v findmnt > /dev/null; then
831912 docker_mount=$( findmnt -T " ${docker_root} " -o TARGET -n)
832913 docker_mount_opts=$( findmnt -T " ${docker_root} " -o OPTIONS -n 2> /dev/null)
@@ -917,6 +998,11 @@ __install_docker() {
917998 exit 70
918999 fi
9191000
1001+ if dpkg-query -W -f=' ${Status}' podman 2> /dev/null | grep -q " ok installed" ; then
1002+ echo " Found podman. Will not install Docker, as it would conflict."
1003+ return
1004+ fi
1005+
9201006 if [[ -z " $( command -v docker) " ]]; then
9211007 ${__auto_sudo} install -m 0755 -d /etc/apt/keyrings
9221008 ${__auto_sudo} curl -fsSL https://download.docker.com/linux/${repo} /gpg -o /etc/apt/keyrings/docker.asc
@@ -1032,8 +1118,12 @@ __get_docker_free_space() {
10321118 if [[ " $OSTYPE " = " darwin" * ]]; then # macOS doesn't expose docker root dir to the OS
10331119 __free_space=$( __dodocker run --rm -v macos-space-check:/dummy busybox df -P /dummy | awk ' /[0-9]%/{print $(NF-2)}' )
10341120 else
1035- __docker_dir=$( __dodocker system info --format ' {{.DockerRootDir}}' )
1036- __free_space=$( df -P " ${__docker_dir} " | awk ' /[0-9]%/{print $(NF-2)}' )
1121+ if [[ " ${__docker_exe} " = " podman" ]]; then
1122+ __docker_dir=$( __dodocker system info --format ' {{.Store.GraphRoot}}' )
1123+ else
1124+ __docker_dir=$( __dodocker system info --format ' {{.DockerRootDir}}' )
1125+ fi
1126+ __free_space=$( ${__docker_sudo} df -P " ${__docker_dir} " | awk ' /[0-9]%/{print $(NF-2)}' ) # Allow for rootful podman
10371127 fi
10381128
10391129 regex=' ^[0-9]+$'
@@ -1042,7 +1132,7 @@ __get_docker_free_space() {
10421132 if [[ " $OSTYPE " = " darwin" * ]]; then
10431133 echo " df reports $( __dodocker run --rm -v macos-space-check:/dummy busybox df -P /dummy) and __free_space is ${__free_space} "
10441134 else
1045- echo " df reports $( df -P " ${__docker_dir} " ) and __free_space is ${__free_space} "
1135+ echo " df reports $( ${__docker_sudo} df -P " ${__docker_dir} " ) and __free_space is ${__free_space} " # Allow for rootful podman
10461136 fi
10471137 exit 70
10481138 fi
@@ -1055,7 +1145,7 @@ __display_docker_dir() {
10551145 __dodocker run --rm -v macos-space-check:/dummy busybox df -h /dummy
10561146 else
10571147 echo " Here's total and used space on ${__docker_dir} "
1058- df -h " ${__docker_dir} "
1148+ ${__docker_sudo} df -h " ${__docker_dir} " # Allow for rootful podman
10591149 fi
10601150}
10611151
@@ -4810,8 +4900,8 @@ __query_web3signer() {
48104900
48114901__query_grafana () {
48124902 if whiptail --title " Grafana" --yesno " Do you want to use Grafana dashboards?" 10 65; then
4813- if [[ " $OSTYPE " = " darwin" * ]] || __dodocker system info --format ' {{json .SecurityOptions}}' | grep -qi rootless; then
4814- # macOS doesn't do well with / bind mount - leave node-exporter and cadvisor off by default
4903+ if [[ " $OSTYPE " = " darwin" * ]] || { [[ " ${__docker_exe} " = " podman " ]] && ! systemctl status podman.socket > /dev/null 2>&1 ; } || __dodocker system info --format ' {{json .SecurityOptions}}' 2> /dev/null | grep -qi rootless; then
4904+ # macOS doesn't do well with / bind mount - leave node-exporter and cadvisor off by default. Also detect rootless Docker/Podman
48154905 CORE_FILES+=" :grafana-rootless.yml:grafana-shared.yml"
48164906 else
48174907 CORE_FILES+=" :grafana.yml:grafana-shared.yml"
@@ -6254,7 +6344,7 @@ __update_help() {
62546344 echo " Updates ${__project_name} itself, as required the contents of \" .env\" , and the clients."
62556345 echo
62566346 echo " A combination of \" git pull\" for ${__project_name} , some bash scripting to bring new variables from \" default.env\" ,"
6257- echo " and \" docker compose pull\" as well as \" docker compose build\" for the clients."
6347+ echo " and \" ${__compose_exe} pull\" as well as \" ${__compose_exe} build\" for the clients."
62586348 echo
62596349 echo " If warranted, will also offer resync when clients require it, or upgrade of PostgreSQL version."
62606350 echo
0 commit comments