From 7035de24c49765461de0d61e8f737a19a7c5d3a3 Mon Sep 17 00:00:00 2001 From: Milk Date: Sat, 28 Jun 2025 17:29:34 +0200 Subject: [PATCH 1/7] Disable poetry package mode --- pyproject.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/pyproject.toml b/pyproject.toml index d7d4ee7..9b7ba66 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -3,6 +3,7 @@ name = "docker-socket-proxy" version = "0.0.0" description = "" authors = ["Tecnativa"] +package-mode = false [tool.poetry.dependencies] python = "^3.8" From 3622fe83b770b2d4a922332bbf58f2aed1859e5a Mon Sep 17 00:00:00 2001 From: Milk Date: Sat, 28 Jun 2025 17:41:20 +0200 Subject: [PATCH 2/7] Upgrade HAProxy image tag - upgraded base image tag from haproxy:2.2-alpine to haproxy:lts-alpine - resolved permission issues cause by user in base image changing from root to haproxy - updated tests - updated documentation --- Dockerfile | 4 ++-- README.md | 11 +++++++---- docker-entrypoint.sh | 11 +++++------ haproxy.cfg | 4 ++-- tests/conftest.py | 3 +++ 5 files changed, 19 insertions(+), 14 deletions(-) diff --git a/Dockerfile b/Dockerfile index 6e8ec04..c68d4d6 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM haproxy:2.2-alpine +FROM haproxy:lts-alpine EXPOSE 2375 ENV ALLOW_RESTARTS=0 \ @@ -32,4 +32,4 @@ ENV ALLOW_RESTARTS=0 \ VERSION=1 \ VOLUMES=0 COPY docker-entrypoint.sh /usr/local/bin/ -COPY haproxy.cfg /usr/local/etc/haproxy/haproxy.cfg.template +COPY haproxy.cfg /usr/local/etc/haproxy/haproxy.cfg \ No newline at end of file diff --git a/README.md b/README.md index a9de927..ce71753 100644 --- a/README.md +++ b/README.md @@ -37,17 +37,20 @@ never happen. ## Usage -1. Run the API proxy (`--privileged` flag is required here because it connects with the - docker socket, which is a privileged connection in some SELinux/AppArmor contexts - and would get locked otherwise): +1. Run the API proxy: $ docker container run \ - -d --privileged \ + -d \ + --group-add "$(getent group docker | cut -d: -f3)" \ --name dockerproxy \ -v /var/run/docker.sock:/var/run/docker.sock \ -p 127.0.0.1:2375:2375 \ tecnativa/docker-socket-proxy + The `--group-add` adds the container's user (`haproxy`) to the `docker` group, allowing access to the Docker socket. This assumes that the `docker` group exists and has access to the Docker socket. + + An additional `--privileged` flag is required in some SELinux/AppArmor contexts, because the Docker socket is considered a privileged resource and might otherwise be blocked. + 2. Connect your local docker client to that socket: $ export DOCKER_HOST=tcp://localhost:2375 diff --git a/docker-entrypoint.sh b/docker-entrypoint.sh index c328d3a..59f703b 100755 --- a/docker-entrypoint.sh +++ b/docker-entrypoint.sh @@ -4,19 +4,18 @@ set -e # Normalize the input for DISABLE_IPV6 to lowercase DISABLE_IPV6_LOWER=$(echo "$DISABLE_IPV6" | tr '[:upper:]' '[:lower:]') -# Check for different representations of 'true' and set BIND_CONFIG +# Check for different representations of 'true' and set BIND_PORT and BIND_OPTIONS accordingly case "$DISABLE_IPV6_LOWER" in 1|true|yes) - BIND_CONFIG=":2375" + export BIND_PORT=':2375' + export BIND_OPTIONS='' ;; *) - BIND_CONFIG="[::]:2375 v4v6" + export BIND_PORT=':::2375' + export BIND_OPTIONS='v4v6' ;; esac -# Process the HAProxy configuration template using sed -sed "s/\${BIND_CONFIG}/$BIND_CONFIG/g" /usr/local/etc/haproxy/haproxy.cfg.template > /usr/local/etc/haproxy/haproxy.cfg - # first arg is `-f` or `--some-option` if [ "${1#-}" != "$1" ]; then set -- haproxy "$@" diff --git a/haproxy.cfg b/haproxy.cfg index 43e3526..352d6e8 100644 --- a/haproxy.cfg +++ b/haproxy.cfg @@ -1,7 +1,7 @@ global log stdout format raw daemon "${LOG_LEVEL}" - pidfile /run/haproxy.pid + pidfile /tmp/haproxy.pid maxconn 4000 # Turn on stats unix socket @@ -44,7 +44,7 @@ backend docker-events timeout server 0 frontend dockerfrontend - bind ${BIND_CONFIG} + bind "$BIND_PORT" "$BIND_OPTIONS" http-request deny unless METH_GET || { env(POST) -m bool } http-request allow if { path,url_dec -m reg -i ^(/v[\d\.]+)?/containers/[a-zA-Z0-9_.-]+/((stop)|(restart)|(kill)) } { env(ALLOW_RESTARTS) -m bool } http-request allow if { path,url_dec -m reg -i ^(/v[\d\.]+)?/containers/[a-zA-Z0-9_.-]+/start } { env(ALLOW_START) -m bool } diff --git a/tests/conftest.py b/tests/conftest.py index 4324a54..e3c1d0a 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,6 +1,7 @@ import json import logging import time +import grp from contextlib import contextmanager from pathlib import Path @@ -56,6 +57,7 @@ def proxy_factory(image): @contextmanager def _proxy(**env_vars): container_id = None + docker_gid = grp.getgrnam("docker").gr_gid env_list = [f"--env={key}={value}" for key, value in env_vars.items()] _logger.info(f"Starting {image} container with: {env_list}") try: @@ -66,6 +68,7 @@ def proxy_factory(image): "--privileged", "--publish=2375", "--volume=/var/run/docker.sock:/var/run/docker.sock", + f"--group-add={docker_gid}", *env_list, image, ).strip() From b6cac7b4fd70baf749a32d80ab76e987ef6d6241 Mon Sep 17 00:00:00 2001 From: Niklas Teichmann Date: Mon, 30 Jun 2025 11:10:04 +0200 Subject: [PATCH 3/7] Upgrade job image to ubuntu-latest --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d5867b3..e8ab7cb 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -29,7 +29,7 @@ env: jobs: build-test: - runs-on: ubuntu-20.04 + runs-on: ubuntu-latest strategy: matrix: python: @@ -61,7 +61,7 @@ jobs: # Run tests - run: poetry run pytest --prebuild build-push: - runs-on: ubuntu-20.04 + runs-on: ubuntu-latest services: registry: image: registry:2 From ebca21ec95a80b45772b91075a283555cbab6c48 Mon Sep 17 00:00:00 2001 From: Niklas Teichmann Date: Mon, 30 Jun 2025 11:12:19 +0200 Subject: [PATCH 4/7] Upgrade version of actions/cache to v4 --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e8ab7cb..43132b2 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -47,7 +47,7 @@ jobs: echo "CACHE=${{ secrets.CACHE_DATE }} ${{ runner.os }} $(python -VV | sha256sum | cut -d' ' -f1) ${{ hashFiles('pyproject.toml') }} ${{ hashFiles('poetry.lock') }}" >> $GITHUB_ENV - - uses: actions/cache@v2 + - uses: actions/cache@v4 with: path: | .cache.~ @@ -74,7 +74,7 @@ jobs: steps: # Set up Docker Environment - uses: actions/checkout@v2 - - uses: actions/cache@v2 + - uses: actions/cache@v4 with: path: | /tmp/.buildx-cache From c6e73c04e2444a365e79de32b74cd3357ade7dd3 Mon Sep 17 00:00:00 2001 From: Niklas Teichmann Date: Mon, 30 Jun 2025 13:47:25 +0200 Subject: [PATCH 5/7] Pinned job image version to ubuntu-24.04 --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 43132b2..9eb7b39 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -29,7 +29,7 @@ env: jobs: build-test: - runs-on: ubuntu-latest + runs-on: ubuntu-24.0.4 strategy: matrix: python: @@ -61,7 +61,7 @@ jobs: # Run tests - run: poetry run pytest --prebuild build-push: - runs-on: ubuntu-latest + runs-on: ubuntu-24.0.4 services: registry: image: registry:2 From a1f3a9e38f2fa48557a55f7994ea0da64e53f054 Mon Sep 17 00:00:00 2001 From: Niklas Teichmann Date: Wed, 2 Jul 2025 13:22:49 +0200 Subject: [PATCH 6/7] Refactored docker-entrypoint.sh to add docker group - moved most of docker-entrypoint.sh into start-haproxy.sh - made container run as root initially, assign group of docker socket to haproxy user and execute start-haproxy.sh as haproxy - passthrough positional parameters to start-haproxy - updated documentation --- Dockerfile | 4 +++- README.md | 3 --- docker-entrypoint.sh | 33 +++++---------------------------- start-haproxy.sh | 32 ++++++++++++++++++++++++++++++++ 4 files changed, 40 insertions(+), 32 deletions(-) create mode 100755 start-haproxy.sh diff --git a/Dockerfile b/Dockerfile index c68d4d6..fd8ed69 100644 --- a/Dockerfile +++ b/Dockerfile @@ -32,4 +32,6 @@ ENV ALLOW_RESTARTS=0 \ VERSION=1 \ VOLUMES=0 COPY docker-entrypoint.sh /usr/local/bin/ -COPY haproxy.cfg /usr/local/etc/haproxy/haproxy.cfg \ No newline at end of file +COPY haproxy.cfg /usr/local/etc/haproxy/haproxy.cfg +COPY start-haproxy.sh /usr/local/bin/ +USER root \ No newline at end of file diff --git a/README.md b/README.md index ce71753..63f83a5 100644 --- a/README.md +++ b/README.md @@ -41,14 +41,11 @@ never happen. $ docker container run \ -d \ - --group-add "$(getent group docker | cut -d: -f3)" \ --name dockerproxy \ -v /var/run/docker.sock:/var/run/docker.sock \ -p 127.0.0.1:2375:2375 \ tecnativa/docker-socket-proxy - The `--group-add` adds the container's user (`haproxy`) to the `docker` group, allowing access to the Docker socket. This assumes that the `docker` group exists and has access to the Docker socket. - An additional `--privileged` flag is required in some SELinux/AppArmor contexts, because the Docker socket is considered a privileged resource and might otherwise be blocked. 2. Connect your local docker client to that socket: diff --git a/docker-entrypoint.sh b/docker-entrypoint.sh index 59f703b..5832f6b 100755 --- a/docker-entrypoint.sh +++ b/docker-entrypoint.sh @@ -1,32 +1,9 @@ #!/bin/sh set -e -# Normalize the input for DISABLE_IPV6 to lowercase -DISABLE_IPV6_LOWER=$(echo "$DISABLE_IPV6" | tr '[:upper:]' '[:lower:]') +# add haproxy user to group of docker socket +DOCKER_GROUP=$(stat -c %G "$SOCKET_PATH") +adduser haproxy "$DOCKER_GROUP" -# Check for different representations of 'true' and set BIND_PORT and BIND_OPTIONS accordingly -case "$DISABLE_IPV6_LOWER" in - 1|true|yes) - export BIND_PORT=':2375' - export BIND_OPTIONS='' - ;; - *) - export BIND_PORT=':::2375' - export BIND_OPTIONS='v4v6' - ;; -esac - -# first arg is `-f` or `--some-option` -if [ "${1#-}" != "$1" ]; then - set -- haproxy "$@" -fi - -if [ "$1" = 'haproxy' ]; then - shift # "haproxy" - # if the user wants "haproxy", let's add a couple useful flags - # -W -- "master-worker mode" (similar to the old "haproxy-systemd-wrapper"; allows for reload via "SIGUSR2") - # -db -- disables background mode - set -- haproxy -W -db "$@" -fi - -exec "$@" +# continue as haproxy user, preserving entrypoint parameters +su -s /bin/sh -c 'start-haproxy.sh "$@"' haproxy -- "$@" \ No newline at end of file diff --git a/start-haproxy.sh b/start-haproxy.sh new file mode 100755 index 0000000..cfbe8c6 --- /dev/null +++ b/start-haproxy.sh @@ -0,0 +1,32 @@ +#!/bin/sh +set -e + +# Normalize the input for DISABLE_IPV6 to lowercase +DISABLE_IPV6_LOWER=$(echo "$DISABLE_IPV6" | tr '[:upper:]' '[:lower:]') + +# Check for different representations of 'true' and set BIND_PORT and BIND_OPTIONS accordingly +case "$DISABLE_IPV6_LOWER" in + 1|true|yes) + export BIND_PORT=':2375' + export BIND_OPTIONS='' + ;; + *) + export BIND_PORT=':::2375' + export BIND_OPTIONS='v4v6' + ;; +esac + +# first arg is `-f` or `--some-option` +if [ "${1#-}" != "$1" ]; then + set -- haproxy "$@" +fi + +if [ "$1" = 'haproxy' ]; then + shift # "haproxy" + # if the user wants "haproxy", let's add a couple useful flags + # -W -- "master-worker mode" (similar to the old "haproxy-systemd-wrapper"; allows for reload via "SIGUSR2") + # -db -- disables background mode + set -- haproxy -W -db "$@" +fi + +exec "$@" \ No newline at end of file From 593f1808ce1f0d7f8660c817ff7dfafc81768a63 Mon Sep 17 00:00:00 2001 From: Niklas Teichmann Date: Wed, 2 Jul 2025 13:29:59 +0200 Subject: [PATCH 7/7] Fixed typo in ubuntu image version --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9eb7b39..0fb4701 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -29,7 +29,7 @@ env: jobs: build-test: - runs-on: ubuntu-24.0.4 + runs-on: ubuntu-24.04 strategy: matrix: python: @@ -61,7 +61,7 @@ jobs: # Run tests - run: poetry run pytest --prebuild build-push: - runs-on: ubuntu-24.0.4 + runs-on: ubuntu-24.04 services: registry: image: registry:2