2025-09-13 09:31:05 +02:00
# hcloud-upload-image
2024-05-02 22:12:29 +02:00
2025-05-04 02:18:47 +02:00
< p align = "center" >
Quickly upload any raw disk images into your < a href = "https://hetzner.com/cloud" target = "_blank" > Hetzner Cloud< / a > projects!
< / p >
< p align = "center" >
< a href = "https://apricote.github.io/hcloud-upload-image" target = "_blank" > < img src = "https://img.shields.io/badge/Documentation-brightgreen?style=flat-square" alt = "Badge: Documentation" / > < / a >
< a href = "https://github.com/apricote/hcloud-upload-image/releases" target = "_blank" > < img src = "https://img.shields.io/github/v/release/apricote/hcloud-upload-image?sort=semver&display_name=release&style=flat-square&color=green" alt = "Badge: Stable Release" / > < / a >
< img src = "https://img.shields.io/badge/License-MIT-green?style=flat-square" alt = "Badge: License MIT" / >
< / p >
2024-05-02 22:12:29 +02:00
## About
2025-09-13 09:31:05 +02:00
The [Hetzner Cloud API ](https://docs.hetzner.cloud/ ) does not support uploading disk images directly and only provides a limited set of default images. The only option for custom disk images is to take a snapshot of an existing server’ s root disk. These snapshots can then be used to create new servers.
2024-05-04 23:56:58 +02:00
2025-09-13 09:31:05 +02:00
To create a completely custom disk image, users need to follow these steps:
2024-05-04 23:56:58 +02:00
2025-09-13 09:31:05 +02:00
1. Create a server with the correct server type
2. Enable the rescue system for the server
2024-05-04 23:56:58 +02:00
3. Boot the server
4. Download the disk image from within the rescue system
2025-09-13 09:31:05 +02:00
5. Write the disk image to the server’ s root disk
2024-05-04 23:56:58 +02:00
6. Shut down the server
2025-09-13 09:31:05 +02:00
7. Take a snapshot of the server’ s root disk
2024-05-04 23:56:58 +02:00
8. Delete the server
2025-09-13 09:31:05 +02:00
This is a frustratingly long process. Many users have automated it with [Packer ](https://www.packer.io/ ) and [`packer-plugin-hcloud` ](https://github.com/hetznercloud/packer-plugin-hcloud/ ), but Packer introduces additional complexity that can be difficult to manage.
2024-05-04 23:56:58 +02:00
2025-09-13 09:31:05 +02:00
This repository provides a simple CLI tool and Go library to streamline the process.
2024-05-04 23:56:58 +02:00
2024-05-02 22:12:29 +02:00
## Getting Started
### CLI
2024-05-04 23:56:58 +02:00
#### Binary
2024-05-10 20:01:39 +02:00
We provide pre-built `deb` , `rpm` and `apk` packages. Alternatively we also provide the binaries directly.
Check out the [GitHub release artifacts ](https://github.com/apricote/hcloud-upload-image/releases/latest ) for all of these files and archives.
2025-09-13 09:31:05 +02:00
#### Arch Linux
2024-05-10 20:01:39 +02:00
You can get [`hcloud-upload-image-bin` ](https://aur.archlinux.org/packages/hcloud-upload-image-bin ) from the AUR.
Use your preferred wrapper to install:
```shell
yay -S hcloud-upload-image-bin
```
2024-05-04 23:56:58 +02:00
#### `go install`
If you already have a recent Go toolchain installed, you can build & install the binary from source:
```shell
2024-11-02 22:21:38 +01:00
go install github.com/apricote/hcloud-upload-image@latest
2024-05-04 23:56:58 +02:00
```
2025-05-04 02:23:20 +02:00
#### Docker
There is a docker image published at `ghcr.io/apricote/hcloud-upload-image` .
```shell
docker run --rm -e HCLOUD_TOKEN="< your token > " ghcr.io/apricote/hcloud-upload-image:latest < command >
```
2024-05-04 23:56:58 +02:00
#### Usage
```shell
export HCLOUD_TOKEN="< your token > "
hcloud-upload-image upload \
--image-url "https://example.com/disk-image-x86.raw.bz2" \
--architecture x86 \
--compression bz2
```
2025-05-04 02:18:47 +02:00
To learn more, you can use the embedded help output or check out the [CLI help pages in this repository ](docs/reference/cli/hcloud-upload-image.md ).:
2024-05-04 23:56:58 +02:00
```shell
hcloud-upload-image --help
hcloud-upload-image upload --help
hcloud-upload-image cleanup --help
```
2024-05-02 22:12:29 +02:00
### Go Library
2024-05-05 01:06:38 +02:00
The functionality to upload images is also exposed in the library `hcloudimages` ! Check out the [reference documentation ](https://pkg.go.dev/github.com/apricote/hcloud-upload-image/hcloudimages ) for more details.
2024-05-04 23:56:58 +02:00
2024-05-05 01:06:38 +02:00
#### Install
2024-05-04 23:56:58 +02:00
```shell
2024-05-05 01:06:38 +02:00
go get github.com/apricote/hcloud-upload-image/hcloudimages
2024-05-04 23:56:58 +02:00
```
2024-05-05 01:06:38 +02:00
#### Usages
2024-05-04 23:56:58 +02:00
```go
package main
import (
"context"
"fmt"
"net/url"
"github.com/hetznercloud/hcloud-go/v2/hcloud"
"github.com/apricote/hcloud-upload-image/hcloudimages"
)
func main() {
client := hcloudimages.NewClient(
hcloud.NewClient(hcloud.WithToken("< your token > ")),
)
imageURL, err := url.Parse("https://example.com/disk-image-x86.raw.bz2")
if err != nil {
panic(err)
}
image, err := client.Upload(context.TODO(), hcloudimages.UploadOptions{
ImageURL: imageURL,
ImageCompression: hcloudimages.CompressionBZ2,
Architecture: hcloud.ArchitectureX86,
})
if err != nil {
panic(err)
}
fmt.Printf("Uploaded Image: %d", image.ID)
}
```
2024-05-05 00:30:23 +02:00
## Contributing
If you have any questions, feedback or ideas, feel free to open an issue or pull request.
## License
This project is licensed under the MIT license, unless the file explicitly specifies another license.
2024-05-04 23:56:58 +02:00
2024-05-02 22:12:29 +02:00
## Support Disclaimer
This is not an official Hetzner Cloud product in any way and Hetzner Cloud does not provide support for this.