{"id":13415987,"url":"https://gitlab.com/n0r1sk/bosnd","last_synced_at":"2025-03-14T23:31:19.275Z","repository":{"id":63887131,"uuid":"6799913","full_name":"n0r1sk/bosnd","owner":"n0r1sk","description":"BosnD, the boatswain daemon - A dynamic configuration file writer \u0026 service reloader for dynamically changing container environments.\r\n","archived":false,"fork":false,"pushed_at":null,"size":null,"stargazers_count":4,"open_issues_count":0,"forks_count":1,"subscribers_count":null,"default_branch":"master","last_synced_at":"2024-07-31T21:54:53.276Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":null,"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":false,"icon_url":"https://gitlab.com/uploads/-/system/project/avatar/6799913/bosnd-sticker.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","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":"2018-06-05T12:10:15.399Z","updated_at":"2021-01-15T06:38:24.845Z","dependencies_parsed_at":"2022-11-28T13:27:06.528Z","dependency_job_id":null,"html_url":"https://gitlab.com/n0r1sk/bosnd","commit_stats":null,"previous_names":[],"tags_count":13,"template":null,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/gitlab.com/repositories/n0r1sk%2Fbosnd","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/gitlab.com/repositories/n0r1sk%2Fbosnd/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/gitlab.com/repositories/n0r1sk%2Fbosnd/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/gitlab.com/repositories/n0r1sk%2Fbosnd/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/gitlab.com/owners/n0r1sk","download_url":"https://gitlab.com/n0r1sk/bosnd/-/archive/master/bosnd-master.zip","host":{"name":"gitlab.com","url":"https://gitlab.com","kind":"gitlab","repositories_count":4518057,"owners_count":6822,"icon_url":"https://github.com/gitlab.png","version":null,"created_at":"2022-05-30T11:31:42.605Z","updated_at":"2024-07-18T11:24:13.055Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/gitlab.com","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/gitlab.com/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/gitlab.com/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/gitlab.com/owners"}},"keywords":[],"created_at":"2024-07-30T21:00:53.482Z","updated_at":"2025-03-14T23:31:14.265Z","avatar_url":"https://gitlab.com/uploads/-/system/project/avatar/6799913/bosnd-sticker.png","language":null,"funding_links":[],"categories":["Container Operations","Running Containers"],"sub_categories":["Deployment and Infrastructure","Deployment \u0026 Platforms"],"readme":"# Bosnd\n\n![BosnD Sticker](https://gitlab.com/n0r1sk/bosnd/raw/master/sticker/bosnd-sticker-4.png)\n\nBosnD, the boatswain daemon - A dynamic configuration file writer \u0026 service reloader for dynamically changing container environments. ```Bosnd``` means boatswain daemon. The word itself comes from ```bos'n``` which is a pronounciation used by people with sea legs.\n\n## What it does\n\n```BosnD``` takes a configuration file as argument and based on that configuration file, it uses the given Docker Swarm connection to retrieve information from the Docker Swarm. Therefore the daemon connects to a Docker Swarm manager (leader or promoted node) via the Docker API. The needed information is collected from the ```docker network inspect -v \u003cnetwork\u003e``` and ```docker service inspect \u003cservice\u003e``` commands via API. After the information is retrieved, ```BosnD``` processes the configured Golang templates and writes the resulting configuration files to the desired (configured) locations. Afterwards ```BosnD``` will reload the controlled daemon, which is also configured in the ```bosnd.yml``` config file. Alternatively and recommended, the ```midshipman``` \n\n## Quickstart\n\n1. Clone the repository enable Docker Swarm:\n~~~bash\ngit clone https://gitlab.com/n0r1sk/bosnd\n~~~\n\nIf you have not already enabled Docker Swarm mode just do it now:\n~~~bash\ndocker swarm init\n~~~\n\n2. Build your own Nginx Docker image which is enhanced with BosnD\n~~~bash\ncd bosnd/examples/bosnd-nginx\ndocker build . -t mybosnd\n~~~\n\n3. Create a Docker overlay network, start your own BosnD-Nginx image and attach it to the created overlay network\n~~~bash\ndocker network create --driver=overlay --attachable test_net\ndocker run -d --net=test_net -p 80:80 -v /var/run/docker.sock:/var/run/docker.sock --name=mybosnd mybosnd\n~~~\n\nIf you run `docker logs -f mybosnd` in a second console afterwards, you will notice, that the current configuraiton is not valid, as there are no endpoints at the moment which can be picked up by the BosnD to create a valid Nginx configuration file currently. Furthermore, for demonstration purpose, the BonsD will try to refresh the configuration every three seconds.\n\n4. Create a Docker Stack whose services are using the same Docker overlay network\n~~~bash\ncd swarm\ndocker stack deploy -c teststack.yml test\n~~~\n\nPlease wait some time, until the defined replicas are running. This might take some time. You can check the current status with:\n~~~bash\ndocker service ls\nID                  NAME                MODE                REPLICAS            IMAGE                       PORTS\n1sv0kmogkppo        test_app            replicated          0/2                 n0r1skcom/echohttp:latest   \n~~~\n\nAfter the replicas are online, the following output should appear in the log output of the BosnD.\n~~~bash\nINFO[2018-12-15 11:19:23] MD5 sums of  /es/tpl/nginx.conf.tpl different writing new conf! \nINFO[2018-12-15 11:19:23] Reloading Process! \n~~~\n\n5. Open a browser an check the Nginx load balancing\nOpen a browser and open the URL `http://localhost`. The following output should appear:\n~~~\n================================================================================\nHostname:                     test_app-1\n--------------------------------------------------------------------------------\nInterface lo:                 127.0.0.1/8\nInterface lo:                 10.0.0.15/32\nInterface eth0:               10.0.0.16/24\nInterface eth1:               172.18.0.4/16\n--------------------------------------------------------------------------------\nCache-Control                 max-age=0\nAccept                        text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8\nAccept-Language               de,en-US;q=0.9,en;q=0.8,ru;q=0.7\nX-Forwarded-For               172.18.0.1\nConnection                    close\nX-Real-Ip                     172.18.0.1\nX-Forwarded-Proto             http\nUpgrade-Insecure-Requests     1\nUser-Agent                    Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/71.0.3578.80 Chrome/71.0.3578.80 Safari/537.36\nAccept-Encoding               gzip, deflate, br\nX-Forwarded-Server            localhost\n~~~\n\n6. Disable sticky sessions by editing the Docker Swarm deployment\nIf you would like to disable the stickiness of your Docker Stack, just edit the `examples/bosnd-nginx/swarm/teststack.yml` file and remove the `sticky` label. Afterwards redeploy you Docker Stack.\n\n### Lessons learned\nThis Quickstart should show, how you can build a custom Docker Image including the BosnD to change configuration files dynamically based on Docker Swarm information. Mounting the `/var/run/docker.sock` file is not needed, if you use additional services like the `Midshipman` which will be probably integrated in BosnD in one of the next version.\n\nYou are also not limited to Nginx. Instead you could use any binary which could be configured via config files. The BosnD does not restrict you in which binary programm you would like to use, nor does it restrict you in any kind of labels you would like to define to control your configuration files based on the Golang template language.\n\nFurthermore, you can run multiple BosnD on one Docker host by specifying another port mapping during the `docker run` command, eg `-p \"192.168.3.1:80:80\"`. This enables you to use one Docker Host with multiple IP addresses to bind you services to, for example `https`.\n\n## Features\n\n- Mutliple configuration templates\n- Usable with any daemon binary\n- Automatically reload the daemon on every change (if supported by the daemon) \n- Reconfigurable during runtime\n- Recognises new Docker stack services which are appearing on the Docker network on the fly\n- Add new Docker networks to the Bosnd on the fly\n- Optional switchable debug mode including Golang pprof interface\n\n\n## Why don't use xyz...\n\n```BosnD``` is not meant to replace an already existing software. If you are familiar with Traefik for example, please use it. We have created ```BosnD``` because we were in the need to configure software in the Docker environment in a dynamic way. For example, Traefik is already able to read the running services out of the Docker Swarm events. But for us, thats not all we need and also thats not enough. There are a lot of other services which are not Docker Swarm aware. Imagine the following situation: You have a myriad of Apache Tomcat application servers as backends and they are working perfectly in combination with Apache httpd as a load balancer because the Apache httpd has a very pretty module called ```mod_jk```. Now, if you want to modernize this applications with the Docker Swarm environment, you will face some problems. First, you won't drop Apache httpd, because it is the best for the job. Therefore you need a flexible way to change the configuration of the httpd on the fly and reload it. Also, you won't like to map the Docker socket into the loadbalancer container to read the Docker events because that puts the system on a risk. If something terrible happens, someone can have access to the full Docker Swarm API. Bad. It's better to communicate with the swarm via the external API, the API can be protected by RBAC mechanisms like [Golang casbin](https://github.com/casbin/casbin-authz-plugin). And, last but not least, you may have more than one service like the Apache httpd which you would like to empower with dynamic template based configuration.\n\n## And what about confd?\n\nAs we wrote ```BosnD``` we soon recognized, that we are writing something like [confd](https://github.com/kelseyhightower/confd). Thats true. But with a different approach. confd will propagate the affected daemon with the new configuration and then reload/restart it. ```BosnD``` in the opposite will be the number one process inside the container. It is responsible for the invoked daemon. If ```BosnD``` dies, the container dies and it will be restarted (if configured in the compose-swarm.yml). Yes, there is always a discussion if there should be only one process inside a container but this is the decision we made (more than one process) for us because we need a general purpose tool. Next, instead of enforcing the possible combination of labels (like Traefik does;no critics here), we decided to let you label the things you like it because we can use the full capability of the Golang Template language. If you need the port, add a label and then use it in the template.\n\n## But it is not real time...\n\n... you are not listening on the Docker events! ;-)\n\nPlease define real time. Real time in computing is, when you can guarantee a system response within a specific time frame. By default, ```BosnD``` will pull the actual state of the Docker network every 30 seconds (that's configurable). This is real time.\n\n## Template files\n\nThe template files are working with the [Golang template language](https://golang.org/pkg/text/template/).\n\n## Control\n\nThe control interface can be used to force a service reload from the outside via http. This is useful, if you have services which are rely on SSL certificates which are renewed by a LetsEncrypt container. If this container renews the certificates you might want to reload the service which is controlled by the ```BosnD``` too.\n~~~yaml\ncontrol:\n  port: 3333\n  key: mykey\n~~~\n\nIf you enable the control block, you can use a browser (or curl) afterwards to trigger the reload: \n```\n$ curl http://127.0.0.1:3333/reload/mykey\n$ Reloaded!\n```\n\n## Cron daemon reload\n\nThis can be used to periodically reload the daemon which is controlled by Bosnd, eg. if you are using LetsEncrpyt certificates, there might be the need to reload the controlled daemon ever n-days.\n\n~~~yaml\nCron struct {\n\tCrontab string // this is the enable Cron config switch\n}\n~~~\n\n## Midshipman\nConfiguration of the midship man url is done via the following config\n\n~~~yaml\nMidshipman string // this enables the midshipman interface\n~~~\n\n# Full current config options (taken from types.go)\n~~~yaml\ntype Config struct {\n\tDebug          bool\n\tDebugport      string\n\tCheckintervall int64\n\tCmd            struct {\n\t\tStart       []string\n\t\tReload      []string\n\t\tProcessname string\n\t}\n\tMidshipman string // this enables the midshipman interface\n\tTemplates  map[string]Configfilepair\n\tSwarm      struct {\n\t\tCacertpem     string\n\t\tClientcertpem string\n\t\tClientkeypem  string\n\t\tDomainprefix  string\n\t\tDomainzone    string\n\t\tManagerurl    string\n\t\tUsesocket     bool\n\t\tServices      *[]Service\n\t\tNetworks      []string // this is the enable Swarm config switch\n\t}\n\tFiledb  string // this is the enable switch for the json based file db\n\tControl struct {\n\t\tPort string\n\t\tKey  string // this is the enable Control config switch\n\t}\n\tCron struct {\n\t\tCrontab string // this is the enable Cron config switch\n\t}\n}\n~~~\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/gitlab.com%2Fn0r1sk%2Fbosnd","html_url":"https://awesome.ecosyste.ms/projects/gitlab.com%2Fn0r1sk%2Fbosnd","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/gitlab.com%2Fn0r1sk%2Fbosnd/lists"}