{"id":26131349,"url":"https://github.com/jonasprogrammer/docker-machine-driver-hetzner","last_synced_at":"2025-12-15T02:50:28.094Z","repository":{"id":44806490,"uuid":"109452425","full_name":"JonasProgrammer/docker-machine-driver-hetzner","owner":"JonasProgrammer","description":"Docker machine driver for the new hetzner cloud API","archived":false,"fork":false,"pushed_at":"2023-12-15T15:22:39.000Z","size":200,"stargazers_count":434,"open_issues_count":13,"forks_count":53,"subscribers_count":13,"default_branch":"master","last_synced_at":"2024-11-13T10:37:47.724Z","etag":null,"topics":["docker","docker-machine","driver","hetzner","machine"],"latest_commit_sha":null,"homepage":"https://jonasprogrammer.github.io/docker-machine-driver-hetzner/","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/JonasProgrammer.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,"governance":null,"roadmap":null,"authors":null}},"created_at":"2017-11-03T23:45:14.000Z","updated_at":"2024-10-31T04:04:56.000Z","dependencies_parsed_at":"2023-09-24T02:02:00.022Z","dependency_job_id":"a2e96a45-8ed8-428c-b36b-fc943116305d","html_url":"https://github.com/JonasProgrammer/docker-machine-driver-hetzner","commit_stats":{"total_commits":152,"total_committers":22,"mean_commits":6.909090909090909,"dds":0.5592105263157895,"last_synced_commit":"e4302bfa30e9f97421eacdc50f932a76cac2ed39"},"previous_names":[],"tags_count":49,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JonasProgrammer%2Fdocker-machine-driver-hetzner","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JonasProgrammer%2Fdocker-machine-driver-hetzner/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JonasProgrammer%2Fdocker-machine-driver-hetzner/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JonasProgrammer%2Fdocker-machine-driver-hetzner/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/JonasProgrammer","download_url":"https://codeload.github.com/JonasProgrammer/docker-machine-driver-hetzner/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":242933899,"owners_count":20208912,"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","docker-machine","driver","hetzner","machine"],"created_at":"2025-03-10T22:00:29.949Z","updated_at":"2025-12-15T02:50:28.017Z","avatar_url":"https://github.com/JonasProgrammer.png","language":"Go","readme":"# Hetzner Cloud Docker machine driver\n\n[![Go Report Card](https://goreportcard.com/badge/github.com/JonasProgrammer/docker-machine-driver-hetzner)](https://goreportcard.com/report/github.com/JonasProgrammer/docker-machine-driver-hetzner)\n[![License](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)\n[![Go-CI](https://github.com/JonasProgrammer/docker-machine-driver-hetzner/actions/workflows/go.yml/badge.svg)](https://github.com/JonasProgrammer/docker-machine-driver-hetzner/actions/workflows/go.yml)\n\n\u003e This library adds the support for creating [Docker machines](https://github.com/docker/machine) hosted on the [Hetzner Cloud](https://www.hetzner.de/cloud).\n\nYou need to create a project-specific access token under `Access` \u003e `API Tokens` in the project control panel\nand pass that to `docker-machine create` with the `--hetzner-api-token` option.\n\n## Installation\n\nYou can find sources and pre-compiled binaries [here](https://github.com/JonasProgrammer/docker-machine-driver-hetzner/releases).\n\n```bash\n# Download the binary (this example downloads the binary for linux amd64)\n$ wget https://github.com/JonasProgrammer/docker-machine-driver-hetzner/releases/download/5.0.0/docker-machine-driver-hetzner_5.0.0_linux_amd64.tar.gz\n$ tar -xvf docker-machine-driver-hetzner_5.0.0_linux_amd64.tar.gz\n\n# Make it executable and copy the binary in a directory accessible with your $PATH\n$ chmod +x docker-machine-driver-hetzner\n$ cp docker-machine-driver-hetzner /usr/local/bin/\n```\n\n## Usage\n\n```bash\n$ docker-machine create \\\n  --driver hetzner \\\n  --hetzner-api-token=QJhoRT38JfAUO037PWJ5Zt9iAABIxdxdh4gPqNkUGKIrUMd6I3cPIsfKozI513sy \\\n  some-machine\n```\n\n### Using environment variables\n\n```bash\n$ HETZNER_API_TOKEN=QJhoRT38JfAUO037PWJ5Zt9iAABIxdxdh4gPqNkUGKIrUMd6I3cPIsfKozI513sy \\\n  \u0026\u0026 HETZNER_IMAGE=centos-7 \\\n  \u0026\u0026 docker-machine create \\\n     --driver hetzner \\\n     some-machine\n```\n\n### Dealing with kernels without aufs\n\nIf you use an image without aufs, like the one currently supplied with the\ndebian-9 image, you can try specifying another storage driver, such as\noverlay2. Like so:\n\n```bash\n$ docker-machine create \\\n  --engine-storage-driver overlay2 \\\n  --driver hetzner \\\n  --hetzner-image debian-9 \\\n  --hetzner-api-token=QJhoRT38JfAUO037PWJ5Zt9iAABIxdxdh4gPqNkUGKIrUMd6I3cPIsfKozI513sy \\\n  some-machine\n```\n\n### Using Cloud-init\n\n```bash\n$ CLOUD_INIT_USER_DATA=`cat \u003c\u003cEOF\n#cloud-config\nwrite_files:\n  - path: /test.txt\n    content: |\n      Here is a line.\n      Another line is here.\nEOF\n`\n\n$ docker-machine create \\\n  --driver hetzner \\\n  --hetzner-api-token=QJhoRT38JfAUO037PWJ5Zt9iAABIxdxdh4gPqNkUGKIrUMd6I3cPIsfKozI513sy \\\n  --hetzner-user-data=\"${CLOUD_INIT_USER_DATA}\" \\\n  some-machine\n```\n\n### Using a snapshot\n\nAssuming your snapshot ID is `424242`:\n```bash\n$ docker-machine create \\\n  --driver hetzner \\\n  --hetzner-api-token=QJhoRT38JfAUO037PWJ5Zt9iAABIxdxdh4gPqNkUGKIrUMd6I3cPIsfKozI513sy \\\n  --hetzner-image-id=424242 \\\n  some-machine\n```\n\n## Options\n\n- `--hetzner-api-token`: **required**. Your project-specific access token for the Hetzner Cloud API.\n- `--hetzner-image`: The name (or ID) of the Hetzner Cloud image to use, see [Images API](https://docs.hetzner.cloud/#images-get-all-images) for how to get a list (currently defaults to `ubuntu-20.04`). *Explicitly specifying an image is **strongly** recommended and will be **required from v6 onwards***.\n- `--hetzner-image-arch`: The architecture to use during image lookup, inferred from the server type if not explicitly given.\n- `--hetzner-image-id`: The id of the Hetzner cloud image (or snapshot) to use, see [Images API](https://docs.hetzner.cloud/#images-get-all-images) for how to get a list (mutually excludes `--hetzner-image`).\n- `--hetzner-server-type`: The type of the Hetzner Cloud server, see [Server Types API](hhttps://docs.hetzner.cloud/#server-types-get-all-server-types) for how to get a list (defaults to `cx11`).\n- `--hetzner-server-location`: The location to create the server in, see [Locations API](https://docs.hetzner.cloud/#locations-get-all-locations) for how to get a list.\n- `--hetzner-existing-key-path`: Use an existing (local) SSH key instead of generating a new keypair. If a remote key with a matching fingerprint exists, it will be used as if specified using `--hetzner-existing-key-id`, rather than uploading a new key.\n- `--hetzner-existing-key-id`: **requires `--hetzner-existing-key-path`**. Use an existing (remote) SSH key instead of uploading the imported key pair,\n  see [SSH Keys API](https://docs.hetzner.cloud/#ssh-keys-get-all-ssh-keys) for how to get a list\n- `--hetzner-additional-key`: Upload an additional public key associated with the server, or associate an existing one with the same fingerprint. Can be specified multiple times.\n- `--hetzner-user-data`: Cloud-init based data, passed inline as-is.\n- `--hetzner-user-data-file`: Cloud-init based data, read from passed file.\n- `--hetzner-user-data-from-file`: DEPRECATED, use `--hetzner-user-data-file`. Read `--hetzner-user-data` as file name and use contents as user-data.\n- `--hetzner-volumes`: Volume IDs or names which should be attached to the server\n- `--hetzner-networks`: Network IDs or names which should be attached to the server private network interface\n- `--hetzner-use-private-network`: Use private network\n- `--hetzner-firewalls`: Firewall IDs or names which should be applied on the server\n- `--hetzner-server-label`: `key=value` pairs of additional metadata to assign to the server.\n- `--hetzner-key-label`: `key=value` pairs of additional metadata to assign to SSH key (only applies if newly created).\n- `--hetzner-placement-group`: Add to a placement group by name or ID; a spread-group will be created on demand if it does not exist\n- `--hetzner-auto-spread`: Add to a `docker-machine` provided `spread` group (mutually exclusive with `--hetzner-placement-group`)\n- `--hetzner-ssh-user`: Change the default SSH-User\n- `--hetzner-ssh-port`: Change the default SSH-Port\n- `--hetzner-primary-ipv4/6`: Sets an existing primary IP (v4 or v6 respectively) for the server, as documented in [Networking](#networking)\n- `--hetzner-wait-on-error`: Amount of seconds to wait on server creation failure (0/no wait by default)\n- `--hetzner-wait-on-polling`: Amount of seconds to wait between requests when waiting for some state to change. (Default: 1 second)\n- `--hetzner-wait-for-running-timeout`: Max amount of seconds to wait until a machine is running. (Default: 0/no timeout)\n\nPlease beware, that for options referring to entities by name, such as server locations and types, the names used by the API may differ from the ones\nshown in the server creation UI. If server creation fails due to a failure to resolve such issues, try another variant of the name (e.g. lowercase,\nkebab-case). As of writing, server types use lowercase (i.e. `cx21` instead of `CX21`) and locations use a three-letter abbreviation suffixed by 1\n(i.e. `fsn1` instead of `Falkenstein`).\n\n#### Image selection\n\nWhen `--hetzner-image-id` is passed, it will be used for lookup by ID as-is. No additional validation is performed, and it is mutually exclusive with\nother `--hetzner-image*`-flags.\n\nWhen `--hetzner-image` is passed, lookup will happen either by name or by ID as per Hetzner-supplied logic. The lookup mechanism will filter by image\narchitecture, which is usually inferred from the server type. One may explicitly specify it using `--hetzner-image-arch` in which case the user\nsupplied value will take precedence.\n\nWhile there is currently a default image as fallback, this behaviour will be removed in a future version. Explicitly specifying an operating system\nimage is strongly recommended for new deployments, and will be mandatory in upcoming versions.\n\n#### Existing SSH keys\n\nWhen you specify the `--hetzner-existing-key-path` option, the driver will attempt to copy `(specified file name)`\nand `(specified file name).pub` to the machine's store path. They public key file's permissions will be set according\nto your current `umask` and the private key file will have `600` permissions.\n\nWhen you additionally specify the `--hetzner-existing-key-id` option, the driver will not create an SSH key using the API\nbut rather try to use the existing public key corresponding to the given id. Please note that during machine creation,\nthe driver will attempt to [get the key](https://docs.hetzner.cloud/#resources-ssh-keys-get-1) and **compare it's\nfingerprint to the local public key's fingerprtint**. Keep in mind that the both the local and the remote key must be\naccessible and have matching fingerprints, otherwise the machine will fail it's pre-creation checks.\n\nAlso note that the driver will attempt to delete the linked key during machine removal, unless `--hetzner-existing-key-id`\nwas used during creation.\n\n#### Environment variables and default values\n\n| CLI option                           | Environment variable               | Default                    |\n|--------------------------------------|------------------------------------|----------------------------|\n| **`--hetzner-api-token`**            | `HETZNER_API_TOKEN`                |                            |\n| `--hetzner-image`                    | `HETZNER_IMAGE`                    | `ubuntu-20.04` as fallback |\n| `--hetzner-image-arch`               | `HETZNER_IMAGE_ARCH`               | *(infer from server)*      |\n| `--hetzner-image-id`                 | `HETZNER_IMAGE_ID`                 |                            |\n| `--hetzner-server-type`              | `HETZNER_TYPE`                     | `cx11`                     |\n| `--hetzner-server-location`          | `HETZNER_LOCATION`                 | *(let Hetzner choose)*     |\n| `--hetzner-existing-key-path`        | `HETZNER_EXISTING_KEY_PATH`        | *(generate new keypair)*   |\n| `--hetzner-existing-key-id`          | `HETZNER_EXISTING_KEY_ID`          | 0 *(upload new key)*       |\n| `--hetzner-additional-key`           | `HETZNER_ADDITIONAL_KEYS`          |                            |\n| `--hetzner-user-data`                | `HETZNER_USER_DATA`                |                            |\n| `--hetzner-user-data-file`           | `HETZNER_USER_DATA_FILE`           |                            |\n| `--hetzner-networks`                 | `HETZNER_NETWORKS`                 |                            |\n| `--hetzner-firewalls`                | `HETZNER_FIREWALLS`                |                            |\n| `--hetzner-volumes`                  | `HETZNER_VOLUMES`                  |                            |\n| `--hetzner-use-private-network`      | `HETZNER_USE_PRIVATE_NETWORK`      | false                      |\n| `--hetzner-disable-public-ipv4`      | `HETZNER_DISABLE_PUBLIC_IPV4`      | false                      |\n| `--hetzner-disable-public-ipv6`      | `HETZNER_DISABLE_PUBLIC_IPV6`      | false                      |\n| `--hetzner-disable-public`           | `HETZNER_DISABLE_PUBLIC`           | false                      |\n| `--hetzner-server-label`             | (inoperative)                      | `[]`                       |\n| `--hetzner-key-label`                | (inoperative)                      | `[]`                       |\n| `--hetzner-placement-group`          | `HETZNER_PLACEMENT_GROUP`          |                            |\n| `--hetzner-auto-spread`              | `HETZNER_AUTO_SPREAD`              | false                      |\n| `--hetzner-ssh-user`                 | `HETZNER_SSH_USER`                 | root                       |\n| `--hetzner-ssh-port`                 | `HETZNER_SSH_PORT`                 | 22                         |\n| `--hetzner-primary-ipv4`             | `HETZNER_PRIMARY_IPV4`             |                            |\n| `--hetzner-primary-ipv6`             | `HETZNER_PRIMARY_IPV6`             |                            |\n| `--hetzner-wait-on-error`            | `HETZNER_WAIT_ON_ERROR`            | 0                          |\n| `--hetzner-wait-on-polling`          | `HETZNER_WAIT_ON_POLLING`          | 1                          |\n| `--hetzner-wait-for-running-timeout` | `HETZNER_WAIT_FOR_RUNNING_TIMEOUT` | 0                          |\n\n#### Networking\n\nGiven `--hetzner-primary-ipv4` or `--hetzner-primary-ipv6`, the driver\nattempts to set up machine creation with an existing [primary IP](https://docs.hetzner.com/cloud/servers/primary-ips/overview/)\nas follows: If the passed argument parses to a valid IP address, the primary IP is resolved via address.\nOtherwise, it is resolved in the default Hetzner Cloud API way (i.e. via ID and name as a fallback).\n\nNo address family validation is performed, so when specifying an IP address it is the user's responsibility to pass the\nappropriate type. This also applies to any given preconditions regarding the state of the address being attached.\n\nIf no existing primary IPs are specified and public address creation is not disabled for a given address family, a new\nprimary IP will be auto-generated by default. Primary IPs created in that fashion will exhibit whatever default behavior\nHetzner assigns them at the given time, so users should take care what retention flags etc. are being set.\n\nWhen disabling all public IPs, `--hetzner-use-private-network` must be given.\n`--hetzner-disable-public` will take care of that, and behaves as if\n`--hetzner-disable-public-ipv4 --hetzner-disable-public-ipv6 --hetzner-use-private-network`\nwere given.\nUsing `--hetzner-use-private-network` implicitly or explicitly requires at least one `--hetzner-network`\nto be given.\n\n## Building from source\n\nUse an up-to-date version of [Go](https://golang.org/dl) to use Go Modules.\n\nTo use the driver, you can download the sources and build it locally:\n\n```shell\n# Enable Go Modules if you are not outside of your $GOPATH\n$ export GO111MODULE=on\n\n# Get sources and build the binary at ~/go/bin/docker-machine-driver-hetzner\n$ go get github.com/jonasprogrammer/docker-machine-driver-hetzner\n\n# Make the binary accessible to docker-machine\n$ export GOPATH=$(go env GOPATH)\n$ export GOBIN=$GOPATH/bin\n$ export PATH=\"$PATH:$GOBIN\"\n$ cd $GOPATH/src/jonasprogrammer/docker-machine-driver-hetzner\n$ go build -o docker-machine-driver-hetzner\n$ cp docker-machine-driver-hetzner /usr/local/bin/docker-machine-driver-hetzner\n```\n\n## Development\n\nFork this repository, yielding `github.com/\u003cyourAccount\u003e/docker-machine-driver-hetzner`.\n\n```shell\n# Get the sources of your fork and build it locally\n$ go get github.com/\u003cyourAccount\u003e/docker-machine-driver-hetzner\n\n# * This integrates your fork into the $GOPATH (typically pointing at ~/go)\n# * Your sources are at $GOPATH/src/github.com/\u003cyourAccount\u003e/docker-machine-driver-hetzner\n# * That folder is a local Git repository. You can pull, commit and push from there.\n# * The binary will typically be at $GOPATH/bin/docker-machine-driver-hetzner\n# * In the source directory $GOPATH/src/github.com/\u003cyourAccount\u003e/docker-machine-driver-hetzner\n#   you may use go get to re-build the binary.\n# * Note: when you build the driver from different repositories, e.g. from your fork\n#   as well as github.com/jonasprogrammer/docker-machine-driver-hetzner,\n#   the binary files generated by these builds are all called the same\n#   and will hence override each other.\n\n# Make the binary accessible to docker-machine\n$ export GOPATH=$(go env GOPATH)\n$ export GOBIN=$GOPATH/bin\n$ export PATH=\"$PATH:$GOBIN\"\n\n# Make docker-machine output help including hetzner-specific options\n$ docker-machine create --driver hetzner\n```\n\n## Upcoming breaking changes\n\n### 4.0.0\n\n* **check log output for BREAKING-V6** (previously *BREAKING-V5*)\n* `--hetzner-user-data-from-file` will be fully deprecated and its flag description will only read 'DEPRECATED, legacy'; current fallback behaviour will be retained. `--hetzner-flag-user-data-file` should be used instead.\n* `--hetzner-disable-public-4`/`--hetzner-disable-public-6` will be fully deprecated and its flag description will only read 'DEPRECATED, legacy'; current fallback behaviour will be retained. `--hetzner-disable-public-ipv4`/`--hetzner-disable-public-ipv6` should be used instead.\n\n### 5.0.0\n\n* major update due to #108 ([hetznercloud/hcloud-go#263](https://github.com/hetznercloud/hcloud-go/v2/issues/263))\n* new `hcloud-go` v2 requiring int64 IDs is used for interaction with Hetzner cloud\n* old configs should be forward-compatible\n* newly created machines may now use 64-bit integers in all stored and transmitted data, potentially breaking existing tools supporting 32-bit only\n  - this includes anything interacting with the flags CLI via RPC, as `mcnflags` lacks an int64 flag type, so `StringFlag` and parsing are used now\n* previous changes were moved one version (i.e. 5 -\u003e 6, 6 -\u003e 7)\n\n### 6.0.0\n\n* *moved from 5.0.0*\n* `--hetzner-user-data-from-file` will be removed entirely, including its fallback behavior\n* `--hetzner-disable-public-4`/`--hetzner-disable-public-6` ill be removed entirely, including their fallback behavior\n* not specifying `--hetzner-image` will generate a warning stating 'use of default image is DEPRECATED'\n\n### 7.0.0\n\n* *moved from 6.0.0*\n* specifying `--hetzner-image` will be mandatory, and a default image will no longer be provided\n","funding_links":[],"categories":["Integrations"],"sub_categories":["Rust"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjonasprogrammer%2Fdocker-machine-driver-hetzner","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjonasprogrammer%2Fdocker-machine-driver-hetzner","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjonasprogrammer%2Fdocker-machine-driver-hetzner/lists"}