{"id":19569519,"url":"https://github.com/containx/beethoven","last_synced_at":"2025-04-27T03:30:42.370Z","repository":{"id":57609819,"uuid":"68429441","full_name":"ContainX/beethoven","owner":"ContainX","description":"Mesos/Marathon, Docker Swarm HTTP Proxy via NGINX","archived":false,"fork":false,"pushed_at":"2017-10-02T04:49:00.000Z","size":220,"stargazers_count":19,"open_issues_count":0,"forks_count":0,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-04-04T20:25:35.864Z","etag":null,"topics":["docker","loadbalancer","marathon","mesos","nginx","proxy","swarm"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ContainX.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2016-09-17T03:21:59.000Z","updated_at":"2024-02-02T08:51:21.000Z","dependencies_parsed_at":"2022-08-27T11:33:18.461Z","dependency_job_id":null,"html_url":"https://github.com/ContainX/beethoven","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ContainX%2Fbeethoven","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ContainX%2Fbeethoven/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ContainX%2Fbeethoven/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ContainX%2Fbeethoven/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ContainX","download_url":"https://codeload.github.com/ContainX/beethoven/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":251085147,"owners_count":21533821,"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":["docker","loadbalancer","marathon","mesos","nginx","proxy","swarm"],"created_at":"2024-11-11T06:10:17.034Z","updated_at":"2025-04-27T03:30:42.071Z","avatar_url":"https://github.com/ContainX.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# B E E T H O V E N\n\n**Beethoven** is an application written in Go that automatically configures Nginx for applications deployed on Marathon/Mesos or Docker Swarm.  Beethoven runs in Docker and can be managed by the scheduler to provide HTTP loadbalancing.\n\n**Feature Highlights**\n\n* Uses Nginx for HTTP based loadbalancing\n* Handlebars for powerful template parsing\n* Allows stream filtering so Nginx re-configuration is only triggered by RegEx patterns\n* Listens to the realtime SSE from Marathon to quickly change upstreams based on application/tasks state changes\n* RESTful endpoints for current status\n* Flexible configuration options (local config, spring-cloud configuration remote configuration fetching and ENV variables)\n* Easy to get started add a `FROM containx/beethoven` to your `Dockerfile` add your template, config options and deploy!\n* Scheduler Support - Marathon/Mesos or Docker Swarm Mode\n\n\n### Architecture Overview\n\n![Architecture](images/beethoven-architecture.jpg?raw=true \"Architecture\")\n\nBeethoven runs in your cluster as a container managed by Marathon or Docker Swarm Mode.  This allows for horizontal scaling across the cluster.  Supervisor is leveraged to manage both Nginx and Beethoven since we are running two executables in a single container.\n\nBeethoven attaches to the event stream and listens for real-time changes to Services and Tasks.  This includes new applications being added to the cluster or existing which has had a state change such as a health event.\n\nWhen an event occurs Beethoven takes the user provided `nginx.template` and parses it with the Handlebars processor.  Handlebars offers a lot of power behind the template including logic blocks, object iteration and other conditional behaviours. \n\nAfter the template has been parsed a temp Nginx configuration file is rendered within the container.  Beethoven then asks Nginx to validate the temporary configuration file to determine if it's syntax is correct.  If the syntax is good then the current `nginx.conf` is replaced with the temp. file and a soft reload is issued.  If the temp file is bad then it is recorded and associated with the `/bt/status/` endpoint for debugging.\n\n### Getting Started\n\nBelow we will cover the barebones setup to get going.  \n\n#### Create a Template\n\nCreate a file called `nginx.template`.  Refer to the `nginx.template` found in the [examples/](https://github.com/ContainX/beethoven/tree/master/examples) directory in this repo. Modify the example to suit your own needs \n\n**A couple notes about the example template:**  \n- The `{{#if}}` blocks are optional.  I prefer these so if an application is removed all together in the cluster then the final `nginx.conf` is valid\n- The `/_health` endpoint at the bottom is optional.  If allows for Marathon health checks to use that to determine Nginx is running. \n- The `/_bt` endpoint at the bottom is optional.  If you would like to find information such as updated times and any failures from Beethoven then this mapping allows you to expose these internal endpoints via Nginx.  Alternatively you can expose Beethoven via it's configured port.\n\n### Create the Beethoven Configuration File\n\nCreate a file that ends in `.json`.  In this example we'll use Marathon as the scheduler and call the file `config-marathon.json`. Refer to the `config-marathon.json` found in the [examples/](https://github.com/ContainX/beethoven/tree/master/examples) directory in this repo.\n  \nAdd/Modify any options to suit your needs.  For a description and all possible configuration options refer to the docs found within the [config.go](https://github.com/ContainX/beethoven/blob/master/config/config.go) file.\n \n#### Create a Dockerfile\n\nNext we will create the `Dockerfile` to package up the `nginx.template` and `config-marathon.json` files.  If you used the filenames in this guide then simply copy the code below into your `Dockerfile`.\n\n```\nFROM containx/beethoven\n\nADD nginx.template /etc/nginx/nginx.template\nADD config-marathon.json /etc/config-marathon.json\n```\n\n#### Build and Testing your Container\n\nBuild and Run your Container\n\n```\ndocker build -t myloadbalancer .\ndocker run -p 80:80 -d myloadbalancer -c /etc/config-marathon.json\n```\n\nNow open your browser and test paths you created at http://localhost\n\n#### Using a remote configuration file on Startup\n\nA good practice is to keep configuration outside of Docker so the same container can be used between environments (QA, Prod, etc).  \n\nBeethoven has built in support for using [spring-cloud-config](http://cloud.spring.io/spring-cloud-static/spring-cloud-config/1.2.0.RELEASE/) for centralized configuration.  Lets take the Docker example above but run it using our remote server.\n\n\n```\ndocker run -p 80:80 -d myloadbalancer --remote --server http://spring-cloud-host:8888 --name myloadbalancer --profile prod\n```\n\nYou can also specify the `--label` option which is the SCM branch the configuration server is pulling from. The names used above `profile, label and name` are the same names referenced in the official guide for `spring-cloud-config`. http://cloud.spring.io/spring-cloud-static/spring-cloud-config/1.2.0.RELEASE/\n\n\n## License\n\nThis software is licensed under the Apache 2 license, quoted below.\n\nCopyright 2017 ContainX / Jeremy Unruh\n\nLicensed under the Apache License, Version 2.0 (the \"License\"); you may not\nuse this file except in compliance with the License. You may obtain a copy of\nthe License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT\nWARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the\nLicense for the specific language governing permissions and limitations under\nthe License.","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcontainx%2Fbeethoven","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcontainx%2Fbeethoven","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcontainx%2Fbeethoven/lists"}