{"id":22425402,"url":"https://github.com/projektmotor/docker-apache-load-balancer","last_synced_at":"2025-07-21T06:32:25.432Z","repository":{"id":102330592,"uuid":"113621052","full_name":"projektmotor/docker-apache-load-balancer","owner":"projektmotor","description":"Debian based docker image containing apache2 load balancer for use as reverse proxy and/or load balancer.","archived":false,"fork":false,"pushed_at":"2024-05-30T14:08:15.000Z","size":69,"stargazers_count":9,"open_issues_count":3,"forks_count":6,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-04-07T18:46:28.240Z","etag":null,"topics":["apache","docker-image","load-balancer","reverse-proxy"],"latest_commit_sha":null,"homepage":"https://hub.docker.com/r/projektmotor/apache-load-balancer/","language":"Shell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/projektmotor.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2017-12-08T21:58:01.000Z","updated_at":"2024-05-30T14:08:19.000Z","dependencies_parsed_at":"2025-07-21T06:32:03.343Z","dependency_job_id":null,"html_url":"https://github.com/projektmotor/docker-apache-load-balancer","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/projektmotor/docker-apache-load-balancer","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/projektmotor%2Fdocker-apache-load-balancer","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/projektmotor%2Fdocker-apache-load-balancer/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/projektmotor%2Fdocker-apache-load-balancer/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/projektmotor%2Fdocker-apache-load-balancer/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/projektmotor","download_url":"https://codeload.github.com/projektmotor/docker-apache-load-balancer/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/projektmotor%2Fdocker-apache-load-balancer/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":266253614,"owners_count":23900053,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["apache","docker-image","load-balancer","reverse-proxy"],"created_at":"2024-12-05T19:14:04.110Z","updated_at":"2025-07-21T06:32:25.402Z","avatar_url":"https://github.com/projektmotor.png","language":"Shell","funding_links":[],"categories":[],"sub_categories":[],"readme":"# APACHE2 Load Balancer\n\n[![Build Status](https://travis-ci.org/projektmotor/docker-apache-load-balancer.svg?branch=master)](https://travis-ci.org/projektmotor/docker-apache-load-balancer) \n\n## Use Cases\n\n* as reverse proxy to serve multiple (docker-) web apps on a single host\n* as load balancer between multiple worker nodes\n* as a combination of the first two things\n\nWhat else:\n\n* using as reverse-proxy / load balancer in a development env, including local https with local CA\n\n## Table of Content\n\n1. [General Usage](#1-general-usage)\n    * [Self-Signed Certificates with local CA Usage](#self-signed-certificateswwith-local-ca)\n    * [Persistence](#persistence)\n    * [Logging](#logging)\n2. [Load Balancer Mode](#2-load-balancer-mode)\n    * [Load Balancer with Self-Signed Certificate](#load-balancer-with-self-signed-certificate)\n3. [Reverse Proxy Mode](#3-reverse-proxy-mode)\n    * [Reverse Proxy with Self-Signed Certificate](#reverse-proxy-with-self-signed-certificate)\n4. [Build-In Scripts](#4-build-in-scripts)\n    * [Loadbalancer Build-In Scripts](#loadbalancer-build-in-scripts)\n    * [Reverseproxy Build-In Scripts](#reverseproxy-build-in-scripts)\n5. [Examples with docker-compose](#5-examples-with-docker-compose)\n    * [Run with docker-compose as a local dev-server](#run-with-docker-compose-as-a-local-dev-server)\n\n## 1. General Usage\n\n### Self-Signed Certificates with local CA\n\nCertification warnings suck! To change this (for your self-signed certificate), \nyou should be your own local CA. All you need is a root-key (**myCA.key**) \u0026 \nroot-certificate (**myCA.pem**). These two things should be placed on your **docker \nhost and mounted to any docker container which uses self-signed certificates**. \nAdditionally the root-certificate must be added as CA on all devices (browsers) \nwhich execute requests against your ssl-host(s). \n\n* create you private key:\n```bash\n$ openssl genrsa -out myCA.key 2048\n```\n* create your root-certificate\n```bash\n$ openssl req -x509 -new -nodes -key myCA.key -sha256 -days 1825 -out myCA.pem\n```\n\nAt the beginning of the command, the script asks for some certificate informations:\n\n```bash\nCountry Name (2 letter code) [AU]:DE\nState or Province Name (full name) [Some-State]:Saxony\nLocality Name (eg, city) []:Leipzig\nOrganization Name (eg, company) [Internet Widgits Pty Ltd]:ProjektMOTOR GmbH\nOrganizational Unit Name (eg, section) []:\nCommon Name (e.g. server FQDN or YOUR name) []:\nEmail Address []:noreply@projektmotor.de\n```\n\nCongrats, now you are your own CA! :] Stop... you are your own CA, but nobody knows about it! :/\nTo change this, you should add the earlier generated certificate as CA to your browser.\n\n* Chrome:\n * Settings \u003e Manage certificates \u003e Authorities \u003e IMPORT\n * select you certificate file (myCA.pem)\n * select signing targets (e.g. websites)\n * double check the list of authorities if the certificate is imported as new authority\n\n### Persistence\n\n* mount a single path (i.e. vhost path)\n    ```bash\n    $ docker run -it --rm \\\n          -v /path/loadbalancer/conf/:/etc/apache2/conf-loadbalancer \\\n          -v /path/sites-available/:/etc/apache2/sites-available \\\n          --name acme-load-balancer-container \\\n          projektmotor/apache-load-balancer:latest\n    ```\n* mount a whole apache-config path\n    ```bash\n    $ docker run -it --rm \\\n          -v /path/apache2/:/etc/apache2 \\\n          --name acme-load-balancer-container \\\n          projektmotor/apache-load-balancer:latest\n    ```\n\n### Logging\n\nIn general it is a good idea to mount a host-folder to ```/var/log/apache2```. This makes your apache log-files persistent\nand log debugging from the outside of the docker container quite easy. \n\n```bash\n$ docker run -it --rm \\\n      -v .../logs/:/var/log/apache2 \\\n      --name acme-load-balancer-container \\\n      projektmotor/apache-load-balancer:latest\n```\n\n## 2. Load Balancer Mode\n\n* create a local load balancer config file ```.../conf-loadbalancer/loadbalancer.conf```\n    ```bash\n    [acme-app]                            # starts config part (name has no further meaning)\n    cluster=acme-cluster                  # name of load balancer cluster for acme-app\n    uri=acme.de                           # the url your app should be available under\n    ssl=true                              # use SSL for incoming connections\n    ssl_self_signed=false                 # if true: use self signed certificate, if false: use letsencrypt\n    reverse_proxy_address=0.0.0.0         # if behind reverse proxy OR another load balancer, set its ip here (otherwise REMOTE_ADDR \u0026 client ip logging doesn't work)\n    nodes=[web1:443;web2:443;web3:443]    # comma separated list of worker nodes (HOST|IP:PORT)\n    node_ssl=true                         # use ssl-connection for nodes\n    ```\n* run docker image\n    ```bash\n    $ docker run -it --rm \\\n          -v .../conf-loadbalancer/loadbalancer.conf/:/etc/apache2/conf-loadbalancer \\\n          --name acme-load-balancer-container \\\n          projektmotor/apache-load-balancer:latest\n    ```\n* vhost \u0026 proxy config is auto-generated inside the container during startup\n    * **NOTICE**: if you change the ```loadbalancer.conf``` of a running container, you could regenerate the vhost- \u0026 proxy-config by running:\n    ```bash\n    $ apache-reload-cluster-conf.sh\n    ```\n* go to your browser \u0026 type https://acme.de\n\n### Load Balancer with Self-Signed Certificate\n\n* set ```ssl_self_signed=true``` in ```.../conf-loadbalancer/loadbalancer.conf```\n* mount the root-certificate, root-key \u0026 and a folder to persist the certificates\n    ```bash\n    $ docker run -it --rm \\\n          -v .../conf-loadbalancer/loadbalancer.conf/:/etc/apache2/conf-loadbalancer \\\n          -v .../ssl_ca/:/etc/ssl_ca \\\n          -v .../myCA.key:/etc/myCA.key \\\n          -v .../myCA.pem:/etc/myCA.pem \\\n          --name acme-load-balancer-container \\\n          projektmotor/apache-load-balancer:latest\n    ```\n\n## 3. Reverse Proxy Mode\n\n* run docker image\n    ```bash\n    $ docker run -it --rm \\\n          -v .../apache2/:/etc/apache2 \\\n          -v .../letsencrypt/:/etc/letsencrypt \\\n          --name acme-load-balancer-container \\\n          projektmotor/apache-load-balancer:latest\n    ```\n* add new vhost with build-in script: ```apache-init-reverseproxy-vhost.sh```\n    ```bash\n    $ docker exec -it acme-load-balancer-container apache-init-reverseproxy-vhost.sh\n    ```\n* the script asks for all necessary informations and creates the new vhost for you \n\n### Reverse Proxy with Self-Signed Certificate\n\n* mount the root-certificate, root-key \u0026 and a folder to persist the certificates\n    ```bash\n    $ docker run -it --rm \\\n          -v .../apache2/:/etc/apache2 \\\n          -v .../ssl_ca/:/etc/ssl_ca \\\n          -v .../myCA.key:/etc/myCA.key \\\n          -v .../myCA.pem:/etc/myCA.pem \\\n          --name acme-load-balancer-container \\\n          projektmotor/apache-load-balancer:latest\n    ```\n* during execution of the build-in script ```apache-init-reverseproxy-vhost.sh``` type\n    ```\n    $ docker exec -it acme-load-balancer-container apache-init-reverseproxy-vhost.sh\n    ...\n    'Use self-signed certificate for incoming connections - from browser (only used when SSL for incoming connections is enabled; when N is used then certbot certificate is generated; shortcut: e) [y|N]: Y\n    ...\n    ```\n\n## 4. Build-In Scripts\n\n* reload apache config (```apache-reload.sh```)\n    ```bash\n    $ docker exec -it acme-load-balancer-container apache-reload.sh\n  ```\n\n### Loadbalancer Build-In Scripts\n\n* add new VHOST (```apache-init-cluster-vhost```)\n    ```bash\n    $ docker exec -it acme-load-balancer-container apache-init-cluster-vhost.sh HOST-URI CLUSTER-NAME\n    ```\n    * HOST-URI: the url your app should be available under \n    * CLUSTER-NAME: a name of load balancer cluster for your app (free choice, but needed for cluster \u0026 node conf)\n    * **NOTICE**: apache config has to be reloaded\n\n* create new cluster (```apache-init-cluster.sh```)\n    ```bash\n    $ docker exec -it acme-load-balancer-container apache-init-cluster.sh CLUSTER-NAME\n    ```\n    * CLUSTER-NAME: the cluster name of your app (set in your vhost)\n\n* add new worker node to existing cluster (```apache-add-cluster-node.sh```)\n    ```bash\n    $ docker exec -it acme-load-balancer-container apache-add-cluster-node.sh CLUSTER-NAME NODE\n    ```\n    * CLUSTER-NAME: the cluster name of your app (set in your vhost \u0026 cluster config)\n    * NODE: a node config of format URI|IP[:PORT]\n    * USE_SSL: use ssl for node-connection (https)\n    * **NOTICE**: apache config has to be reloaded\n    \n    \n### Reverseproxy Build-In Scripts\n\n* add new VHOST (```apache-init-reverseproxy-vhost```)\n    ```bash\n    $ docker exec -it acme-load-balancer-container apache-init-reverseproxy-vhost.sh\n    ```\n    * this is an interactive and non-interactive command\n        * all required parameters (domain, target ip, target port) will be \n          requested interactively\n        * parameters can also be passed\n          ```bash\n          $ docker exec -it acme-load-balancer-container apache-init-reverseproxy-vhost.sh -d acme.de -i 157.138.29.201 -p 9600 -a n -m Y -s Y -l Y\n          ```\n    * optional: including SSL certificate creation\n    * optional: use maintenance page\n\n## 5. Examples with docker-compose\n\n### Run with docker-compose as a local dev-server\n* create config file ```/var/apps/reverse-proxy/docker-compose.yml``` \n    ```\n    version: \"3\"\n    services:\n    \n      loadbalancer:\n        image: projektmotor/apache-load-balancer\n        ports:\n          - 80:80\n          - 443:443\n        volumes:\n          - /var/apps/reverse-proxy/apache2/:/etc/apache2\n          - /var/apps/reverse-proxy/letsencrypt/:/etc/letsencrypt\n          - /var/apps/reverse-proxy/ssl_ca/:/etc/ssl_ca\n          - /var/apps/reverse-proxy/myCA.key:/etc/myCA.key\n          - /var/apps/reverse-proxy/myCA.pem:/etc/myCA.pem\n        restart: always\n        extra_hosts:\n          - \"dockerhost:$DOCKERHOST\"\n    ```\n* create an executable file ```/var/apps/reverse-proxy/docker-start.sh``` as start script\n    ```bash\n    #!/bin/sh\n    set -e\n    \n    export DOCKERHOST=$(ifconfig | grep -E \"([0-9]{1,3}\\.){3}[0-9]{1,3}\" | grep -v 127.0.0.1 | awk '{ print $2 }' | cut -f2 -d: | head -n1)\n    docker-compose -f docker-compose.yml up -d\n    ```\n    This one ensures that the env var ```DOCKERHOST``` always got your host ip which you can use in your reverse proxy vhost config.\n* add vhosts to your local reverse proxy:\n    * add in /etc/hosts\n        ```\n        127.0.0.1\tacme\n        127.0.0.1\tacme-webpack\n        127.0.0.1\tacme-storybook\n        ```\n    * simple https secured project\n        ```bash\n        $ docker-compose exec loadbalancer apache-init-reverseproxy-vhost.sh -d acme -i dockerhost -p 9700 -a n -m n -s y -e y -l y -r n -w n -q y\n        ```\n    * webpack-dev-server with https\n        ```bash\n        $ docker-compose exec loadbalancer apache-init-reverseproxy-vhost.sh -d acme -i dockerhost -p 9704 -a n -m n -s y -e y -l y -r n -w y -q y\n        ```\n    * storybook with https\n        ```bash\n        $ docker-compose exec loadbalancer apache-init-reverseproxy-vhost.sh -d acme -i dockerhost -p 9705 -a n -m n -s y -e y -l n -r n -q y -w n\n        ```\n* Now you can start storybook and webpack-dev-server in your development container:  \n    ```\n    $ yarn start-storybook --config-dir storybook/ --port 9705\n    ```   \n    ```\n    $ yarn encore dev-server --https --host 0.0.0.0 --port 9704 --disable-host-check  --public acme-webpack\n    ```\n    Ensure that ports 9700, 9704 and 9705 a forwarded in your development container. \n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fprojektmotor%2Fdocker-apache-load-balancer","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fprojektmotor%2Fdocker-apache-load-balancer","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fprojektmotor%2Fdocker-apache-load-balancer/lists"}