|
1 | 1 | #!/usr/bin/env bash |
2 | 2 | set -e |
3 | 3 |
|
4 | | -# Find the GID of the socket |
5 | | -SOCKET_GID=$(stat -c '%g' /var/run/docker.sock) |
6 | | - |
7 | | -# Find an existing group with the same GID |
8 | | -# This is needed eg. for alpine which already has GID 999 (ping) |
9 | | -# If this breaks some things, we might need to implement a solution based on socat |
10 | | -EXISTING_GROUP=$(getent group $SOCKET_GID | cut -d: -f1) |
11 | | -if [ -n "$EXISTING_GROUP" ]; then |
12 | | - # Delete this group |
13 | | - sudo groupdel $EXISTING_GROUP |
14 | | -fi |
| 4 | +# Wrapper function to only use sudo if not already root |
| 5 | +sudoIf() { |
| 6 | + if [ "$(id -u)" -ne 0 ]; then |
| 7 | + sudo "$@" |
| 8 | + else |
| 9 | + "$@" |
| 10 | + fi |
| 11 | +} |
| 12 | + |
| 13 | +# Source socket (socket on the host) |
| 14 | +SOURCE_SOCKET="${SOURCE_SOCKET:-"/var/run/docker-host.sock"}" |
| 15 | +# Target socket (socket in the container) |
| 16 | +TARGET_SOCKET="${TARGET_SOCKET:-"/var/run/docker.sock"}" |
15 | 17 |
|
16 | 18 | # Determine the correct user |
17 | 19 | USERNAME="${USERNAME:-"${_REMOTE_USER:-"auto"}"}" |
18 | 20 | if [ "${USERNAME}" = "auto" ]; then |
19 | 21 | USERNAME=$(awk -v val=1000 -F ":" '$3==val{print $1}' /etc/passwd) |
20 | 22 | fi |
21 | 23 |
|
22 | | -# Create a matching docker group in the container and add the current user to it |
23 | | -sudo groupadd -g $SOCKET_GID docker |
24 | | -sudo usermod -a -G docker $USERNAME |
| 24 | +# Check if the docker group exists |
| 25 | +if ! getent group docker > /dev/null 2>&1; then |
| 26 | + # Create the docker group |
| 27 | + echo "Adding missing docker group" |
| 28 | + sudoIf groupadd --system docker |
| 29 | +fi |
| 30 | + |
| 31 | +# Add the user to the docker group |
| 32 | +sudoIf usermod -a -G docker $USERNAME |
| 33 | + |
| 34 | +# By default, make the source and target sockets the same |
| 35 | +if [ "${SOURCE_SOCKET}" != "${TARGET_SOCKET}" ]; then |
| 36 | + sudoIf touch "${SOURCE_SOCKET}" |
| 37 | + sudoIf ln -s "${SOURCE_SOCKET}" "${TARGET_SOCKET}" |
| 38 | +fi |
| 39 | + |
| 40 | +# Get the id of the docker group |
| 41 | +DOCKER_GID=$(getent group docker | cut -d: -f3) |
| 42 | + |
| 43 | +# Find the GID of the source socket |
| 44 | +SOCKET_GID=$(stat -c '%g' ${SOURCE_SOCKET}) |
| 45 | + |
| 46 | +# If the group ids don't match, we need to adjust |
| 47 | +if [ "$DOCKER_GID" = "$SOCKET_GID" ]; then |
| 48 | + echo "Docker group GID matches socket GID ($DOCKER_GID), no changes needed." |
| 49 | +else |
| 50 | + # Find an existing group with the same GID as the source socket |
| 51 | + EXISTING_GROUP=$(getent group $SOCKET_GID | cut -d: -f1) |
| 52 | + # If no group is found, just adjust the docker group to match the socket GID |
| 53 | + if [ -z "$EXISTING_GROUP" ]; then |
| 54 | + echo "Adjusting docker group GID ($DOCKER_GID) to match socket GID ($SOCKET_GID)." |
| 55 | + sudoIf groupmod -g $SOCKET_GID docker |
| 56 | + else |
| 57 | + # Use socat |
| 58 | + echo "Using socat to bridge socket from GID $SOCKET_GID to docker GID $DOCKER_GID." |
| 59 | + sudoIf rm -rf ${TARGET_SOCKET} |
| 60 | + # Check if socat is installed |
| 61 | + if command -v socat > /dev/null 2>&1; then |
| 62 | + echo "socat is already installed." |
| 63 | + else |
| 64 | + echo "socat is not installed. Installing socat." |
| 65 | + if command -v apt-get > /dev/null 2>&1; then |
| 66 | + # Apt-based |
| 67 | + sudoIf apt-get update && sudoIf apt-get install -y socat |
| 68 | + elif command -v apk > /dev/null 2>&1; then |
| 69 | + # Apk-based |
| 70 | + sudoIf apk add socat |
| 71 | + else |
| 72 | + echo "Error: socat is required but could not be installed. Please install socat manually." |
| 73 | + exit 1 |
| 74 | + fi |
| 75 | + fi |
| 76 | + # Create the socat bridge |
| 77 | + sudoIf socat UNIX-CONNECT:${SOURCE_SOCKET} UNIX-LISTEN:${TARGET_SOCKET},fork,user=${USERNAME},group=docker,mode=660 |
| 78 | + fi |
| 79 | +fi |
25 | 80 |
|
26 | 81 | # Execute whatever commands were passed in (if any). This allows us |
27 | 82 | # to set this script to ENTRYPOINT while still executing the default CMD. |
|
0 commit comments