Skip to main content

dncli

Manage your DevNomads services from the command line: inspect your services, manage DNS zones and records, and move zones over from other providers - from a shell or a script.

The command is dncli - named to avoid clashing with the macOS dnctl traffic-shaper at /usr/sbin/dnctl. Install it from PyPI as devnomads-cli.

Install

Install dncli with uv. It gives dncli its own isolated environment and puts the dncli command on your PATH:

uv tool install devnomads-cli

No uv yet? Install it first:

curl -LsSf https://astral.sh/uv/install.sh | sh                               # macOS, Linux
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"  # Windows

pipx (pipx install devnomads-cli) and pip (pip install devnomads-cli) work as well.

Updates

Upgrade with:

dncli upgrade

It uses the tool you installed dncli with (uv, pipx, or pip in a virtualenv); where it can't, such as a system-wide pip install or on Windows, it prints the command to run instead. dncli upgrade --dry-run shows what it would do.

dncli checks PyPI at most once a day and tells you when a new version is out. It only does so on an interactive terminal, never in pipes, scripts or CI; set DN_NO_UPDATE_CHECK=1 to turn it off.

dncli also warns when the DevNomads API reports a major version it was not built for, and tells you when the API no longer supports your dncli version. Update dncli in both cases.

Shell completion

Enable shell completion (bash, zsh, fish, PowerShell):

dncli --install-completion

Getting started

Create an API key in the DevNomads portal under Profiel -> API Sleutels, then store it:

dncli configure

The key is written to ~/.config/dncli/credentials, readable only by you. From here every command works:

dncli services list
dncli domains list
dncli containers show <id>

Every DevNomads product has its own command group - apps, buckets, containers, databases, domains, emails, forwards, proxies, servers, sites and more, plus keys for your SSH keys and jobs for background work. Explore with dncli --help and dncli <group> --help.

Commands accept any unambiguous prefix: dncli e l is dncli emails list. An ambiguous prefix lists the candidates.

Managing DNS

dncli dns zones list
dncli dns zones show example.com
dncli dns records list example.com
dncli dns records set example.com www A 192.0.2.1 --ttl 3600
dncli dns records delete example.com www A

Anywhere a zone is expected you may pass the service id of a domain instead of its name, so the ids from dncli domains list work here too:

dncli dns records list 42

An id always means that domain's own zone. A delegated subzone such as foo.example.com has no domain service of its own, so address it by name.

Moving a zone from another provider

dncli dns transfer copies a zone from your current DNS provider into DevNomads. It reads the records at the source (never writes there), shows you the changes, and applies them after confirmation:

dncli configure --provider transip       # store source credentials
dncli dns transfer --from transip --zone example.com --dry-run
dncli dns transfer --from transip --zone example.com

Supported source providers: TransIP and AuroraDNS. The zone must already exist at DevNomads; register or transfer the domain in the portal first.

Multiple accounts

Store each account as a named profile and select it per command or per shell:

dncli configure --profile acme
dncli services list --profile acme
export DN_PROFILE=acme

Manage stored profiles:

dncli configure list                 # profiles, with keys masked
dncli configure set-key acme         # replace a profile's API key
dncli configure delete acme          # remove a profile

set-key --stdin reads the new key from standard input, and delete --yes skips the question, for use in scripts.

Scripting

Output is a human-readable table on a terminal and JSON when piped, so pipelines get parseable output without any flags; --out table|json|csv|tsv forces a specific format. Data goes to stdout, everything else (warnings, prompts, status messages) to stderr, so dncli ... | jq . is always safe.

The csv and tsv formats use the same columns as the table view, so dncli servers list --out csv is ready for a spreadsheet.

List tables show a focused set of columns: fields that are empty for every row, and nested collections (a server's IPs, a container's instances, a mailbox list) are left out of the overview. Use <group> show <id> or --out json for the complete record.

To pick exactly the columns you want, pass --columns (-c) a comma-separated list, e.g. dncli services list -c entity,started_at. It applies to every format, projecting json and csv/tsv to just those fields, and reports an error on an unknown column name.

Commands that take a service id also accept a unique entity name and resolve it for you, so dncli domains show example.com works as well as dncli domains show 1234. Names match regardless of case. A purely numeric value is always treated as an id; an entity that matches more than one service is rejected, so pass the id when an entity is not unique. Other references, such as cluster, key or user ids, take the numeric id only.

Some changes run in the background: creating a site, server, proxy or domain, for example, queues one or more jobs in a batch. Such a command prints the queued jobs and returns right away; add --wait to follow the batch until every job has finished and see how each one ended. With --wait the exit status is 0 only when every job completed. You can look a batch up later with dncli jobs batches show <batch_id>.

The exit status is 0 when the API accepted the request and 1 for any error response, so dncli ... && next-step is safe in scripts. Every command takes --timeout <seconds> (default 300) for how long to wait for the API, including the time spent waiting on --wait.

In CI and pipelines, skip the credentials file and pass the key via the environment:

export DN_API_KEY=...        # beats any stored profile
dncli services list | jq -r '.[].entity'

AI agents

dncli ships with a skill that teaches AI coding agents how to use it safely: where ids come from, what costs money or deletes data, and to ask before changing anything. It works with Claude Code, Codex, Gemini CLI, GitHub Copilot, Cursor and OpenCode:

dncli skill install                      # every agent found on this machine
dncli skill install --agent codex        # a specific agent; repeat for more
dncli skill install --project            # into the current project instead

Run it again after upgrading dncli to update the skill; dncli skill show prints it.

Certificates

dncli issues Let's Encrypt certificates using the DNS-01 challenge:

dncli certs issue example.com -d www.example.com --wildcard

The first argument is the primary domain (the certificate CN); add extra names (SANs) by repeating --san/-d. --wildcard/-w is a shortcut that adds *.<domain> as a SAN - a wildcard is never accepted as the CN itself. Every name must live in one of your DevNomads DNS zones, and that zone must be delegated to the DevNomads nameservers (one.dns.infrapod.nl, two.dns.infrapod.nl, three.dns.infrapod.eu) - otherwise issuance is refused, since the DNS-01 challenge records would not be visible to the CA.

The certificate is always written to ~/.config/dncli/certs/<domain>/ as cert.pem, fullchain.pem, chain.pem, and privkey.pem (0600). Pass --out <file> to additionally export a single PEM bundle of the key, the certificate, and the full chain (intermediate plus any cross-signed roots), in that order. Add -v/--verbose for detailed ACME progress.

Keys are ECDSA P-384 by default. Pick another with --key-type (ecdsa256, ecdsa384, ecdsa521, rsa2048, rsa4096).

Let's Encrypt is the certificate authority by default. Pass --provider zerossl to use ZeroSSL instead. ZeroSSL requires External Account Binding credentials (create an EAB key pair in the ZeroSSL dashboard under Developer > EAB Credentials), supplied with --eab-kid and --eab-hmac-key or the DN_ZEROSSL_EAB_KID and DN_ZEROSSL_EAB_HMAC_KEY environment variables:

dncli certs issue example.com --provider zerossl \
  --eab-kid <kid> --eab-hmac-key <hmac>

--staging (the Let's Encrypt staging CA) applies only to the letsencrypt provider. certs renew takes the same --provider and EAB options.

Each CA gets its own ACME account: the key lives in ~/.config/dncli/acme/ as account.pem for Let's Encrypt production and account-<provider>.pem for ZeroSSL and the staging CA.

Re-running certs issue is a no-op while the existing certificate is still valid for more than 21 days; pass --force to re-issue anyway.

List what you have issued and re-export any of them - as a PEM bundle or a PKCS#12 (.pfx) file - without re-issuing. certs list includes a provider column showing the issuing CA (recorded at issue time, or inferred from the certificate's issuer for older certificates):

dncli certs list
dncli certs export example.com --out bundle.pem    # omit --out to print
dncli certs export example.com --format pfx --out bundle.pfx
dncli certs export example.com --format pfx --out bundle.pfx --passphrase secret

The .pfx is unencrypted unless you pass --passphrase (alias --password). Both bundle formats carry the same items: key, certificate, and the full chain. The chain includes the cross-signs: with Let's Encrypt's current hierarchy the path to a trusted root runs through the intermediate (e.g. YE2), Root YE (cross-signed by ISRG Root X2) and ISRG Root X2 (cross-signed by ISRG Root X1).

dncli certs delete <domain> removes a stored certificate and its private key from disk (after confirmation; --yes skips it). By default it only deletes the local files; add --revoke to also revoke the certificate at the CA that issued it (the files are kept if revocation fails).

A dehydrated-compatible DNS-01 hook ships as dncli-dns-hook:

# dehydrated/config
CHALLENGETYPE="dns-01"
HOOK="dncli-dns-hook"

License

MIT.

Metadata

Release files for devnomads-cli 0.12.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for devnomads-cli 0.12.1
File Size Uploaded Provenance
devnomads_cli-0.12.1.tar.gz 86.7 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for devnomads-cli 0.12.1
File Interpreter ABI Platform
devnomads_cli-0.12.1-py3-none-any.whl Python 3 none any Details

Total release size: 146.9 kB

Release files / devnomads_cli-0.12.1.tar.gz

Download URL devnomads_cli-0.12.1.tar.gz
Size 86.7 kB
Tags Source
SHA-256 checksum
How to use checksums
1e6bf883b8c17209713d29adf3c873308a0898d3f5b92bb162a6a4127ddf4f17
BLAKE2b-256 checksum
How to use checksums
f317496fa874a3dd17c1779aa4ada5380ac872a0ecd33b6bf87f750f7e7664e0
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.13.1 {"installer":{"name":"uv","version":"0.13.1","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Alpine Linux","version":"3.23.6","id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / devnomads_cli-0.12.1-py3-none-any.whl

Download URL devnomads_cli-0.12.1-py3-none-any.whl
Size 60.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
fd093eb4c7cc8526cc79000c89f1dd0cf26c556ad12344c665f738f99bdceb2b
BLAKE2b-256 checksum
How to use checksums
58eaa60c6130ba6865ce2780f62541ef4a806ecd5164b205f8b700d48d847437
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.13.1 {"installer":{"name":"uv","version":"0.13.1","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Alpine Linux","version":"3.23.6","id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Security for devnomads-cli 0.12.1

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page