Docker
Connect your app to SendMock when either of them runs in Docker, with Compose, CI and webhook examples.
See Install to start SendMock in Docker, and your language's page for the code side.
Which address to use
Inside a container, 127.0.0.1 is the container itself. Pick the row that matches where each one runs:
| Your app runs | SendMock runs | SMTP | SendMock API |
|---|---|---|---|
| on your machine | in Docker (docker run) | 127.0.0.1:1025 | http://127.0.0.1:8025 |
| in the same Compose project | in that Compose project | sendmock:1025 | http://sendmock:8025 |
| in a container | on your machine | host.docker.internal:1025 | http://host.docker.internal:8025 |
| in a CI job | as a CI service container | 127.0.0.1:1025 | http://127.0.0.1:8025 |
The examples below use Laravel's .env names (MAIL_HOST, MAIL_PORT). For other languages, put the same host and port into the settings shown on your language's page: PHP, Node.js, Python, Go, Java, Rust, Ruby, .NET.
SendMock in Docker, your app on your machine
-
Start SendMock:
docker run --rm -p 1025:1025 -p 8025:8025 ghcr.io/shibbirweb/sendmock -
Point your app at the published port. Laravel
.env:MAIL_MAILER=smtp MAIL_HOST=127.0.0.1 MAIL_PORT=1025 MAIL_ENCRYPTION=null -
Send a message from your app and open http://127.0.0.1:8025 to see it.
SendMock and your app in one Compose project
-
Add the
sendmockservice to yourcompose.yaml(create the file if you do not have one):services: sendmock: image: ghcr.io/shibbirweb/sendmock ports: - "1025:1025" - "8025:8025" volumes: - sendmock-data:/data volumes: sendmock-data: -
Start it:
docker compose up -
Open http://127.0.0.1:8025 in your browser.
With your existing app
If your app is a service in the same compose.yaml, point it at SendMock by the service name.
-
Add these lines to your app's service (here named
app, with Laravel's settings):app: environment: MAIL_MAILER: smtp MAIL_HOST: sendmock MAIL_PORT: 1025 MAIL_ENCRYPTION: "null" depends_on: sendmock: condition: service_healthy -
Start everything again:
docker compose up -
Send a message from your app and see it at http://127.0.0.1:8025.
The whole compose.yaml then looks like this:
services:
sendmock:
image: ghcr.io/shibbirweb/sendmock
ports:
- "1025:1025"
- "8025:8025"
volumes:
- sendmock-data:/data
app:
build: .
environment:
MAIL_MAILER: smtp
MAIL_HOST: sendmock
MAIL_PORT: 1025
MAIL_ENCRYPTION: "null"
depends_on:
sendmock:
condition: service_healthy
volumes:
sendmock-data:Good to know:
depends_onwithservice_healthymakes your app wait until SendMock's built-in health check passes, so the first email is not lost at start-up.- The
sendmock-datavolume keeps captured mail and SMS when the containers restart. - Symfony apps use one setting instead:
MAILER_DSN: smtp://sendmock:1025. - Other languages use the same host (
sendmock) and port (1025) in the settings on their page.
Use provider SDKs from Compose (Twilio, SendGrid, ...)
SDKs that only let you change the host talk to SendMock's provider port, 8026. It is off until you set its address.
-
Turn on the provider port in the
sendmockservice:sendmock: image: ghcr.io/shibbirweb/sendmock ports: - "1025:1025" - "8025:8025" - "8026:8026" environment: SENDMOCK_PROVIDER_ADDR: 0.0.0.0:8026 -
Set your SDK's base URL to the service name and that port:
http://sendmock:8026 -
Send a message; it shows in SMS or Mail like any other. The SMS and Mail pages list the supported providers.
Your app in a container, SendMock on your machine
Docker Desktop (macOS and Windows)
-
Start SendMock on your machine:
sendmock -
Point the app in the container at
host.docker.internal:MAIL_HOST=host.docker.internal MAIL_PORT=1025
Linux
On Linux, host.docker.internal must be added to the container, and SendMock must listen on all interfaces, because the container cannot reach your machine's 127.0.0.1.
-
Start SendMock listening on all interfaces:
sendmock serve --smtp-addr 0.0.0.0:1025 --http-addr 0.0.0.0:8025 -
Add
host.docker.internalto your app's service incompose.yaml:app: extra_hosts: - "host.docker.internal:host-gateway" environment: MAIL_HOST: host.docker.internal MAIL_PORT: 1025Or, with
docker run, add this flag:--add-host=host.docker.internal:host-gateway
Listening on all interfaces makes SendMock reachable from your network too; protect the UI as shown in Protect the UI, or use a firewall.
Send webhooks back to your app
When a rule fires, SendMock calls the endpoint URL you set in Webhooks > Endpoints. Use the address SendMock can reach from where it runs:
| SendMock runs | Your app runs | Endpoint URL example |
|---|---|---|
| in Compose | in the same Compose project (service app, port 8000) | http://app:8000/webhooks/sendmock |
| in Docker | on your machine (port 8000) | http://host.docker.internal:8000/webhooks/sendmock |
| on your machine | on your machine | http://127.0.0.1:8000/webhooks/sendmock |
On Linux, start the SendMock container with --add-host=host.docker.internal:host-gateway (or extra_hosts in Compose) for the second row. The endpoint editor warns when a URL uses localhost from inside a container.
Load a seed file
Endpoints, rules, numbers and templates can come from a seed file, so every teammate starts with the same setup.
-
Put
sendmock.seed.tomlin your project folder. -
Mount it into the
sendmockservice:sendmock: image: ghcr.io/shibbirweb/sendmock volumes: - sendmock-data:/data - ./sendmock.seed.toml:/config/sendmock.seed.toml:ro -
Restart the service; SendMock loads the file on start:
docker compose up -d sendmock
Load a config file and template files
The image also reads /config/sendmock.toml (the configuration file) and every template file in /templates (as --templates-dir does) when they are mounted.
-
Mount them into the
sendmockservice:sendmock: image: ghcr.io/shibbirweb/sendmock volumes: - sendmock-data:/data - ./sendmock.toml:/config/sendmock.toml:ro - ./webhook-templates:/templates:ro -
Restart the service:
docker compose up -d sendmock
Template files are read again when they change, so you can edit them without a restart.
Look inside a running container
The image has no shell, which keeps it small. Every tag has a -debug twin with the same SendMock on a base that has a shell (/busybox/sh), for looking around:
-
Start the debug image:
docker run -d --name sendmock-debug -p 1025:1025 -p 8025:8025 ghcr.io/shibbirweb/sendmock:beta-debug -
Open a shell in it:
docker exec -it sendmock-debug /busybox/sh
Protect the UI when ports are published
Published ports can be reached from other machines on your network. Set a username and password for the web UI and API:
sendmock:
image: ghcr.io/shibbirweb/sendmock
environment:
SENDMOCK_UI_AUTH: admin:change-meUse your own password instead of change-me.
Run SendMock in CI (GitHub Actions)
-
Add SendMock as a service container in your workflow. The runner waits for the image's health check before your steps start:
jobs: test: runs-on: ubuntu-latest services: sendmock: image: ghcr.io/shibbirweb/sendmock ports: - 1025:1025 - 8025:8025 steps: - uses: actions/checkout@v5 - name: Run the tests run: ./vendor/bin/phpunit env: MAIL_HOST: 127.0.0.1 MAIL_PORT: 1025 -
In your tests, read what the app sent through the API, for example wait up to 10 seconds for an email to an address:
curl "http://127.0.0.1:8025/api/v1/wait/[email protected]&timeout=10s"
The API reference lists every endpoint your tests can use.