Open-Source Wikis

/

CoreDNS

/

Systems

/

Caddy bootstrap

coredns/coredns

Caddy bootstrap

Active contributors: miekg, chrisohaver, johnbelamaric

Purpose

The bootstrap layer is the small amount of code that turns the coredns binary into a running DNS server. It registers all plugins, parses the Corefile, and hands control to Caddy. After this layer finishes, every interesting decision is made inside core/dnsserver or a plugin.

Directory layout

.
├── coredns.go              # main(): blank-import plugins, call coremain.Run
└── coremain/
    ├── run.go              # flag parsing, Corefile loading, caddy.Start
    ├── service_other.go    # POSIX runService stub
    ├── service_windows.go  # Windows service registration
    └── version.go          # CoreVersion, CoreName, serverType constants

How it works

graph TD
    A[main]
    A --> B[blank import core/plugin]
    B -->|init() side effects| C[plugin.Register / caddy.RegisterPlugin]
    A --> D[coremain.Run]
    D --> E[init: caddy.RegisterCaddyfileLoader, flag.StringVar]
    D --> F[caddy.TrapSignals]
    D --> G[flag.Parse]
    G --> H{-version or -plugins?}
    H -->|yes| I[print and exit]
    H -->|no| J[maxprocs.Set]
    J --> K[caddy.LoadCaddyfile dns]
    K --> L[caddy.Start]
    L --> M[runService]

coredns.go

The whole binary is six lines:

package main

import (
    _ "github.com/coredns/coredns/core/plugin" // Plug in CoreDNS.
    "github.com/coredns/coredns/coremain"
)

func main() { coremain.Run() }

Two go:generate directives at the top of coredns.go reference directives_generate.go and owners_generate.go. make gen runs them.

The blank import of core/plugin resolves to a generated file (core/plugin/zplugin.go) that blank-imports every plugin listed in plugin.cfg. Each plugin's init() registers itself with the Caddy plugin registry — caddy.RegisterPlugin under the hood — so MakeServers can instantiate it.

coremain.init

Defined in coremain/run.go, runs before Run:

  • Sets caddy.DefaultConfigFile = "Corefile" and caddy.Quiet = true.
  • Calls setVersion() (see below) to compute the version string from -ldflags-injected variables.
  • Registers command-line flags: -conf, -plugins, -pidfile, -version, -quiet, -dns.port, -p.
  • Registers two Caddyfile loaders:
    • confLoader — invoked when -conf <file> is passed; supports stdin.
    • defaultLoader — falls back to reading Corefile from the working directory.
  • Sets caddy.AppName = "CoreDNS" and caddy.AppVersion = CoreVersion (coremain/version.go).

coremain.Run

The Run function is CoreDNS's main() body:

  1. caddy.TrapSignals() — install handlers for SIGINT, SIGTERM, SIGUSR1.
  2. flag.Parse() and reject any positional arguments.
  3. log.SetOutput(os.Stdout); log.SetFlags(LogFlags).
  4. Handle -version and -plugins and exit.
  5. maxprocs.Set from go.uber.org/automaxprocs — adjust GOMAXPROCS to the cgroup CPU limit (mostly relevant in containers).
  6. caddy.LoadCaddyfile("dns") — invokes the registered loaders to obtain the Corefile bytes.
  7. caddy.Start(corefile) — parses, validates, and starts the servers. Internally this calls dnsContext.InspectServerBlocks and MakeServers from DNS server.
  8. showVersion() if not -quiet.
  9. runService(instance) — POSIX: instance.Wait(). Windows: register a service control handler.

Version metadata

coremain/version.go hard-codes CoreVersion = "1.14.3". Additional metadata is injected at link time via -ldflags in the Makefile:

  • GitCommitgit describe --dirty --always output.
  • gitTag, gitNearestTag, gitShortStat, gitFilesModified, buildDate — set by the release pipeline (Makefile.release).

setVersion() computes a development version string of the form 1.14.3 (+abc123 2026-04-30) for unreleased builds. showVersion() prints <AppName>-<AppVersion> plus <OS>/<ARCH>, <go version>, <commit>.

Service handling

File Behavior
coremain/service_other.go runService(instance) calls instance.Wait().
coremain/service_windows.go Registers as a Windows service via golang.org/x/sys/windows/svc. Falls back to console mode when run interactively.

Key abstractions

Symbol File Description
Run coremain/run.go Entry point invoked by coredns.go:main
confLoader, defaultLoader coremain/run.go Caddyfile loaders for -conf and the default Corefile
setVersion, showVersion coremain/run.go Compute and print the version banner
mustLogFatal coremain/run.go Routes fatal errors to stderr (or to the Caddy log on graceful upgrade)
runService coremain/service_*.go OS-specific run loop
CoreVersion, CoreName, serverType coremain/version.go Compile-time constants

Integration points

  • Caddy. All meaningful work is delegated to github.com/coredns/caddy. CoreDNS embeds a fork of Caddy v1.
  • Generated plugin imports. The blank import path github.com/coredns/coredns/core/plugin is the generated file; if make gen is skipped, no plugins are registered.
  • DNS server type. Registered in core/dnsserver/register.go. The bootstrap doesn't reference dnsserver directly — it just calls caddy.LoadCaddyfile("dns"), where the string "dns" matches the type registered by dnsserver.init(). See DNS server.

Entry points for modification

  • Adding a new flag → coremain/run.go init().
  • Changing the version banner format → versionString / releaseString in coremain/run.go.
  • A new build-time variable injected via -ldflags → declare it under var (...) near the bottom of run.go and add it to STRIP_FLAGS/LDFLAGS in the Makefile.
  • Bumping CoreVersioncoremain/version.go. Coordinate with Makefile.release and the release notes under notes/.

Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.

Caddy bootstrap – CoreDNS wiki | Factory