Cloudflare compatible PowerDNS API Server

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>.
Build and run
Use JDK 25. The Gradle wrapper selects the Java 25 toolchain for compilation.
bootRun activates the dev profile. Supply the environment variables below before starting the app. Tests use an in-memory H2 database and do not require MariaDB or PowerDNS.
| Variable |
Description |
DB_HOST |
MariaDB host |
DB_PORT |
MariaDB port, usually 3306 |
DB_NAME |
Database name |
DB_USER |
Database user |
DB_PASSWORD |
Database password |
PDNS_API_KEY |
PowerDNS HTTP API key |
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 |
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.
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.
Update API documentation
This task starts the app in a test context, writes the current OpenAPI 3.1 specification to openapi.json, and refreshes the generated API section below. generateOpenApi and updateReadme are also available separately. The documentation task uses H2 and does not contact PowerDNS.
API reference
Generated from openapi.json. Do not edit this section by hand.
Endpoints
Schemas
ApiResponseDTO
| Field |
Type |
Required |
Description |
success |
boolean |
No |
— |
errors |
array of ErrorOrMessage |
No |
— |
messages |
array of ErrorOrMessage |
No |
— |
result |
— |
No |
— |
ApiResponseDTODeleteResponseWithId
ApiResponseDTODomainResponseDTO
ApiResponseDTOListDomainResponseDTO
ApiResponseDTOListRecordResponseDTO
ApiResponseDTORecordResponseDTO
DeleteResponseWithId
| Field |
Type |
Required |
Description |
id |
string |
No |
— |
DomainRequestDTO
Request DTO for Domain
| Field |
Type |
Required |
Description |
name |
string |
No |
Domain name(TLD) |
DomainResponseDTO
Response DTO for Domain
| Field |
Type |
Required |
Description |
id |
string |
No |
Domain CFID |
name |
string |
No |
Domain name(TLD) |
ErrorOrMessage
| Field |
Type |
Required |
Description |
code |
integer |
No |
— |
message |
string |
No |
— |
RecordRequestDTO
Request DTO for Record
| Field |
Type |
Required |
Description |
type |
string |
No |
Record type |
name |
string |
No |
Host name |
value |
string |
No |
Record data |
ttl |
integer |
No |
TTL (Time to Live) |
priority |
integer or null |
No |
Priority |
proxied |
boolean |
No |
Proxied: cloudflare api compatibility |
comment |
string |
No |
comment |
RecordResponseDTO
Response DTO for Record
| Field |
Type |
Required |
Description |
id |
string |
No |
Record ID |
type |
string |
No |
Record type |
name |
string |
No |
Record name |
content |
string |
No |
Record content |
zoneId |
string |
No |
Zone(TLD) ID |
zoneName |
string |
No |
Zone name(TLD) |
createdOn |
string |
No |
Record creation time |
modifiedOn |
string |
No |
Record modification time |
priority |
integer or null |
No |
Record priority |
proxiable |
boolean |
No |
is proxyable: must false |
proxied |
boolean |
No |
is proxied: must false |
ttl |
integer |
No |
Record TTL |
locked |
boolean |
No |
Record is locked: must false |
comment |
string or null |
No |
Record comments |