I am having an issue which I am trying to resolve ...
# ory-selfhosting
s
I am having an issue which I am trying to resolve since a month. I am having a self hosted Ory Kratos instance (On a Raspberry Pi behind my router). I have gone through all docs and configured everything. All works except the damn emails. Kratos is not able to send emails after sign up is completed for a reason I am exhausted now to figure out. Coming here is my last resort. Please find my configuration below for reference: kratos.yml
Copy code
version: v0.13.0

dsn: <mysql://kratos>:<REDACTED>@tcp(localhost:3306)/kratos?max_conns=20&max_idle_conns=4

serve:
  public:
    base_url: <https://auth.warrantify.me/>
    host: 127.0.0.1
    cors:
      enabled: true
      allowed_origins:
        - <http://localhost>
        - <https://localhost>
        - <https://warrantify.me>
        - <https://www.warrantify.me>
        - <https://auth.warrantify.me>
        - <https://www.auth.warrantify.me>
      allowed_methods:
        - POST
        - GET
        - PUT
        - PATCH
        - DELETE
        - OPTIONS
      allowed_headers:
        - Authorization
        - Cookie
        - Content-Type
      exposed_headers:
        - Content-Type
        - Set-Cookie

  admin:
    base_url: <http://127.0.0.1:4434/>
    host: 127.0.0.1

session:
    cookie:
      domain: warrantify.me
      same_site: Lax
      name: wme_auth
    whoami:
      required_aal: aal1

selfservice:
  default_browser_return_url: <https://auth.warrantify.me/auth/>
  allowed_return_urls:
    - <https://auth.warrantify.me>

  methods:
    password:
      enabled: true
    lookup_secret:
      enabled: true
    link:
      enabled: true
    code:
      enabled: true

  flows:
    error:
      ui_url: <https://auth.warrantify.me/auth/errors>

    settings:
      ui_url: <https://auth.warrantify.me/auth/settings>
      privileged_session_max_age: 15m
      required_aal: highest_available

    recovery:
      enabled: true
      ui_url: <https://auth.warrantify.me/auth/recovery>
      use: code

    verification:
      enabled: true
      ui_url: <https://auth.warrantify.me/auth/verification>
      use: code
      after:
        default_browser_return_url: <https://auth.warrantify.me/auth/>

    logout:
      after:
        default_browser_return_url: <https://auth.warrantify.me/auth/login>

    login:
      ui_url: <https://auth.warrantify.me/auth/login>
      lifespan: 10m

    registration:
      lifespan: 10m
      ui_url: <https://auth.warrantify.me/auth/registration>
      after:
        password:
          hooks:
            - hook: session
            - hook: show_verification_ui

log:
  level: debug
  format: text
  leak_sensitive_values: false

secrets:
  cookie:
    - <REDACTED>
  cipher:
    - <REDACTED>

ciphers:
  algorithm: xchacha20-poly1305

hashers:
  algorithm: argon2
  argon2:
    parallelism: 1
    memory: 64MB
    iterations: 3
    salt_length: 16
    key_length: 32

identity:
  default_schema_id: user_v0
  schemas:
    - id: user_v0
      url: file:///serverapps/auth/ory/kratos/config/identity.schema.json

courier:
  delivery_strategy: http
  http:
    request_config:
      url: <https://send.api.mailtrap.io/api/send>
      method: POST
      body: file:///serverapps/auth/ory/kratos/config/mailtrap.jsonnet
      headers:
        "Content-Type": "application/json"
      auth:
        type: api_key
        config:
          name: Api-Token
          value: <REDACTED>
          in: header

feature_flags:
  - use_continue_with_transitions: true
identity.schema.json:
Copy code
{
  "$id": "<https://schemas.ory.sh/presets/kratos/quickstart/email-password/identity.schema.json>",
  "$schema": "<http://json-schema.org/draft-07/schema#>",
  "title": "Person",
  "type": "object",
  "properties": {
    "traits": {
      "type": "object",
      "properties": {
        "email": {
          "type": "string",
          "format": "email",
          "title": "E-Mail",
          "minLength": 3,
          "ory.sh/kratos": {
            "credentials": {
              "password": {
                "identifier": true
              }
            },
            "recovery": {
              "via": "email"
            },
            "verification": {
              "via": "email"
            }
          }
        },
        "phone": {
          "type": "string",
          "format": "tel",
          "title": "Phone"
          }
        },
        "name": {
          "type": "object",
          "required": ["first", "last"],
          "properties": {
            "first": {
              "title": "First Name",
              "type": "string"
            },
            "last": {
              "title": "Last Name",
              "type": "string"
            }
          }
        }
      },
      "required": ["email", "name", "phone"],
      "additionalProperties": false
    }
  }
}
Mail Configuration: Mailtrap API docs: https://api-docs.mailtrap.io/docs/mailtrap-api-docs/67f1d70aeb62c-send-email-including-templates mailtrap.jsonnet
Copy code
function(ctx) {
  from: {
    "email": "no-reply@warrantify.me",
    "name": "Warrantify.me"
  },
  to: [{
    "email": ctx.recepient
  }],
  subject: if "template_data" in ctx && "subject" in ctx.template_data then ctx.template_data.subject else null,
  html: ctx.body
}
nginx config:
Copy code
upstream kratos_ui {
        server 127.0.0.1:3000;
}

upstream kratos_public_api {
        server 127.0.0.1:4433;
}

upstream kratos_admin_api {
        server 127.0.0.1:4434;
}

server {

    server_name auth.warrantify.me;

    listen 443 ssl http2;

    ssl_certificate /etc/letsencrypt/live/warrantify.me-0001/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/warrantify.me-0001/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot

    location / {
        proxy_pass              <http://kratos_public_api>;
        proxy_redirect          off;
        proxy_set_header        Host                    $host;
        proxy_set_header        X-Real-IP               $remote_addr;
        proxy_set_header        X-Forwarded-For         $proxy_add_x_forwarded_for;
    }

    location /admin {
    # Example of managing access control
    # for the /admin endpoint
    # in that example we allow access
    # either from the subnet
    # or by checking query parameter ?secret=
                set $allow 0;
    # Check against remote address
                if ($remote_addr ~* "172.24.0.*") {
                        set $allow 1;
                }
    # Check against ?secret param
                if ($arg_secret = "GuQ8alL2") {
                        set $allow 1;
                }
                if ($allow = 0) {
                        return 403;
                }

                rewrite /admin/(.*) /$1  break;

                proxy_pass <http://kratos_admin_api>;
                proxy_redirect          off;
                proxy_set_header        Host            $host;
                proxy_set_header        X-Real-IP       $remote_addr;
                proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
    }

    location /identities {
                proxy_pass <http://kratos_admin_api>;
                proxy_redirect          off;
                proxy_set_header        Host            $host;
                proxy_set_header        X-Real-IP       $remote_addr;
                proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
    }

    location /auth {
            rewrite /auth/(.*) /$1  break;

            proxy_pass <http://kratos_ui>;
            proxy_redirect          off;
            proxy_set_header        Host            $host;
            proxy_set_header        X-Real-IP       $remote_addr;
            proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
    }

    error_page 401 = @error401;
    # Catch if 401/unauthorized and redirect for login
    location @error401 {
        return 302 <https://auth.warrantify.me/auth/login>;
    }

}
server {
    server_name warrantify.me;

    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/warrantify.me-0001/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/warrantify.me-0001/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot

    location / {
        root /serverapps/wme/frontend;
        index index.html index.htm;
    }


}
server {

    if ($host = warrantify.me) {
        return 301 https://$host$request_uri;
    } # managed by Certbot


    listen 80;
    server_name warrantify.me;
    return 404; # managed by Certbot


}
p
hey @stale-tiger-66317 incase you dont know, you need to start kratos with
--watch-courier
then only it will send emails. https://www.ory.sh/docs/kratos/self-hosted/mail-courier-selfhosted#single-instance-setup
s
Hey.. I already have that:
Okay, so after trying different things whole day, following template worked:
Copy code
function(ctx) {
  from: {
    email: '<mailto:no-reply@warrantify.me|no-reply@warrantify.me>',
    name: '<http://Warrantify.me|Warrantify.me>'
  },
  to: [
    {
      email: ctx.recipient
    }
  ],
  subject: ctx.subject,
  html: ctx.body
}
Notable Changes: 1. Changed ctx.template_data.subject to ctx.subject 2. Removed double quotes from fields inside 'from'. 3. Changed double quotes to single quotes for values inside 'from' I manually had to build a new kratos from source and add debug logs. I will raise a PR for this.