mirror of
https://github.com/dalbodeule/sh0rt.kr-pdns.git
synced 2026-11-05 22:29:34 +09:00
feat: Add multi-architecture Docker image build script and update README
This commit is contained in:
3 files changed
+108
-6
No files matched your search
@@ -1,6 +1,6 @@
|
|||||||
# Cloudflare compatible PowerDNS API Server
|
# Cloudflare compatible PowerDNS API Server
|
||||||
|
|
||||||
[](https://discord.gg/EPnCfz7xx5) [](https://teamcity.mori.space/project/PdnsApi)
|
[](https://discord.gg/EPnCfz7xx5)
|
||||||
|
|
||||||
A Kotlin and Spring Boot API that exposes Cloudflare-style zone and DNS record endpoints backed by PowerDNS and MariaDB. API requests use `Authorization: Bearer <API_KEY>`.
|
A Kotlin and Spring Boot API that exposes Cloudflare-style zone and DNS record endpoints backed by PowerDNS and MariaDB. API requests use `Authorization: Bearer <API_KEY>`.
|
||||||
|
|
||||||
@@ -26,6 +26,23 @@ Use JDK 25. The Gradle wrapper selects the Java 25 toolchain for compilation.
|
|||||||
| `PDNS_API_URL` | PowerDNS HTTP API base URL, for example `http://pdns:8081` |
|
| `PDNS_API_URL` | PowerDNS HTTP API base URL, for example `http://pdns:8081` |
|
||||||
| `PDNS_NS` | Comma-separated nameservers, for example `ns1.example.com,ns2.example.com` |
|
| `PDNS_NS` | Comma-separated nameservers, for example `ns1.example.com,ns2.example.com` |
|
||||||
|
|
||||||
|
## Publish AMD64 and ARM64 images
|
||||||
|
|
||||||
|
The script builds a Linux native image for each architecture with Paketo Buildpacks, pushes the architecture-specific tags with Docker CLI credentials, then publishes a multi-platform manifest. Docker, Buildx, and a registry login with push access to the target repository are required. On a host with a different architecture, Docker must support emulation for the target platform.
|
||||||
|
|
||||||
|
```sh
|
||||||
|
./scripts/build-multiarch-image.sh 1.0.0
|
||||||
|
```
|
||||||
|
|
||||||
|
The default repository is `${DOCKER_USERNAME:-dalbodeule}/dnsapi`. Set `IMAGE_REPOSITORY` to use another repository, such as `git.mori.space/dalbodeule/dnsapi`. The script publishes `:1.0.0-amd64`, `:1.0.0-arm64`, `:1.0.0`, and `:latest`; set `PUBLISH_LATEST=0` to leave `:latest` unchanged. Review the commands without publishing by setting `DRY_RUN=1`.
|
||||||
|
|
||||||
|
If a previous run built an architecture image locally but failed while pushing, log in to the registry and rerun with `RESUME=1`. The script checks the local image architecture and skips its costly rebuild.
|
||||||
|
|
||||||
|
```sh
|
||||||
|
docker login --username dalbodeule
|
||||||
|
RESUME=1 ./scripts/build-multiarch-image.sh 1.0.0
|
||||||
|
```
|
||||||
|
|
||||||
## Update API documentation
|
## Update API documentation
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
|
|||||||
+11
-5
@@ -97,18 +97,24 @@ tasks.register("updateDocs") {
|
|||||||
|
|
||||||
tasks.withType<BootBuildImage> {
|
tasks.withType<BootBuildImage> {
|
||||||
val dockerId = System.getenv("DOCKER_USERNAME") ?: "dalbodeule"
|
val dockerId = System.getenv("DOCKER_USERNAME") ?: "dalbodeule"
|
||||||
val dockerPw = System.getenv("DOCKER_PASSWORD") ?: ""
|
val dockerPw = System.getenv("DOCKER_PASSWORD")
|
||||||
|
|
||||||
docker {
|
docker {
|
||||||
publish = true
|
publish = true
|
||||||
publishRegistry {
|
if (!dockerPw.isNullOrBlank()) {
|
||||||
username = dockerId
|
publishRegistry {
|
||||||
password = dockerPw
|
username = dockerId
|
||||||
|
password = dockerPw
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
imageName.set("$dockerId/dnsapi")
|
imageName.set("$dockerId/dnsapi")
|
||||||
tags.set(setOf("$dockerId/dnsapi:latest", "$dockerId/dnsapi:${datetimeFormatter.format(LocalDateTime.now())}"))
|
if (providers.gradleProperty("multiArchImage").orNull == "true") {
|
||||||
|
tags.set(emptySet<String>())
|
||||||
|
} else {
|
||||||
|
tags.set(setOf("$dockerId/dnsapi:latest", "$dockerId/dnsapi:${datetimeFormatter.format(LocalDateTime.now())}"))
|
||||||
|
}
|
||||||
buildpacks.set(setOf("docker.io/paketobuildpacks/oracle", "urn:cnb:builder:paketo-buildpacks/java-native-image"))
|
buildpacks.set(setOf("docker.io/paketobuildpacks/oracle", "urn:cnb:builder:paketo-buildpacks/java-native-image"))
|
||||||
|
|
||||||
environment = mapOf(
|
environment = mapOf(
|
||||||
|
|||||||
Executable
+79
@@ -0,0 +1,79 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
usage() {
|
||||||
|
echo "Usage: $0 <image-tag>" >&2
|
||||||
|
echo "Set IMAGE_REPOSITORY to override the default repository." >&2
|
||||||
|
exit 2
|
||||||
|
}
|
||||||
|
|
||||||
|
if [[ $# -ne 1 ]]; then
|
||||||
|
usage
|
||||||
|
fi
|
||||||
|
|
||||||
|
tag=$1
|
||||||
|
if [[ ! $tag =~ ^[A-Za-z0-9_][A-Za-z0-9_.-]{0,121}$ ]]; then
|
||||||
|
echo "Invalid Docker image tag: $tag" >&2
|
||||||
|
exit 2
|
||||||
|
fi
|
||||||
|
|
||||||
|
repository=${IMAGE_REPOSITORY:-${DOCKER_USERNAME:-dalbodeule}/dnsapi}
|
||||||
|
publish_latest=${PUBLISH_LATEST:-1}
|
||||||
|
dry_run=${DRY_RUN:-0}
|
||||||
|
resume=${RESUME:-0}
|
||||||
|
root_dir=$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)
|
||||||
|
|
||||||
|
if [[ $publish_latest != 0 && $publish_latest != 1 ]]; then
|
||||||
|
echo "PUBLISH_LATEST must be 0 or 1" >&2
|
||||||
|
exit 2
|
||||||
|
fi
|
||||||
|
if [[ $dry_run != 0 && $dry_run != 1 ]]; then
|
||||||
|
echo "DRY_RUN must be 0 or 1" >&2
|
||||||
|
exit 2
|
||||||
|
fi
|
||||||
|
if [[ $resume != 0 && $resume != 1 ]]; then
|
||||||
|
echo "RESUME must be 0 or 1" >&2
|
||||||
|
exit 2
|
||||||
|
fi
|
||||||
|
if [[ $dry_run == 0 ]]; then
|
||||||
|
command -v docker >/dev/null || { echo "Docker is required" >&2; exit 1; }
|
||||||
|
docker buildx version >/dev/null
|
||||||
|
fi
|
||||||
|
|
||||||
|
run() {
|
||||||
|
if [[ $dry_run == 1 ]]; then
|
||||||
|
printf 'DRY RUN:'
|
||||||
|
printf ' %q' "$@"
|
||||||
|
printf '\n'
|
||||||
|
else
|
||||||
|
"$@"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
cd "$root_dir"
|
||||||
|
for arch in amd64 arm64; do
|
||||||
|
image="$repository:$tag-$arch"
|
||||||
|
if [[ $resume == 1 && $dry_run == 0 ]] && docker image inspect "$image" >/dev/null 2>&1; then
|
||||||
|
actual_platform=$(docker image inspect "$image" --format '{{.Os}}/{{.Architecture}}')
|
||||||
|
if [[ $actual_platform != "linux/$arch" ]]; then
|
||||||
|
echo "$image has platform $actual_platform, expected linux/$arch" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
echo "Reusing local image $image"
|
||||||
|
else
|
||||||
|
run ./gradlew bootBuildImage \
|
||||||
|
-PmultiArchImage=true \
|
||||||
|
"--imagePlatform=linux/$arch" \
|
||||||
|
"--imageName=$image" \
|
||||||
|
--no-publishImage
|
||||||
|
fi
|
||||||
|
run docker push "$image"
|
||||||
|
done
|
||||||
|
|
||||||
|
manifest_args=(docker buildx imagetools create --tag "$repository:$tag")
|
||||||
|
if [[ $publish_latest == 1 ]]; then
|
||||||
|
manifest_args+=(--tag "$repository:latest")
|
||||||
|
fi
|
||||||
|
manifest_args+=("$repository:$tag-amd64" "$repository:$tag-arm64")
|
||||||
|
run "${manifest_args[@]}"
|
||||||
|
run docker buildx imagetools inspect "$repository:$tag"
|
||||||
Reference in new issue
Block a user