Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Dns Server Bundle Laravel Package

tourze/dns-server-bundle

A Symfony bundle that integrates a DNS server into your PHP application. It provides configuration and service wiring for running DNS services, with extensible handlers for resolving queries and serving records. Suitable for custom DNS tooling and local development.

View on GitHub
Deep Wiki
Context7

Getting Started

  • Install with composer require tourze/dns-server-bundle:^0.1.0. Pin the constraint — this is a pre-1.0 package and the 0.1.0 release notes are a bare changelog link with no itemized changes, so treat the 0.0.1 → 0.1.0 delta as unknown until you diff it.
  • This is published as a Symfony bundle, not a Laravel package. There is no DnsServerServiceProvider, no config/dns.php to publish, and the bundle's DependencyInjection/Configuration.php tree is read by Symfony's config loader, not Laravel's. Expect to write a thin bridge yourself.
  • Look here first, in order:
    1. README.md — usually the only place with a runnable example for tourze packages.
    2. src/ root for the server entrypoint class (commonly DnsServer, Server, or *Kernel) and the resolver/handler interfaces.
    3. DependencyInjection/Configuration.php — the authoritative list of config keys and their defaults.
    4. Resources/config/services.yaml — shows which services are public, which are tagged, and what the constructor graph looks like.
  • First use case: stand up a throwaway local DNS on a high port and query it. Bind the server class as a singleton in a service provider, point it at 127.0.0.1:5353, and run it from php artisan tinker or a scratch command. Confirm with dig @127.0.0.1 -p 5353 example.com A +short. Do this before wiring anything into a real workflow — it validates that the constructor dependencies resolve outside a Symfony kernel.

Implementation Patterns

  • Wrap the server in an Artisan command, not a controller. Long-running listener in a web request will hit max_execution_time and hold a PHP-FPM worker hostage. A dns:serve command with $this->output->writeln() for lifecycle logging is the natural home.

  • Register as a container singleton. In a DnsServerServiceProvider:

    $this->app->singleton(DnsServer::class, fn ($app) => new DnsServer(
        host: config('dns.host', '127.0.0.1'),
        port: config('dns.port', 5353),
        // ...resolve handler/resolver deps from the container
    ));
    

    Manually mirror only the config keys you actually use from the bundle's Configuration tree into config/dns.php. Do not try to load the Symfony tree — the key shapes differ (Symfony nests under a bundle alias root, Laravel does not).

  • Handler/resolver registration via tags. Symfony bundles typically collect resolvers with ->tag('dns.resolver') and a compiler pass. In Laravel, replace that with a tagged binding ($this->app->tag([...], 'dns.resolver')) or an explicit array injected into the server. Check src/ for a compiler pass class — if one exists, that's your list of extension points, and it will silently do nothing under Laravel.

  • Zone/record data from the app, not the bundle. Keep records in Eloquent or a JSON file and have your resolver read from a repository; the bundle's job is transport and dispatch, not storage. This keeps the resolver testable without a socket.

  • Testing pattern. Two layers:

    • Unit: instantiate your resolver directly, feed it a parsed query object, assert the answer record.
    • Integration: start the server on port 5353 in setUp, shell out to dig (or send a hand-built packet over stream_socket_client), assert the wire response, then stop the loop. Always stop the loop in tearDown or the suite hangs.
  • Process supervision. Under systemd/Supervisor, or a dedicated dns container in docker-compose exposing both 53/udp and 53/tcp. Health check with dig @127.0.0.1 -p 5353 health.internal A +time=1 +tries=1.

  • Forwarding setups. If you're placing this in front of an existing resolver, chain upstream to 127.0.0.53 (systemd-resolved) or your VPC resolver and cache aggressively — a naive forwarder per query will be slower than the thing it replaced.

Gotchas and Tips

  • 0.1.0 with a one-line changelog is a red flag for silent breaks. Before upgrading from 0.0.1, git diff 0.0.1..0.1.0 -- src/ and check constructor signatures and interface methods. Pin exactly (0.1.0, not ^0.1) until you've read the diff.
  • Symfony config semantics don't transfer. Laravel's config() returns arrays with different nesting, and %env()%-style placeholders in the bundle's YAML are resolved by Symfony's container, not yours. Any env var referenced in services.yaml must be bound manually.
  • Port 53 requires privilege. In Docker use setcap cap_net_bind_service=+ep on the PHP binary or run on 5353 and redirect. Don't casually run the container as root.
  • UDP truncation is the classic bug. Responses exceeding 512 bytes need the TC bit set with a TCP retry path, or EDNS0 advertised buffer size. Verify the package handles this: dig @127.0.0.1 -p 5353 +ignore big.example.com TXT and compare to a run without +ignore. If large answers come back empty or truncated with no TC bit, clients will hang on retries.
  • Blocking loop. The server almost certainly drives a ReactPHP-style event loop. Never invoke it from a queued job or HTTP request; it does not return. Anything you need per-query must be preloaded, since you can't lazily hit the DB mid-loop without care — either eager-load zone data at boot or accept the blocking call and keep queries short.
  • Debugging toolkit. dig +noall +answer @127.0.0.1 -p 5353 name A for correctness; dig +qr to see the query; tcpdump -i lo -n udp port 5353 -X when you suspect malformed packets the client silently drops; strace -f -e trace=network -p <pid> to confirm the socket is actually bound where you think. A silent failure with no response is nearly always a bind failure or a firewall, not a resolver bug — check ss -lunp | grep 5353 first.
  • Extension points to inventory before forking. Look for interfaces under src/ — resolver/handler/middleware contracts. Bundles in this family tend to ship an abstract base class plus a chain; implement the interface rather than subclassing, since 0.x minor releases freely reshuffle abstract internals but rarely the interfaces.
  • TCP support is not guaranteed. Verify the server binds TCP as well as UDP; some minimal implementations are UDP-only, which breaks large responses and some stub resolvers outright. If UDP-only, front it with dnsdist/unbound rather than patching the loop.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
elsayed85/laravel-api-exceptions
ouhssini/laravel-demo-mode
daworks/ncloud-outbound-mailer-driver
gp247/cms
ignibyte/aic-gates
nexa-merchant/blog
novasa/laravel-language-center
opencage/geocode
adolfoholzer/parameters
livenetworks/ln-starter
shitoudev/permissionmanager
johannesclimacus/laravel-tui
hocvt/seotools
vitalybaev/sypexgeo
amphibee/themosis-ignition
gito-me/fast-excel
frankyso/laravel-ipaymu
geolize-studio/laravel-chile
boomerangui/chat
cgv/localized-resource