Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 8 additions & 8 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,25 +29,25 @@ env:

jobs:
build-test:
runs-on: ubuntu-20.04
runs-on: ubuntu-24.04
strategy:
matrix:
python:
- 3.8
- 3.12
steps:
# Prepare environment
- uses: actions/checkout@v2
- uses: actions/checkout@v4
# Set up and run tests
- name: Install python
uses: actions/setup-python@v2
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python }}
- name: Generate cache key CACHE
run:
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.~
Expand All @@ -61,7 +61,7 @@ jobs:
# Run tests
- run: poetry run pytest --prebuild
build-push:
runs-on: ubuntu-20.04
runs-on: ubuntu-24.04
services:
registry:
image: registry:2
Expand All @@ -73,8 +73,8 @@ jobs:
PUSH: ${{ toJSON(github.event_name != 'pull_request') }}
steps:
# Set up Docker Environment
- uses: actions/checkout@v2
- uses: actions/cache@v2
- uses: actions/checkout@v4
- uses: actions/cache@v4
with:
path: |
/tmp/.buildx-cache
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/pre-commit.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,6 @@ jobs:
pre-commit:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-python@v2
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
- uses: pre-commit/action@v2.0.0
11 changes: 9 additions & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
FROM haproxy:2.2-alpine
FROM haproxy:3.1-alpine

EXPOSE 2375

ENV ALLOW_RESTARTS=0 \
ALLOW_STOP=0 \
ALLOW_START=0 \
Expand Down Expand Up @@ -31,5 +32,11 @@ ENV ALLOW_RESTARTS=0 \
TASKS=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

# We need to be root to access the docker socket
USER root

CMD ["haproxy", "-f", "/usr/local/etc/haproxy/haproxy.cfg"]
37 changes: 23 additions & 14 deletions docker-entrypoint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -6,28 +6,37 @@ DISABLE_IPV6_LOWER=$(echo "$DISABLE_IPV6" | tr '[:upper:]' '[:lower:]')

# Check for different representations of 'true' and set BIND_CONFIG
case "$DISABLE_IPV6_LOWER" in
1|true|yes)
BIND_CONFIG=":2375"
;;
*)
BIND_CONFIG="[::]:2375 v4v6"
;;
1 | true | yes)
BIND_CONFIG=":2375"
;;
*)
BIND_CONFIG="[::]:2375 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
# Create required directories
mkdir -p /var/lib/haproxy

# Process the HAProxy configuration templates
sed -i "s/\${BIND_CONFIG}/$BIND_CONFIG/g" /usr/local/etc/haproxy/haproxy.cfg
sed -i "s|\${SOCKET_PATH}|$SOCKET_PATH|g" /usr/local/etc/haproxy/haproxy.cfg

# Test socket connectivity
if ! timeout 5 socat -t 1 UNIX-CONNECT:$SOCKET_PATH PIPE 2>/dev/null; then
echo "Warning: Could not connect to Docker socket!"
fi

# first arg is `-f` or `--some-option`
if [ "${1#-}" != "$1" ]; then
set -- haproxy "$@"
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 "$@"
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 "$@"
34 changes: 22 additions & 12 deletions haproxy.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,15 @@ global
maxconn 4000

# Turn on stats unix socket
stats socket /var/run/haproxy.sock mode 600 level admin
server-state-file /var/lib/haproxy/server-state

defaults
mode http
log global
option httplog
option dontlognull
option http-server-close
option http-keep-alive
option redispatch
retries 3
timeout http-request 10s
Expand All @@ -37,16 +38,27 @@ defaults
errorfile 504 /usr/local/etc/haproxy/errors/504.http

backend dockerbackend
server dockersocket $SOCKET_PATH
mode http
option httpchk GET /_ping
server dockersocket unix@${SOCKET_PATH} no-check

backend docker-events
server dockersocket $SOCKET_PATH
timeout server 0
mode http
server dockersocket unix@${SOCKET_PATH} no-check
timeout server 1s

frontend dockerfrontend
bind ${BIND_CONFIG}
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 }

# Essential endpoints first
http-request allow if { path,url_dec -m reg -i ^(/v[\d\.]+)?/_ping } { env(PING) -m bool }
http-request allow if { path,url_dec -m reg -i ^(/v[\d\.]+)?/version } { env(VERSION) -m bool }
http-request allow if { path,url_dec -m reg -i ^(/v[\d\.]+)?/info } { env(INFO) -m bool }

# Method check after essential endpoints
http-request deny unless METH_GET || METH_HEAD

# Container operations
http-request allow if { path,url_dec -m reg -i ^(/v[\d\.]+)?/containers/[a-zA-Z0-9_.-]+/start } { env(ALLOW_START) -m bool }
http-request allow if { path,url_dec -m reg -i ^(/v[\d\.]+)?/containers/[a-zA-Z0-9_.-]+/stop } { env(ALLOW_STOP) -m bool }
http-request allow if { path,url_dec -m reg -i ^(/v[\d\.]+)?/auth } { env(AUTH) -m bool }
Expand All @@ -59,20 +71,18 @@ frontend dockerfrontend
http-request allow if { path,url_dec -m reg -i ^(/v[\d\.]+)?/exec } { env(EXEC) -m bool }
http-request allow if { path,url_dec -m reg -i ^(/v[\d\.]+)?/grpc } { env(GRPC) -m bool }
http-request allow if { path,url_dec -m reg -i ^(/v[\d\.]+)?/images } { env(IMAGES) -m bool }
http-request allow if { path,url_dec -m reg -i ^(/v[\d\.]+)?/info } { env(INFO) -m bool }
http-request allow if { path,url_dec -m reg -i ^(/v[\d\.]+)?/networks } { env(NETWORKS) -m bool }
http-request allow if { path,url_dec -m reg -i ^(/v[\d\.]+)?/nodes } { env(NODES) -m bool }
http-request allow if { path,url_dec -m reg -i ^(/v[\d\.]+)?/_ping } { env(PING) -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\.]+)?/plugins } { env(PLUGINS) -m bool }
http-request allow if { path,url_dec -m reg -i ^(/v[\d\.]+)?/secrets } { env(SECRETS) -m bool }
http-request allow if { path,url_dec -m reg -i ^(/v[\d\.]+)?/services } { env(SERVICES) -m bool }
http-request allow if { path,url_dec -m reg -i ^(/v[\d\.]+)?/session } { env(SESSION) -m bool }
http-request allow if { path,url_dec -m reg -i ^(/v[\d\.]+)?/swarm } { env(SWARM) -m bool }
http-request allow if { path,url_dec -m reg -i ^(/v[\d\.]+)?/system } { env(SYSTEM) -m bool }
http-request allow if { path,url_dec -m reg -i ^(/v[\d\.]+)?/tasks } { env(TASKS) -m bool }
http-request allow if { path,url_dec -m reg -i ^(/v[\d\.]+)?/version } { env(VERSION) -m bool }
http-request allow if { path,url_dec -m reg -i ^(/v[\d\.]+)?/volumes } { env(VOLUMES) -m bool }
http-request deny
default_backend dockerbackend

use_backend docker-events if { path,url_dec -m reg -i ^(/v[\d\.]+)?/events }
default_backend dockerbackend
http-request deny if ! { path -i -m beg /events }
use_backend docker-events if { path -i -m beg /events }
Loading
Loading