Sending Email from the Wiki

This guide explains how to configure Wikantik to send transactional emails from a self-hosted installation. Wikantik sends mail in three situations: a welcome email to a user when their profile is created, a password-reset email that carries a temporary password (the user must change it at the next login), and an optional notice to an administrator whenever a new profile is created (wikantik.admin.notification.email). It does not send a separate address-verification email.

Why You Need an Email Relay Service

Sending email directly from a home server will fail because:

You need a transactional email relay service.


1. Brevo (formerly Sendinblue) — Best Free Tier

3. Mailjet

4. Amazon SES — Cheapest at Scale

5. Resend — Modern Option

For low volume (few hundred emails per week), Brevo or SendGrid free tiers are more than sufficient.


Step-by-Step Setup

This example uses Brevo, but the process is similar for other providers.

Step 1: Sign Up for Email Service

  1. Go to https://www.brevo.com
  2. Create a free account
  3. Verify your email address

Step 2: Add and Verify Your Sending Domain

  1. In Brevo dashboard, go to Senders & IP → Domains
  2. Add your domain (e.g., jakefear.com or wiki.jakefear.com)
  3. Brevo will provide DNS records to add

Step 3: Configure DNS Records

Add the DNS records provided by your email service. Typical records include:

TypeHostValuePurpose
TXT@v=spf1 include:sendinblue.com ~allSPF - authorizes service to send
TXTmail._domainkeyk=rsa; p=MIGf...DKIM - email signing
TXT_dmarcv=DMARC1; p=quarantine; rua=mailto:...DMARC - policy

Note: If you already have an SPF record, merge them:

v=spf1 include:existing.com include:sendinblue.com ~all

Step 4: Get SMTP Credentials

In your email service dashboard:

  1. Navigate to SMTP settings
  2. Note down:
    • SMTP Server (e.g., smtp-relay.brevo.com)
    • Port: 587 (TLS) or 465 (SSL)
    • Login/Username
    • Password or API Key

Step 5: Configure Wikantik

Add to your wikantik-custom.properties (bare-metal Tomcat: tomcat/tomcat-11/lib/wikantik-custom.properties):

# Email configuration
mail.from = Wikantik <wiki@yourdomain.com>
mail.smtp.host = smtp-relay.brevo.com
mail.smtp.port = 587
mail.smtp.account = your-login@email.com
mail.smtp.password = your-smtp-key-here
mail.smtp.starttls.enable = true
mail.smtp.timeout = 5000
mail.smtp.connectiontimeout = 5000

The last three lines restate the defaults, which a standalone session applies whenever the keys are unset (see the properties reference below); releases up to 2.4.56 did not apply them, so on those versions set all three explicitly.

In the container stack you do not edit the properties file: set MAIL_SMTP_HOST, MAIL_SMTP_PORT (default 587), MAIL_SMTP_ACCOUNT, MAIL_SMTP_PASSWORD and MAIL_FROM in .env. Whenever MAIL_SMTP_HOST is non-empty, docker/entrypoint.sh writes the matching mail.* properties (including mail.smtp.starttls.enable = true) into the generated wikantik-custom.properties on every start. Leave MAIL_SMTP_HOST empty to leave mail unconfigured. See Wikantik on Docker.

Step 6: Test Email

  1. Restart Tomcat (or the container)
  2. Create a user account that has an email address, or use the password-reset flow (/reset-password) for an existing account
  3. Check that the welcome or password-reset email arrives
  4. Look for Sent e-mail to=... in wikantik.log, which also says whether the JNDI or the standalone session was used
  5. Check your email service dashboard for delivery logs

Alternative: JNDI Configuration (More Secure)

To keep credentials out of properties files, configure the mail session in Tomcat's context file.

Add to your Tomcat context file conf/Catalina/localhost/ROOT.xml (Wikantik is deployed as the ROOT context; bin/deploy-local.sh renders this file once and does not overwrite it afterwards). This route is for bare-metal Tomcat only: the container's entrypoint regenerates ROOT.xml on every start, so use the MAIL_SMTP_* variables there.

<Resource name="mail/Session"
          auth="Container"
          type="jakarta.mail.Session"
          mail.smtp.host="smtp-relay.brevo.com"
          mail.smtp.port="587"
          mail.smtp.auth="true"
          mail.smtp.starttls.enable="true"
          mail.smtp.timeout="5000"
          mail.smtp.connectiontimeout="5000"
          mail.smtp.user="your-login@email.com"
          password="your-smtp-key-here"
          mail.from="wiki@yourdomain.com"/>

Wikantik will automatically use the JNDI session mail/Session when available. Wikantik's built-in timeout and STARTTLS defaults apply only to the standalone session, not to a JNDI one, so declare mail.smtp.timeout, mail.smtp.connectiontimeout and mail.smtp.starttls.enable in the <Resource> as shown or the container's (usually unbounded) defaults apply.


SMTP Settings by Provider

Brevo (Sendinblue)

mail.smtp.host = smtp-relay.brevo.com
mail.smtp.port = 587
mail.smtp.starttls.enable = true

SendGrid

mail.smtp.host = smtp.sendgrid.net
mail.smtp.port = 587
mail.smtp.account = apikey
mail.smtp.password = SG.your-api-key-here
mail.smtp.starttls.enable = true

Mailjet

mail.smtp.host = in-v3.mailjet.com
mail.smtp.port = 587
mail.smtp.starttls.enable = true

Amazon SES

mail.smtp.host = email-smtp.us-east-1.amazonaws.com
mail.smtp.port = 587
mail.smtp.starttls.enable = true

Wikantik Mail Properties Reference

PropertyDefaultDescription
mail.fromWikantik <Wikantik@localhost> (the shipped ini/wikantik.properties value; the code falls back to wikantik@localhost)The sender email address
mail.smtp.host127.0.0.1SMTP server hostname
mail.smtp.port25SMTP server port
mail.smtp.account(not set)SMTP username for authentication; setting it turns SMTP authentication on
mail.smtp.password(not set)SMTP password for authentication
mail.smtp.starttls.enabletrueEnable TLS encryption (opportunistic, see below)
mail.smtp.timeout5000Socket I/O timeout (ms)
mail.smtp.connectiontimeout5000Connection timeout (ms)
wikantik.mail.jndinamemail/SessionJNDI name for container-managed session; Wikantik tries it first and falls back to the mail.* properties if the lookup fails
wikantik.admin.notification.email(blank)When set, an email is sent to this address each time a new user profile is created

Standalone-session defaults. When Wikantik builds its own mail session from wikantik-custom.properties (the path used when no JNDI mail/Session exists), it applies the defaults in the table above to the session itself whenever a key is unset: mail.smtp.starttls.enable = true, mail.smtp.timeout = 5000 and mail.smtp.connectiontimeout = 5000. Without them JavaMail would never negotiate STARTTLS and would wait forever on an unresponsive relay, blocking the sending thread. STARTTLS is opportunistic (starttls.enable, not starttls.required): the connection is upgraded only if the server offers it, so a relay without TLS still works. An explicit value always wins, including mail.smtp.starttls.enable = false and mail.smtp.timeout = 0 (no timeout); a blank value (mail.smtp.timeout =) counts as unset and gets the default. mail.smtps.* keys are passed to JavaMail as written and do not stand in for the mail.smtp.* ones. A JNDI session is used exactly as the container defines it — Wikantik adds no defaults to it, so set the timeouts and STARTTLS in the <Resource> (see above). Releases up to 2.4.56 passed only the mail.smtp.* keys you had set to JavaMail, whose own defaults are no STARTTLS and no timeout, so on those versions set all three keys explicitly.


Troubleshooting

Emails Not Sending

  1. Check the logs for mail-related errors (a failed registration mail logs Could not send registration confirmation e-mail. Is the e-mail server running?)
  2. Verify SMTP credentials are correct
  3. Ensure port 587 outbound is not blocked by firewall
  4. Check email service dashboard for rejected/bounced messages

Emails Going to Spam

  1. Verify SPF, DKIM, and DMARC records are properly configured
  2. Use a "from" address that matches your verified domain
  3. Allow 24-48 hours for DNS changes to propagate
  4. Check your domain's reputation at https://mxtoolbox.com

Authentication Errors

  1. Some services require API keys instead of passwords
  2. SendGrid uses apikey as the username with API key as password
  3. Ensure special characters in passwords are properly escaped

Connection Timeouts

  1. Try port 465 (SSL) instead of 587 (TLS)
  2. Check if your ISP blocks outbound SMTP ports
  3. A standalone session gives up after 5 seconds by default (mail.smtp.connectiontimeout to connect, mail.smtp.timeout per read); raise either in wikantik-custom.properties for a slow relay


Cluster Hub: Wikantik Platform Development Hub: Architecture, MCP Protocols, and Agent Briefings (wikantik-development)