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 constantsHow 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"andcaddy.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; supportsstdin.defaultLoader— falls back to readingCorefilefrom the working directory.
- Sets
caddy.AppName = "CoreDNS"andcaddy.AppVersion = CoreVersion(coremain/version.go).
coremain.Run
The Run function is CoreDNS's main() body:
caddy.TrapSignals()— install handlers for SIGINT, SIGTERM, SIGUSR1.flag.Parse()and reject any positional arguments.log.SetOutput(os.Stdout);log.SetFlags(LogFlags).- Handle
-versionand-pluginsand exit. maxprocs.Setfromgo.uber.org/automaxprocs— adjust GOMAXPROCS to the cgroup CPU limit (mostly relevant in containers).caddy.LoadCaddyfile("dns")— invokes the registered loaders to obtain the Corefile bytes.caddy.Start(corefile)— parses, validates, and starts the servers. Internally this callsdnsContext.InspectServerBlocksandMakeServersfrom DNS server.showVersion()if not-quiet.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:
GitCommit—git describe --dirty --alwaysoutput.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/pluginis the generated file; ifmake genis skipped, no plugins are registered. - DNS server type. Registered in
core/dnsserver/register.go. The bootstrap doesn't referencednsserverdirectly — it just callscaddy.LoadCaddyfile("dns"), where the string"dns"matches the type registered bydnsserver.init(). See DNS server.
Entry points for modification
- Adding a new flag →
coremain/run.go init(). - Changing the version banner format →
versionString/releaseStringincoremain/run.go. - A new build-time variable injected via
-ldflags→ declare it undervar (...)near the bottom ofrun.goand add it toSTRIP_FLAGS/LDFLAGSin the Makefile. - Bumping
CoreVersion→coremain/version.go. Coordinate withMakefile.releaseand the release notes undernotes/.
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.