{"id":40717536,"url":"https://github.com/cantabular/hanoverd","last_synced_at":"2026-01-21T13:30:58.676Z","repository":{"id":23464769,"uuid":"26828959","full_name":"cantabular/hanoverd","owner":"cantabular","description":"Docker handover daemon - the `docker replace` you always wanted","archived":false,"fork":false,"pushed_at":"2025-12-12T11:59:13.000Z","size":545,"stargazers_count":20,"open_issues_count":7,"forks_count":8,"subscribers_count":4,"default_branch":"main","last_synced_at":"2025-12-14T01:58:16.769Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/cantabular.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","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":"2014-11-18T20:40:06.000Z","updated_at":"2025-12-12T11:59:15.000Z","dependencies_parsed_at":"2024-04-19T12:47:34.536Z","dependency_job_id":"14476525-3072-4326-b884-3e5b4e3c2858","html_url":"https://github.com/cantabular/hanoverd","commit_stats":null,"previous_names":["scraperwiki/hanoverd","cantabular/hanoverd","sensiblecodeio/hanoverd"],"tags_count":39,"template":false,"template_full_name":null,"purl":"pkg:github/cantabular/hanoverd","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cantabular%2Fhanoverd","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cantabular%2Fhanoverd/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cantabular%2Fhanoverd/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cantabular%2Fhanoverd/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/cantabular","download_url":"https://codeload.github.com/cantabular/hanoverd/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cantabular%2Fhanoverd/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28633760,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-21T04:47:28.174Z","status":"ssl_error","status_checked_at":"2026-01-21T04:47:22.943Z","response_time":86,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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":[],"created_at":"2026-01-21T13:30:58.593Z","updated_at":"2026-01-21T13:30:58.660Z","avatar_url":"https://github.com/cantabular.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"Hanoverd - The docker handover daemon\n-------------------------------------\n\nHanoverd (\"Hanover-Dee\") is responsible for managing seamless transitions\nfrom one application version to another with Docker containers.\n\nIt's the [`docker replace`](https://github.com/docker/docker/issues/2733#issuecomment-123502548) command you always wanted.\n\nStatus: beta. Things may change. We may need your feedback to make it work for you.\n\n## What is hanoverd good for?\n\nLet's say you have your web application running in docker, and you\nwant to upgrade it seamlessly.\n\nYou want to move fast and break things with continuous deployment,\nmaking updates to your app, but you don't want your web application\nto go down while it updates; or if it fails to restart.\n\nHanoverd solves the problem by leaving the first working version\nrunning until a second one has started and correctly accepted a\nrequest.\n\nHanoverd is ideal for stateless web applications running in docker\nwhere you can easily have multiple instances running side-by-side.\n\nHanoverd can pull or build images from a variety of sources, and\nalso listen to webhooks from github and elsewhere using an outbound\nTCP connection, rather than having to expose a port for listening to\nsuch events. This is done via [hookbot](#hookbot).\n\n## Installation\n\nHanoverd currently requires the ability to run iptables. This can be\nachieved with setcap to avoid using root. A suitably capable `iptables`\ncommand must be on the `$PATH`. This can be achieved with this command,\nfor example:\n\n```\ncp $(which iptables) .\nsudo setcap 'cap_net_admin,cap_net_raw=+ep' iptables\nPATH=.:$PATH hanoverd\n```\n\n(or you can use some directory other than `.`).\n\nYou should bear in mind that the ability to run iptables is the ability\nto do almost arbitrary things to the network. However, hanoverd can\nrun as a separate user from the container, so it does not share this\nprivilege.\n\n## User experience\n\n* You run one hanoverd per application you wish to run in Docker.\n* You run hanoverd in a directory containing a `Dockerfile`.\n* Starting hanoverd causes that `Dockerfile` to be built and the application is\n  started.\n* Sending hanoverd a signal results in hanoverd rebuilding the container and\n  transitioning to the new version.\n* When the new version successfully accepts a connection, the new version\n  becomes live.\n* If the new version fails to accept any connection, the old version will chug\n  along happily until a new request comes in to start a new application version.\n\n## Building and running\n\nFirst build it:\n\n```\n$ go get -v\n$ go build -v\n```\n\nThen launch it (in a directory with a Dockerfile!):\n\n```\n$ ./hanoverd\n```\n\nSupported command line options are the same sort of things as\ndocker. However not all are implemented -\n[please submit an issue](https://github.com/sensiblecodeio/hanoverd/issues/new)\nif there is one you need which is missing.\n\n* `--env`, `-e` for environment, e.g. `--env HOME` to pass `$HOME` through or `--env HOME=/home/foo`\n* `--publish`, `-p` for specifying port mappings\n* `--volume`, `-v` for volumes\n\nOther things:\n\n* `--status-uri` (defaults to `/`), specify a status URL to send HTTP pings to to determine initial health\n* `--hookbot`, specify a hookbot websocket URL to listen on\n\nEnvironment variables which the docker client (and boot2docker) use\ncan be set first.\n\n    DOCKER_CERT_PATH\n    DOCKER_HOST\n    DOCKER_TLS_VERIFY\n\nAdditionally, Hanoverd injects internal environment variables that can be used\nby the container:\n\n    HANOVERD_IMAGE\n    HANOVERD_IMAGE_REPO\n    HANOVERD_IMAGE_TAGDIGEST\n\n## Method\n\nHanoverd has a few phases. It commences this when it first starts or\nwhen it is signalled.\n\n* Obtain image (can be done a few ways)\n* Start container with the new image\n* Rapidly poll container with requests until it gives a 200 response\n* Redirect traffic to the new container using iptables rules\n* Stop the old container\n\nIf a signal comes in to start a new container and the previous\none has not had new traffic directed to it yet, image obtaining is\ncancelled or the container is stopped and deleted.\n\n## Obtaining an image\n\nImages can be obtained via building them or pulling them from a\nregistry. This part is extensible, so coding something to import\na tar from S3 would also be doable, for example.\n\n## Hookbot\n\n[Hookbot](https://github.com/sensiblecodeio/hookbot) is a service\nthat allows applications such as hanoverd to listen for webhooks\nby using an *outbound* websocket.\n\nHanoverd can make an outbound connection to a hookbot server in order\nto respond to webhook events without needing to listen for them.\nHanoverd supports a few different URL types, for example to build\nand run a github project on a specific branch whenever the branch changes:\n\n```\nhanoverd --hookbot wss://TOKEN@hookbot.scraperwiki.com/sub/github.com/repo/sensiblecodeio/project/branch/master\n```\n\nOr to pull from a docker registry:\n\n```\nhanoverd --hookbot wss://TOKEN@hookbot.scraperwiki.com/sub/docker-pull/localhost.localdomain:5000/pdftables.com/tag/master\n```\n\nInstead of using the `--hookbot` parameter one can also use the\n`HOOKBOT_URL` environment variable.\n\n## Plans (not a promise, may never happen)\n\nRight now restarts are not-quite-zero-downtime. We haven't seen\na broken connection because of it, but if you have long running\nrequests it could happen. This could be reasonably easily fixed\nby giving the old container some grace time.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcantabular%2Fhanoverd","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcantabular%2Fhanoverd","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcantabular%2Fhanoverd/lists"}