diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 289fcb9..1a84174 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -62,6 +62,23 @@ jobs: with: images: ${{ secrets.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }} + - uses: actions/github-script@v6 + id: tags + with: + script: | + tags = "${{ join(steps.meta.outputs.tags, ',') }}" + result = [] + tags.split(",").forEach(function (item) { + short_tag = item.trim().split(":")[1]; + if (short_tag != "latest") { + result.push(short_tag); + } + }) + return result.join(","); + result-encoding: string + - name: Get result + run: echo "${{steps.set-result.outputs.result}}" + # Build and push Docker image with Buildx (don't push on PR) # https://github.com/docker/build-push-action - name: Build and push Docker image @@ -69,6 +86,8 @@ jobs: with: context: . file: Dockerfile + build-args: | + RELEASE_VERSION_ARG="${{ join(steps.tags.outputs.result, ',') }}" platforms: linux/amd64,linux/arm64 push: ${{ github.event_name != 'pull_request' || github.event.inputs.push == 'true' }} tags: ${{ steps.meta.outputs.tags }} diff --git a/Dockerfile b/Dockerfile index ef19a6f..9cb2339 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,9 @@ FROM alpine:3.16 +ARG RELEASE_VERSION_ARG + +ENV RELEASE_VERSION=$RELEASE_VERSION_ARG + WORKDIR /scripts COPY requirements.txt /scripts diff --git a/Makefile b/Makefile index d721ef9..4c3b4e4 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,8 @@ +VERSION := $(shell git rev-parse --short HEAD) + .PHONY: build build: - docker build -t byjg/easy-haproxy -t byjg/easy-haproxy:local . + docker build -t byjg/easy-haproxy --build-arg RELEASE_VERSION_ARG="$(VERSION)" -t byjg/easy-haproxy:local . .PHONY: test test: diff --git a/README.md b/README.md index f239dff..7cbb7c3 100644 --- a/README.md +++ b/README.md @@ -85,6 +85,12 @@ docker run --network easyhaproxy byjg/easyhaproxy docker run --network easyhaproxy myimage ``` +or, if the container is already created you can join it using the command: + +``` +docker network connect easyhaproxy mycontainer +``` + ### EASYHAPROXY_DISCOVER: swarm This method requires a functional Docker Swarm Cluster. The system will search for the labels in all containers on all diff --git a/assets/scripts/banner.txt b/assets/scripts/banner.txt new file mode 100644 index 0000000..f897aab --- /dev/null +++ b/assets/scripts/banner.txt @@ -0,0 +1,5 @@ + _ + ___ __ _ ____ _ ___| |_ __ _ _ __ _ _ _____ ___ _ +/ -_) _` (_-< || |___| ' \/ _` | '_ \ '_/ _ \ \ / || | +\___\__,_/__/\_, | |_||_\__,_| .__/_| \___/_\_\\_, | + |__/ |_| |__/ diff --git a/assets/scripts/certbot.sh b/assets/scripts/certbot.sh index 6d9113d..8678231 100755 --- a/assets/scripts/certbot.sh +++ b/assets/scripts/certbot.sh @@ -1,8 +1,14 @@ #!/usr/bin/env bash +source /scripts/functions.sh + +if [ ! -f /scripts/letsencrypt_hosts.txt ]; then + exit 0 +fi + # Semaphore if [ -f /tmp/certbot-lock ]; then - echo "[CERTBOT_JOB] $(date +"$EASYHAPROXY_DATEFORMAT") Another process is running" + log "notice" "CERTBOT_JOB" "Another process is running" exit 0 fi @@ -26,7 +32,7 @@ for domain in $(cat /scripts/letsencrypt_hosts.txt); do done if [ -n "$REQUEST_CERTS" ]; then - echo "[CERTBOT_JOB] $(date +"$EASYHAPROXY_DATEFORMAT") Requesting certificates for $REQUEST_CERTS" + log "info" "CERTBOT_JOB" "Requesting certificates for $REQUEST_CERTS" certbot certonly \ --standalone \ --preferred-challenges http \ @@ -41,7 +47,7 @@ if [ -n "$REQUEST_CERTS" ]; then fi if [ -n "$RENEW_CERTS" ]; then - echo "[CERTBOT_JOB] $(date +"$EASYHAPROXY_DATEFORMAT") Resquesting renew certificated fort $RENEW_CERTS" + log "info" "CERTBOT_JOB" "Resquesting renew certificated fort $RENEW_CERTS" certbot renew --post-hook "/scripts/certbot_to_haproxy.sh" fi diff --git a/assets/scripts/certbot_to_haproxy.sh b/assets/scripts/certbot_to_haproxy.sh index 7d84250..532a265 100755 --- a/assets/scripts/certbot_to_haproxy.sh +++ b/assets/scripts/certbot_to_haproxy.sh @@ -1,5 +1,7 @@ #!/bin/bash +source /scripts/functions.sh + # Loop through all Let's Encrypt certificates for CERTIFICATE in `find /etc/letsencrypt/live/* -type d`; do CERTIFICATE=`basename $CERTIFICATE` diff --git a/assets/scripts/functions.sh b/assets/scripts/functions.sh new file mode 100644 index 0000000..e90e730 --- /dev/null +++ b/assets/scripts/functions.sh @@ -0,0 +1,9 @@ +#!/bin/bash + +function log() { + # ARGS: + # - loglevel + # - app + # - message + echo [$2] $(date +"$EASYHAPROXY_DATEFORMAT") [$1]: $3 +} diff --git a/assets/scripts/haproxy-reload.sh b/assets/scripts/haproxy-reload.sh index 1d55fe5..20fbad8 100755 --- a/assets/scripts/haproxy-reload.sh +++ b/assets/scripts/haproxy-reload.sh @@ -1,9 +1,16 @@ #!/usr/bin/env bash +source /scripts/functions.sh + cd /scripts RELOAD="true" +if [[ "static|docker|swarm" != *"$EASYHAPROXY_DISCOVER"* ]];then + log "error" "CONF_CHECK" "EASYHAPROXY_DISCOVER should be 'static', 'docker', or 'swarm'. I got '$EASYHAPROXY_DISCOVER' instead." + exit 1 +fi + if [[ "$EASYHAPROXY_DISCOVER" == "static" ]]; then CONTROL_FILE="/etc/haproxy/haproxy.cfg" touch ${CONTROL_FILE} @@ -35,7 +42,7 @@ else RELOAD="false" else python3 swarm.py > /etc/haproxy/haproxy.cfg - echo "[CONF_CHECK] $(date +"$EASYHAPROXY_DATEFORMAT") New configuration found" + log "info" "CONF_CHECK" "New configuration found" fi fi @@ -44,23 +51,23 @@ if cmp -s ${CONTROL_FILE} ${CONTROL_FILE}.old ; then fi if [[ ! -z "$1" ]]; then - echo "[CONF_CHECK] $(date +"$EASYHAPROXY_DATEFORMAT") Initial configuration. Skip certbot." + log "info" "CONF_CHECK" "Initial configuration. Skip certbot." else /scripts/certbot.sh fi # If Certbot reloads successfully will create the file /tmp/force-reload if [ -f /tmp/force-reload ]; then - echo "[CONF_CHECK] $(date +"$EASYHAPROXY_DATEFORMAT") New certificates found..." + log "info" "CONF_CHECK" "New certificates found..." RELOAD="true" rm /tmp/force-reload fi if [[ ! -z "$1" ]]; then - echo "[CONF_CHECK] $(date +"$EASYHAPROXY_DATEFORMAT") Starting haproxy..." + log "info" "CONF_CHECK" "Starting haproxy..." /usr/sbin/haproxy -W -f /etc/haproxy/haproxy.cfg $(ls /etc/haproxy/conf.d/*.cfg 2>/dev/null | xargs -I{} echo -f {}) -p /run/haproxy.pid -S /var/run/haproxy.sock & elif [[ "$RELOAD" == "true" ]]; then - echo "[CONF_CHECK] $(date +"$EASYHAPROXY_DATEFORMAT") Reloading..." + log "info" "CONF_CHECK" "Reloading..." /usr/sbin/haproxy -W -f /etc/haproxy/haproxy.cfg $(ls /etc/haproxy/conf.d/*.cfg 2>/dev/null | xargs -I{} echo -f {}) -p /run/haproxy.pid -x /var/run/haproxy.sock -sf $(cat /run/haproxy.pid) & fi diff --git a/assets/scripts/haproxy.sh b/assets/scripts/haproxy.sh index b830088..92c15e5 100755 --- a/assets/scripts/haproxy.sh +++ b/assets/scripts/haproxy.sh @@ -1,5 +1,7 @@ #!/usr/bin/env bash +source /scripts/functions.sh + /usr/sbin/haproxy -v if [ -z "$EASYHAPROXY_DATEFORMAT" ]; then @@ -10,10 +12,18 @@ if [ -z "$EASYHAPROXY_REFRESH_CONF" ]; then export EASYHAPROXY_REFRESH_CONF=10 fi + +cat banner.txt +echo Release: $RELEASE_VERSION +echo +echo "Environment" +env | sort | grep 'HAPROXY' | xargs -I{} echo " - {} " +echo + /scripts/haproxy-reload.sh initial while true; do sleep $EASYHAPROXY_REFRESH_CONF - echo "[CONF_CHECK] $(date +"$EASYHAPROXY_DATEFORMAT") - Heartbeat." + log "info" "CONF_CHECK" "Heartbeat." /scripts/haproxy-reload.sh done diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..2af38f1 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,32 @@ +version: "3" + +services: + easyhaproxy: + image: byjg/easy-haproxy:4.1.0 + volumes: + - /var/run/docker.sock:/var/run/docker.sock + - certs_letsencrypt:/certs/letsencrypt + - certs_haproxy:/certs/haproxy + + environment: + EASYHAPROXY_DISCOVER: docker + EASYHAPROXY_LABEL_PREFIX: easyhaproxy + EASYHAPROXY_LETSENCRYPT_EMAIL: changeme@example.org + EASYHAPROXY_SSL_MODE: "default" + HAPROXY_CUSTOMERRORS: "true" + HAPROXY_USERNAME: admin + HAPROXY_PASSWORD: password + HAPROXY_STATS_PORT: 1936 + + ports: + - "80:80/tcp" + - "443:443/tcp" + - "1936:1936/tcp" + +volumes: + certs_letsencrypt: + certs_haproxy: + +networks: + easyhaproxy: + driver: bridge