Preview: SendMock has no stable release yet. These docs follow develop.
SendMock
Connect your app

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 runsSendMock runsSMTPSendMock API
on your machinein Docker (docker run)127.0.0.1:1025http://127.0.0.1:8025
in the same Compose projectin that Compose projectsendmock:1025http://sendmock:8025
in a containeron your machinehost.docker.internal:1025http://host.docker.internal:8025
in a CI jobas a CI service container127.0.0.1:1025http://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

  1. Start SendMock:

    docker run --rm -p 1025:1025 -p 8025:8025 ghcr.io/shibbirweb/sendmock
  2. Point your app at the published port. Laravel .env:

    MAIL_MAILER=smtp
    MAIL_HOST=127.0.0.1
    MAIL_PORT=1025
    MAIL_ENCRYPTION=null
  3. 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

  1. Add the sendmock service to your compose.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:
  2. Start it:

    docker compose up
  3. 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.

  1. 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
  2. Start everything again:

    docker compose up
  3. 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_on with service_healthy makes your app wait until SendMock's built-in health check passes, so the first email is not lost at start-up.
  • The sendmock-data volume 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.

  1. Turn on the provider port in the sendmock service:

    sendmock:
      image: ghcr.io/shibbirweb/sendmock
      ports:
        - "1025:1025"
        - "8025:8025"
        - "8026:8026"
      environment:
        SENDMOCK_PROVIDER_ADDR: 0.0.0.0:8026
  2. Set your SDK's base URL to the service name and that port:

    http://sendmock:8026
  3. 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)

  1. Start SendMock on your machine:

    sendmock
  2. 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.

  1. Start SendMock listening on all interfaces:

    sendmock serve --smtp-addr 0.0.0.0:1025 --http-addr 0.0.0.0:8025
  2. Add host.docker.internal to your app's service in compose.yaml:

    app:
      extra_hosts:
        - "host.docker.internal:host-gateway"
      environment:
        MAIL_HOST: host.docker.internal
        MAIL_PORT: 1025

    Or, 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 runsYour app runsEndpoint URL example
in Composein the same Compose project (service app, port 8000)http://app:8000/webhooks/sendmock
in Dockeron your machine (port 8000)http://host.docker.internal:8000/webhooks/sendmock
on your machineon your machinehttp://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.

  1. Put sendmock.seed.toml in your project folder.

  2. Mount it into the sendmock service:

    sendmock:
      image: ghcr.io/shibbirweb/sendmock
      volumes:
        - sendmock-data:/data
        - ./sendmock.seed.toml:/config/sendmock.seed.toml:ro
  3. 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.

  1. Mount them into the sendmock service:

    sendmock:
      image: ghcr.io/shibbirweb/sendmock
      volumes:
        - sendmock-data:/data
        - ./sendmock.toml:/config/sendmock.toml:ro
        - ./webhook-templates:/templates:ro
  2. 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:

  1. Start the debug image:

    docker run -d --name sendmock-debug -p 1025:1025 -p 8025:8025 ghcr.io/shibbirweb/sendmock:beta-debug
  2. 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-me

Use your own password instead of change-me.

Run SendMock in CI (GitHub Actions)

  1. 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
  2. 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.

On this page