Post

Mealie Fix Base And Email

Mealie Fix Base And Email

Mealie Kubernetes Configuration Fix - BASE_URL and SMTP Setup

Issues Encountered

When I deployed Mealie in a Kubernetes environment, I found two common configuration errors which can prevent proper functionality:

  1. BASE_URL Error: “BASE_URL is still the default value on API Server. This will cause issues with notifications links generated on the server for emails, etc.”
  2. Email Configuration Error: “Email Configuration Status: Not Ready - Check Environmental Variables”

Root Cause Analysis

BASE_URL Issue

  • Mealie needs to know its external URL to generate correct links in emails and notifications
  • Without this configuration, all generated links will use default/localhost values
  • This breaks password reset emails, invitations, and other notification features

SMTP Configuration Issue

  • Mealie requires explicit SMTP environment variables to send emails
  • The application cannot auto-detect email server settings
  • Missing SMTP configuration prevents user invitations, password resets, and notifications

Solution Implementation

Step 1: Configure BASE_URL

Added the BASE_URL environment variable to the Mealie deployment specification:

1
2
- name: BASE_URL
  value: "https://mealie.matthewdavidson.us"

Why this works:

  • Tells Mealie the external URL it’s accessible from
  • Enables proper link generation in emails and notifications
  • Should match one of the domains configured in your Ingress

Step 2: Configure SMTP Settings

Added comprehensive SMTP environment variables to enable email functionality:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# SMTP Configuration
- name: SMTP_HOST
  value: "your-smtp-server.com"
- name: SMTP_PORT
  value: "587"
- name: SMTP_FROM_EMAIL
  value: "mealie@yourdomain.com"
- name: SMTP_FROM_NAME
  value: "Mealie"
- name: SMTP_AUTH_STRATEGY
  value: "TLS"
- name: SMTP_USER
  value: "your-email@yourdomain.com"
- name: SMTP_PASSWORD
  value: "your-app-password"

Key SMTP Parameters Explained:

  • SMTP_HOST: Your email server hostname
  • SMTP_PORT: Email server port (587 for TLS, 465 for SSL, 25 for plain)
  • SMTP_FROM_EMAIL: Address Mealie sends emails from
  • SMTP_FROM_NAME: Display name for outgoing emails
  • SMTP_AUTH_STRATEGY: Encryption method (TLS, SSL, or NONE)
  • SMTP_USER: Authentication username for your email server
  • SMTP_PASSWORD: Authentication password for your email server

Final Configuration

The complete working deployment configuration:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
apiVersion: apps/v1
kind: Deployment
metadata:
  name: mealie
  namespace: mealie
spec:
  replicas: 1
  selector:
    matchLabels:
      app: mealie
  template:
    metadata:
      labels:
        app: mealie
    spec:
      containers:
        - name: mealie
          image: ghcr.io/mealie-recipes/mealie:nightly
          ports:
            - containerPort: 9000
          volumeMounts:
            - name: data
              mountPath: /app/data
          env:
            - name: MEALIE_SERVER_PORT
              value: "9000"
            - name: BASE_URL
              value: "https://mealie.matthewdavidson.us"
            # SMTP Configuration
            - name: SMTP_HOST
              value: "your-smtp-server.com"
            - name: SMTP_PORT
              value: "587"
            - name: SMTP_FROM_EMAIL
              value: "mealie@yourdomain.com"
            - name: SMTP_FROM_NAME
              value: "Mealie"
            - name: SMTP_AUTH_STRATEGY
              value: "TLS"
            - name: SMTP_USER
              value: "your-email@yourdomain.com"
            - name: SMTP_PASSWORD
              value: "your-app-password"
      volumes:
        - name: data
          persistentVolumeClaim:
            claimName: mealie-data

Security Considerations

Using Kubernetes Secrets for Sensitive Data

For production deployments, you should consider using Kubernetes secrets for sensitive information like SMTP passwords. Example:

  1. Create a secret:
    1
    2
    3
    
    kubectl create secret generic mealie-smtp-secret \
      --from-literal=password='your-smtp-password' \
      -n mealie
    
  2. Reference the secret in your deployment:
    1
    2
    3
    4
    5
    
    - name: SMTP_PASSWORD
      valueFrom:
     secretKeyRef:
       name: mealie-smtp-secret
       key: password
    

Docker Compose Secrets Pattern

Mealie supports Docker Compose secrets by appending _FILE to environment variables:

1
2
- name: SMTP_PASSWORD_FILE
  value: "/run/secrets/smtp_password"

Verification Steps

After applying the configuration changes:

  1. Apply the updated deployment:
    1
    
    kubectl apply -f mealie-deployment.yaml
    
  2. Verify the pod restarts successfully:
    1
    2
    
    kubectl get pods -n mealie
    kubectl logs -f deployment/mealie -n mealie
    
  3. Check the Mealie web interface:
    • BASE_URL error should disappear from logs
    • Email Configuration Status should show “Ready”
    • Test email functionality through admin panel

Additional Configuration Options

Mealie supports many other environment variables for advanced configuration:

  • Database settings (PostgreSQL vs SQLite)
  • OIDC/SSO integration
  • LDAP authentication
  • Theme customization
  • API rate limiting

Refer to the official Mealie documentation for complete configuration options.

Common Pitfalls

  1. Mismatched BASE_URL: Ensure BASE_URL matches your actual domain from the Ingress
  2. Wrong SMTP port: Verify your email server’s port and encryption requirements
  3. Authentication issues: Some providers require app-specific passwords instead of account passwords
  4. Modern Auth: Gmail and Outlook are moving away from SMTP Auth - consider SMTP relay services if needed

Conclusion

These configuration changes resolve the two most common Mealie deployment issues in Kubernetes environments. Proper BASE_URL and SMTP configuration enables full email functionality, allowing user invitations, password resets, and notifications to work correctly.

This post is licensed under CC BY 4.0 by the author.