inspiredminds/symfony-mailer-command-bundle
A Symfony bundle that adds console commands for testing and debugging Symfony Mailer setups. Send test emails straight from the CLI to verify transports, DSNs, and delivery without writing throwaway code—handy for local development and post-deployment checks.
Install the bundle:
composer require inspiredminds/symfony-mailer-command-bundle
If you don't use Symfony Flex, register it manually in config/bundles.php:
return [
// ...
InspiredMinds\SymfonyMailerCommandBundle\SymfonyMailerCommandBundle::class => ['all' => true],
];
Make sure the Symfony Mailer is configured. The bundle does not ship a transport of its own — it sends through whatever your app already has:
# .env.local
MAILER_DSN=smtp://localhost:1025
# config/packages/mailer.yaml
framework:
mailer:
dsn: '%env(MAILER_DSN)%'
Discover the command:
bin/console list mailer
bin/console mailer:send --help
Read --help first — option names (--from, --to, --subject, --body, transport selection, etc.) are the contract you'll script against.
Note on 1.0.2: the bundle now allows much newer Symfony versions. On Symfony releases that ship the core mailer:test command you will see two mail commands in list mailer. That is expected — they are not equivalent (see below). Check what actually resolved in your lock file, because the relaxed constraint means two environments can now install this bundle against very different Symfony majors:
composer show inspiredminds/symfony-mailer-command-bundle
composer why symfony/framework-bundle
First use case: send a one-off smoke-test message after setting up MAILER_DSN to prove credentials, TLS, and the envelope are correct before wiring mail into application code:
bin/console mailer:send \
[email protected] \
[email protected] \
--subject="Mailer smoke test" \
--body="If you can read this, the DSN works."
If that lands, your framework.mailer config is sound and any later failure is application-level, not infrastructure.
mailer:send vs. core mailer:test — pick deliberately. Since 1.0.2 the bundle is installable on Symfony versions that provide mailer:test. The distinction the maintainer calls out matters in practice:
mailer:test drives mailer.transports directly — it bypasses the mailer service, so it does not exercise Messenger routing, mailer events, or any decorator/override you registered on the mailer service.mailer:send (this bundle) goes through the mailer service — the same path your application code takes, including Messenger handoff and event listeners.Use mailer:send when you want to validate your application's mail wiring; use mailer:test when you want to validate a raw transport/DSN in isolation.
Post-deploy / CI smoke test. Run the command against a dedicated inbox in a deploy pipeline or health check. Exit non-zero should fail the job:
bin/console mailer:send [email protected] [email protected] \
--subject="Deploy $(git rev-parse --short HEAD)" --body="ok" --no-interaction
Debugging local delivery with Mailpit/Mailhog. Point MAILER_DSN at the catcher and send via the command — faster than exercising a registration flow just to see whether mail is produced:
MAILER_DSN=smtp://127.0.0.1:1025
Verifying a specific transport. If you define multiple transports under framework.mailer.transports, use the command to target one explicitly (e.g. a ses transport alongside the default smtp) so you can validate each provider independently rather than only the default. Check --help for the exact transport-selection flag name in your version.
Operational notifications from cron/systemd. For plain-text alerts from shell scripts, the command is a legitimate sendmail-style replacement:
bin/console mailer:send [email protected] [email protected] \
--subject="Disk usage critical" --body="$(df -h | tail -n +1)" \
--no-interaction >/dev/null
Guard it behind an app-level check so you never spam on flapping conditions.
Programmatic invocation inside a real console command. When you want a richer email than the CLI accepts (attachments, HTML, Twig-rendered body), don't shell out — build an Email in your own command and inject MailerInterface. Use mailer:send only as the "no-template, raw text" tool.
Extending/overriding behavior. The command is registered as a service, so you can override it in config/services.yaml (same service id, class: pointing at your subclass) or decorate the underlying transport. This is the cleanest extension point if you need default --from values or a --dry-run flag.
Async transports. If your DSN routes through Messenger (e.g. doctrine://default), the command returns success once the message is queued, not delivered. Pair the smoke test with a worker check (bin/console messenger:consume) when validating that path. Note this is exactly the scenario mailer:test cannot cover — it hits transports directly and never enqueues — which is the bundle's main remaining reason to exist on modern Symfony.
Upgrade testing after the 1.0.2 constraint relaxation. Because the Symfony constraint was widened, composer update can silently move this bundle from "installed alongside Symfony 5.x" to "installed alongside a current major" without any code change of yours. Add a smoke-test run of mailer:send to your Symfony upgrade checklist, and keep the --help output assertion (or a scripted invocation) in CI so an option-name change between Symfony generations fails loudly.
mailer:test on newer Symfony. Since 1.0.2 you may be installing a bundle that duplicates a first-party command. The maintainer's own justification is that this sends via the mailer service rather than mailer.transports — verify that distinction actually matters for you (Messenger routing, event listeners, mailer decorators). If it doesn't, prefer the built-in command and drop the dependency.composer.lock committed, pin the bundle to an exact version, and make sure your CI matrix actually runs the Symfony version you deploy.composer.json, read the handful of source files (the whole package is small enough to audit in minutes), and be prepared to maintain a fork. There is no meaningful community support surface. The bundle's long-term relevance now also depends on whether Symfony's own mail commands close the gap.--from, expect a transport-level error rather than a friendly validation message.@, /, ?, #) must be URL-encoded in MAILER_DSN. A malformed DSN typically surfaces as a connection failure, not a parse error — check with bin/console debug:config framework mailer.MailerInterface and composes an Email.|| true in cron wrappers or you'll silently lose alerts..env. Standard Symfony advice, but especially relevant here since the command is often run from deploy scripts where .env files get copied around.bin/console debug:container mailer to confirm the mailer is wired, bin/console debug:config framework mailer to inspect the active DSN/transports, and add -v/-vv to the command to surface transport responses where supported.--dry-run out of the box. If you want validation without delivery, override the command or point MAILER_DSN at a local catcher transport. Note the same applies to mailer:test — it sends for real.How can I help you explore Laravel packages today?