Issues sending emails

Hi,

I’ve been setting up a self-hosted Baserow instance on an Ubuntu 20.04 server, it all works except for the SMTP connection as it fails to send emails out.

Here are my Config Variables:
EMAIL_SMTP=‘TRUE’,
EMAIL_SMTP_HOST=‘smtp.gmail.com’,
EMAIL_SMTP_USE_TLS=‘TRUE’,
EMAIL_SMTP_PORT=587,
EMAIL_SMTP_USER=‘my@email.com’,
EMAIL_SMTP_PASSWORD=‘mypassword’,
FROM_EMAIL=‘my@email.com’

I’ve tested the user and password which can use the smtp server to send emails.

I did some digging in the worker errors and it appears to be an issue with something internally?
The error is:

[2022-02-03 11:56:24,278: ERROR/ForkPoolWorker-2] djcelery_email_send_multiple[e7a4b733-3af5-4ee1-aab7-128501657989]: Cannot reach CELERY_EMAIL_BACKEND django.core.mail.backends.smtp.EmailBackend
Traceback (most recent call last):
  File "/baserow/env/lib/python3.7/site-packages/djcelery_email/tasks.py", line 40, in send_emails
    conn.open()
  File "/baserow/env/lib/python3.7/site-packages/django/core/mail/backends/smtp.py", line 62, in open
    self.connection = self.connection_class(self.host, self.port, **connection_params)
  File "/usr/lib/python3.7/smtplib.py", line 251, in __init__
    (code, msg) = self.connect(host, port)
  File "/usr/lib/python3.7/smtplib.py", line 336, in connect
    self.sock = self._get_socket(host, port, self.timeout)
  File "/usr/lib/python3.7/smtplib.py", line 307, in _get_socket
    self.source_address)
  File "/usr/lib/python3.7/socket.py", line 728, in create_connection
    raise err
  File "/usr/lib/python3.7/socket.py", line 716, in create_connection
    sock.connect(sa)
TimeoutError: [Errno 110] Connection timed out

I tried to have a look at the python files but I don’t have loads of experience with python so it wasn’t much help.

Has anyone else run into this issue & has a solution?

Thanks in advance!

Hi @JB-Dev ,

This error to me looks like Baserow is failing to connect to the configured SMTP server for some reason.

Just to double check how are you setting those config variables for Baserow to use (which file are you changing exactly etc)?

Otherwise we can try debugging this further by doing the following:

cd /baserow
source env/bin/activate
export DJANGO_SETTINGS_MODULE='baserow.config.settings.base'
export EMAIL_SMTP='TRUE'
export EMAIL_SMTP_HOST='smtp.gmail.com'
export EMAIL_SMTP_USE_TLS='TRUE'
export EMAIL_SMTP_PORT=587
export EMAIL_SMTP_USER='my@email.com'
export EMAIL_SMTP_PASSWORD='mypassword'
export FROM_EMAIL='my@email.com'
baserow shell

Now try copy and pasting the following into the newly opened baserow shell after replacing the REPLACE_WITH_TO_EMAIL_ADDRESS with the email address you want to test sending an email to.

from django.core.mail import EmailMessage
from django.conf import settings

email = EmailMessage(
    'title',
    'msg',
    settings.FROM_EMAIL,
    ['REPLACE_WITH_TO_EMAIL_ADDRESS'],
)
email.send(fail_silently=False)

Once the above has run in the baserow shell do you get any error messages?

Hi @nigel

Thanks for getting back to me,

Any edits to config variables are happening in “/etc/supervisor/conf.d/baserow.conf” believe thats the correct location.

Just followed your steps and got this Traceback:

Traceback (most recent call last):
  File "/baserow/env/lib/python3.7/site-packages/kombu/utils/functional.py", line 30, in __call__
    return self.__value__
AttributeError: 'ChannelPromise' object has no attribute '__value__'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/baserow/env/lib/python3.7/site-packages/kombu/transport/virtual/base.py", line 923, in create_channel
    return self._avail_channels.pop()
IndexError: pop from empty list

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/baserow/env/lib/python3.7/site-packages/redis/connection.py", line 608, in connect
    lambda: self._connect(), lambda error: self.disconnect(error)
  File "/baserow/env/lib/python3.7/site-packages/redis/retry.py", line 45, in call_with_retry
    return do()
  File "/baserow/env/lib/python3.7/site-packages/redis/connection.py", line 608, in <lambda>
    lambda: self._connect(), lambda error: self.disconnect(error)
  File "/baserow/env/lib/python3.7/site-packages/redis/connection.py", line 642, in _connect
    self.host, self.port, self.socket_type, socket.SOCK_STREAM
  File "/usr/lib/python3.7/socket.py", line 752, in getaddrinfo
    for res in _socket.getaddrinfo(host, port, family, type, proto, flags):
socket.gaierror: [Errno -3] Temporary failure in name resolution

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/baserow/env/lib/python3.7/site-packages/kombu/connection.py", line 447, in _reraise_as_library_errors
    yield
  File "/baserow/env/lib/python3.7/site-packages/kombu/connection.py", line 438, in _ensure_connection
    callback, timeout=timeout
  File "/baserow/env/lib/python3.7/site-packages/kombu/utils/functional.py", line 312, in retry_over_time
    return fun(*args, **kwargs)
  File "/baserow/env/lib/python3.7/site-packages/kombu/connection.py", line 878, in _connection_factory
    self._connection = self._establish_connection()
  File "/baserow/env/lib/python3.7/site-packages/kombu/connection.py", line 813, in _establish_connection
    conn = self.transport.establish_connection()
  File "/baserow/env/lib/python3.7/site-packages/kombu/transport/virtual/base.py", line 947, in establish_connection
    self._avail_channels.append(self.create_channel(self))
  File "/baserow/env/lib/python3.7/site-packages/kombu/transport/virtual/base.py", line 925, in create_channel
    channel = self.Channel(connection)
  File "/baserow/env/lib/python3.7/site-packages/kombu/transport/redis.py", line 679, in __init__
    self.client.ping()
  File "/baserow/env/lib/python3.7/site-packages/redis/commands/core.py", line 954, in ping
    return self.execute_command("PING", **kwargs)
  File "/baserow/env/lib/python3.7/site-packages/redis/client.py", line 1173, in execute_command
    conn = self.connection or pool.get_connection(command_name, **options)
  File "/baserow/env/lib/python3.7/site-packages/redis/connection.py", line 1370, in get_connection
    connection.connect()
  File "/baserow/env/lib/python3.7/site-packages/redis/connection.py", line 613, in connect
    raise ConnectionError(self._error_message(e))
redis.exceptions.ConnectionError: Error -3 connecting to redis:6379. Temporary failure in name resolution.

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "/baserow/env/lib/python3.7/site-packages/django/core/mail/message.py", line 284, in send
    return self.get_connection(fail_silently).send_messages([self])
  File "/baserow/env/lib/python3.7/site-packages/djcelery_email/backends.py", line 17, in send_messages
    result_tasks.append(send_emails.delay(chunk_messages, self.init_kwargs))
  File "/baserow/env/lib/python3.7/site-packages/celery/app/task.py", line 422, in delay
    return self.apply_async(args, kwargs)
  File "/baserow/env/lib/python3.7/site-packages/celery/app/task.py", line 576, in apply_async
    **options
  File "/baserow/env/lib/python3.7/site-packages/celery/app/base.py", line 767, in send_task
    amqp.send_task_message(P, name, message, **options)
  File "/baserow/env/lib/python3.7/site-packages/celery/app/amqp.py", line 519, in send_task_message
    **properties
  File "/baserow/env/lib/python3.7/site-packages/kombu/messaging.py", line 180, in publish
    exchange_name, declare, timeout
  File "/baserow/env/lib/python3.7/site-packages/kombu/connection.py", line 524, in _ensured
    return fun(*args, **kwargs)
  File "/baserow/env/lib/python3.7/site-packages/kombu/messaging.py", line 186, in _publish
    channel = self.channel
  File "/baserow/env/lib/python3.7/site-packages/kombu/messaging.py", line 209, in _get_channel
    channel = self._channel = channel()
  File "/baserow/env/lib/python3.7/site-packages/kombu/utils/functional.py", line 32, in __call__
    value = self.__value__ = self.__contract__()
  File "/baserow/env/lib/python3.7/site-packages/kombu/messaging.py", line 225, in <lambda>
    channel = ChannelPromise(lambda: connection.default_channel)
  File "/baserow/env/lib/python3.7/site-packages/kombu/connection.py", line 896, in default_channel
    self._ensure_connection(**conn_opts)
  File "/baserow/env/lib/python3.7/site-packages/kombu/connection.py", line 438, in _ensure_connection
    callback, timeout=timeout
  File "/usr/lib/python3.7/contextlib.py", line 130, in __exit__
    self.gen.throw(type, value, traceback)
  File "/baserow/env/lib/python3.7/site-packages/kombu/connection.py", line 451, in _reraise_as_library_errors
    raise ConnectionError(str(exc)) from exc
kombu.exceptions.OperationalError: Error -3 connecting to redis:6379. Temporary failure in name resolution.

Hopefully that makes some sense to you! :slight_smile:

Hey @JB-Dev sorry about the delayed response, there are two changes to the steps I gave you aboe:

Firstly looks like I forgot to set some more env variables in the commands I gave you which I’ve now added below.
Secondly from testing myself locally you also need to make a direct change to the Baserow config file found in: /baserow/baserow/backend/src/baserow/config/settings/base.py

Could you first edit: /baserow/baserow/backend/src/baserow/config/settings/base.py and find the line EMAIL_BACKEND = "djcelery_email.backends.CeleryEmailBackend" and change it to be EMAIL_BACKEND = "django.core.mail.backends.smtp.EmailBackend" . You will probably need to become root to edit this file as I believe the guide has you install baserow using the root user.

This will force Baserow not to use redis and celery to send emails asynchronously, but instead just do it immediately inside the Baserow server, which will let us debug the underlying issue. Once debugged I would recommend reverting the change above.

cd /baserow
source env/bin/activate
export DJANGO_SETTINGS_MODULE='baserow.config.settings.base'
export EMAIL_SMTP='TRUE'
export EMAIL_SMTP_HOST='smtp.gmail.com'
export EMAIL_SMTP_USE_TLS='TRUE'
export EMAIL_SMTP_PORT=587
export EMAIL_SMTP_USER='my@email.com'
export EMAIL_SMTP_PASSWORD='mypassword'
export FROM_EMAIL='my@email.com'
# Missed commands from last time
# These should exactly match what you have set in your `baserow.conf`
export REDIS_HOST='localhost'
export DATABASE_HOST='localhost'
export DATABASE_PASSWORD='REPLACE_WITH_YOUR_DB_PASSWORD'
export MJML_SERVER_HOST='localhost'
baserow shell

Now try copy and pasting the following into the newly opened baserow shell after replacing the REPLACE_WITH_TO_EMAIL_ADDRESS with the email address you want to test sending an email to.

from django.core.mail import EmailMessage
from django.conf import settings

email = EmailMessage(
    'title',
    'msg',
    settings.FROM_EMAIL,
    ['REPLACE_WITH_TO_EMAIL_ADDRESS'],
)
email.send(fail_silently=False)

Hi @nigel,
No problem!
I retried with the extra changes and got this error (Similar to the original it seems):

Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "/baserow/env/lib/python3.7/site-packages/django/core/mail/message.py", line 284, in send
    return self.get_connection(fail_silently).send_messages([self])
  File "/baserow/env/lib/python3.7/site-packages/django/core/mail/backends/smtp.py", line 102, in send_messages
    new_conn_created = self.open()
  File "/baserow/env/lib/python3.7/site-packages/django/core/mail/backends/smtp.py", line 62, in open
    self.connection = self.connection_class(self.host, self.port, **connection_params)
  File "/usr/lib/python3.7/smtplib.py", line 251, in __init__
    (code, msg) = self.connect(host, port)
  File "/usr/lib/python3.7/smtplib.py", line 336, in connect
    self.sock = self._get_socket(host, port, self.timeout)
  File "/usr/lib/python3.7/smtplib.py", line 307, in _get_socket
    self.source_address)
  File "/usr/lib/python3.7/socket.py", line 728, in create_connection
    raise err
  File "/usr/lib/python3.7/socket.py", line 716, in create_connection
    sock.connect(sa)
OSError: [Errno 101] Network is unreachable

Let me know if there’s anything else I need to do!

@JB-Dev

From a quick google of that error it (python - "[Errno 101] Network is unreachable" when trying to send email using Django - Stack Overflow) looks like perhaps the port you are trying to use is being blocked by your hosting provider / firewall setup perhaps?

What happens when you run the following command on your ubuntu server:

telnet smtp.gmail.com 587

Hi @nigel
Thanks for the help!
This turned out to be a very niche issue which may hopefully help someone in the future!
Everything baserow works perfectly, the issue was this:
If you are hosting ANY server on scaleway within their Private networks you need ipv6 enabled on any server you want SMTP to work on.

Ended up not being anything to do with baserow but hopefully someone will find it useful!

Love the product and you were super helpful!

1 Like

Hi!

I just started a container to test Baserow.

Below my docker-compose.yml:

version: "3.4"
services:

  baserow:
    image: baserow/baserow:1.11.0
    container_name: baserow
    hostname: baserow
    volumes:
      - data:/baserow/data
    #ports:
    #  - "80:80"
    #  - "443:443"
    restart: unless-stopped
    environment:
      BASEROW_PUBLIC_URL: 'https://baserow.mydomain.com'
      EMAIL_SMTP: 'TRUE'
      EMAIL_SMTP_HOST: 'mail.mydomain.com'
      EMAIL_SMTP_PORT: 587
      EMAIL_SMTP_USE_TLS: 'TRUE'
      EMAIL_SMTP_USER: 'smtp@mydomain.com'
      EMAIL_SMTP_PASSWORD: 'P@ssw0rd'
      FROM_EMAIL: 'no-reply@mydomain.com'

volumes:
  data:

networks:
  default:
    name: caddy_net
    external: true

After register the first (admin) account I suppose I would receive an email.

But that do not happens.

How do I test/debug this issue?

I can´t use suggested steps above, I think something is different for version 1.11 and/or docker container.

[admin@vps baserow]$ clear ; docker exec -it baserow /bin/bash
root@baserow:/# cd /baserow
root@baserow:/baserow# source env/bin/activate
bash: env/bin/activate: No such file or directory

Hi @peracchi , Sorry for the delay!

Edit: Just to clarify, we don’t send any emails when you first sign up. The only emails we ever send are password reset emails, group invite emails and possibly some emails related to account deletion.

I’ve updated my instructions from above to match the new Docker setup. One day I would love to add an email test button somewhere in the settings page!

These instructions are assuming you are using the baserow/baserow:XYZ image (which you are, just for future readers!)

  1. Make sure your Baserow is running as normal (docker-compose up -d etc)
  2. Now open a shell into your Baserow container:
# This will setup the venv, env variables etc for you! 
docker exec -it baserow /baserow.sh backend-cmd bash -c bash
  1. Now change to the backend directory
cd /baserow/backend
  1. Open the Python Shell:
./baserow shell
  1. Now try copy and pasting the following into the newly opened baserow shell after replacing the REPLACE_WITH_TO_EMAIL_ADDRESS with the email address you want to test sending an email to.
from django.core.mail import EmailMessage
from django.conf import settings

email = EmailMessage(
    'title',
    'msg',
    settings.FROM_EMAIL,
    ['REPLACE_WITH_TO_EMAIL_ADDRESS'],
)
email.send(fail_silently=False)

I’ve not personally tested these instructions so perhaps there is a typo, let me know if it doesn’t work!

Thanks @nigel !

I infered this after begin my tests and receive an invite email.

I’m using Baserow behind “my Caddy” because I have more containers and Caddy is really gold as reverse proxy for Docker containers.

Bellow my docker-compose.yml with env variables set (may be useful for someone).

version: "3.4"
services:

  baserow:
    image: baserow/baserow:1.11.0
    container_name: baserow
    hostname: baserow
    volumes:
      - data:/baserow/data
    #ports:
    #  - "80:80"
    #  - "443:443"
    restart: unless-stopped
    environment:
      BASEROW_PUBLIC_URL: 'https://baserow.my.domain'
      EMAIL_SMTP: 'TRUE'
      EMAIL_SMTP_HOST: 'mail.my.domain'
      EMAIL_SMTP_PORT: 587
      EMAIL_SMTP_USE_TLS: 'TRUE'
      EMAIL_SMTP_USER: 'smtp@my.domain'
      EMAIL_SMTP_PASSWORD: 'mY-p@sS0rD'
      FROM_EMAIL: 'Baserow <no-reply@my.domain>'

volumes:
  data:

networks:
  default:
    name: caddy_net
    external: true