Self-Host Guide

Last Updated: September 16th, 2022.

This guide describes how to self-host Reacher using Docker 🐳. Reacher recommends the French cloud provider OVH, see the dedicated guide:Install Reacher on OVHInstall Reacher on OVH


Before self-hosting Reacher, make sure you have the permission to self-host. Unless you are an open-source developer, you most likely need to purchase a Commercial License first. Please head to πŸŽ“Reacher Licenses to learn more about the Commercial License.

πŸ’‘ Free Trial

If you wish to have a free trial before purchasing the Commercial License, it should be safe to follow this guide for a short period of time, internally and for non-commercial purposes.

🐳 Using Docker


A cloud server with Docker. You may use the platform of your choice, but make sure that the port 25 is open.

Step-by-Step Guide

The Docker image is hosted on Docker Hub: https://hub.docker.com/r/reacherhq/backend. The current stable version is v0.3.12
  1. Install Docker on your server.
      • This step depends on the provider you are using. If you are stuck on this step, please check out the documentation relative to installing Docker on your cloud provider. An example with French provider OVH can be found in Install Reacher on OVHInstall Reacher on OVH.
  1. Run docker run -p 8080:8080 -e RUST_LOG=info reacherhq/backend:v0.3.12
  1. Once set up, you're ready to do email verifications
curl -X POST \
	-H'Content-Type: application/json' \
	-d'{"to_email":"amaury@reacher.email"}' \
Since email verifications are stateless, they are well-suited for horizontally-scaling deployments, for example using Kubernetes.

Server Configuration

The server can be configured using environment variables. For the full list of configuration options, see https://github.com/reacherhq/check-if-email-exists/blob/master/backend/README.md#configuration.


How do I know if port 25 is open?

Make sure that the server itself has port 25 open AND the chosen cloud provider allows outbound port 25 connections on its network.
To test this, there are two methods :
  • Method 1: telnet
    • telnet alt1.gmail-smtp-in.l.google.com 25
      βœ… Click to see expected output when port 25 is open.
      # This means that connection to port 25 on Google's server is established.
      Connected to alt1.gmail-smtp-in.l.google.com.
      Escape character is '^]'.
      220 mx.google.com ESMTP t2-20020a056402524200b0041d70e3a2b0si10608932edd.55 - gsmtp
      # You can type 'QUIT' to quit this prompt.
      ❌ Click to see unsuccessful output.
      # This step can hang for a couple of seconds...
      telnet: Unable to connect to remote host: Connection refused
  • Method 2: curl
    • curl -sSf --verbose -k smtp://alt1.gmail-smtp-in.l.google.com:25 --ssl-reqd --mail-from test@gmail.com --mail-rcpt test@gmail.com
      βœ… Click to see expected output when port 25 is open.
      * About to connect() to alt1.gmail-smtp-in.l.google.com port 25 (#0)
      *   Trying
      * Connected to alt1.gmail-smtp-in.l.google.com ( port 25 (#0)
      < 220 mx.google.com ESMTP he11-20020a1709073d8b00b006e862100d5bsi2937572ejc.396 - gsmtp
      > EHLO reacher
      < 250-mx.google.com at your service, []
      < 250-SIZE 157286400
      < 250-8BITMIME
      < 250-STARTTLS
      < 250-PIPELINING
      < 250-CHUNKING
      < 250 SMTPUTF8
      > STARTTLS
      < 220 2.0.0 Ready to start TLS
      * Initializing NSS with certpath: sql:/etc/pki/nssdb
      * skipping SSL peer certificate verification
      * SSL connection using TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
      * Server certificate:
      * 	subject: CN=mx.google.com
      * 	start date: May 04 17:12:30 2022 GMT
      * 	expire date: Jul 27 17:12:29 2022 GMT
      * 	common name: mx.google.com
      * 	issuer: CN=GTS CA 1C3,O=Google Trust Services LLC,C=US
      > EHLO reacher
      < 250-mx.google.com at your service, []
      < 250-SIZE 157286400
      < 250-8BITMIME
      < 250-PIPELINING
      < 250-CHUNKING
      < 250 SMTPUTF8
      > MAIL FROM:<test@gmail.com>
      < 250 2.1.0 OK he11-20020a1709073d8b00b006e862100d5bsi2937572ejc.396 - gsmtp
      > RCPT TO:<test@gmail.c>
      < 550-5.1.1 The email account that you tried to reach does not exist. Please try
      < 550-5.1.1 double-checking the recipient's email address for typos or
      < 550-5.1.1 unnecessary spaces. Learn more at
      < 550 5.1.1  https://support.google.com/mail/?p=NoSuchUser he11-20020a1709073d8b00b006e862100d5bsi2937572ejc.396 - gsmtp
      * RCPT failed: 550
      > QUIT
      < 221 2.0.0 closing connection he11-20020a1709073d8b00b006e862100d5bsi2937572ejc.396 - gsmtp
      * Closing connection 0
      curl: (55) RCPT failed: 550

Which cloud providers have port 25 open?

Here are details about some of the most well-known providers:
  • ⚠️ AWS: Needs an application to open port 25, link to apply (Dec 2020).
  • ⚠️ Digital Ocean: Your account needs to be 60d old, then you can apply to open port 25 (Mar 2020).
  • ❌ GCP: Port 25 closed, source.
  • ❌ Heroku: Starting from July 2021, Heroku blocks port 25 intermittently according to this document.
  • ⚠️ Hetzner: Port 25 open according to unofficial source (Feb 2021), but seems now that you need to request manually.
  • ⚠️ Linode: Port 25 closed for new accounts, but can be opened if reverse DNS is set up correctly, source (Apr 2022).
  • βœ… OVH: Port 25 open on new instances, but outbound port 25 traffic is monitored to prevent spam (May 2022). Also see the dedicated guide Install Reacher on OVHInstall Reacher on OVH.
  • ⚠️ Vultr: Create support ticket to open port 25, source, though recent reports (May 2022) show that they won’t do it anymore.

What about IP blacklisting?

Each email verification creates a new SMTP connection to the recipient's email provider. This means that under high volume, said email provider can decide to blacklist your IP address.
One way to bypass blacklisting is to implement an IP rotation before hitting the email provider.
Reacher does NOT provide any consultation, service or advice on IP rotation. Please make your own research.

Can I use a proxy?

Yes you can.
In the API request, you can specify a proxy like so:
    "to_email": "test@gmail.com",
    "proxy": {
        "host": "",
        "port": 5001,
        "username": "mylogin",   // Optional
        "password": "mypassword" // Optional
When using proxies, you need to verify 3 things:
  1. The server on which Reacher is installed can talk to the proxy (in our case, port 5001 is open).
  1. The proxy is a SOCKS5 proxy.
  1. The proxy can make outbound port 25 connections.
Reacher does NOT provide any consultation, service or advice on proxies. Please make your own research.

How can I debug "is_reachable": "unknown"?

In most cases, if you have:
  • TimeoutError
  • "future timed out"
then it most likely means that port 25 is closed. Refer to the 1st question to debug port 25.
In other cases, you can enable the RUST_LOG=debug environment variable on your server or on your Docker container. Then, by looking at the logs when performing an email verification, you can debug why is_reachable is unknown.
Clicking on each Sentry ticket will also show the exact error message with some context, which should give you indications on why the result was "unknown"(IP blacklisting, timeouts...). Feel free to contact βœ‰οΈ amaury@reacher.email if you need help debugging these errors.

Can I build the software locally?

Yes! If you do not want to use Docker, you can compile Reacher (written in Rust) locally. For more information, see the backend’s README.

Any other questions?

Please contact βœ‰οΈ amaury@reacher.email, I’m fast to reply.