DEV Community

Nickson Elauriche Toho
Nickson Elauriche Toho

Posted on

2

Configuring Sendy with NGINX: A Step-by-Step Guide

Sendy is a powerful and cost-effective self-hosted email marketing solution. To optimize its performance and security, integrating it with NGINX, a high-performance web server, is a smart choice. This article will guide you through the process of configuring Sendy with NGINX.

Prerequisites:
Before you begin, make sure you have the following:
Sendy project folder downloaded from SENDY on your server.
NGINX installed on your server.

Step 1: Create NGINX Server Block for Sendy

Navigate to the NGINX sites-available directory. Create a new configuration file for Sendy, for example, sendy.conf.

sudo nano /etc/nginx/sites-available/sendy.conf

Add the following configuration, adjusting the values as needed:

For configure NGINX without SSL config

server {
    listen 80;
    server_name your_sendy_domain.com www.your_sendy_domain.com;

    root /var/www/sendy; # Change this to your Sendy installation directory

    index index.php index.html index.htm;
    autoindex off;

    add_header X-Robots-Tag "noindex, noarchive";
    add_header X-Frame-Options "SAMEORIGIN";
    add_header X-XSS-Protection "1; mode=block";
    add_header X-Content-Type-Options "nosniff";

    location = /favicon.ico { log_not_found off; access_log off; }
    location = /robots.txt { log_not_found off; access_log off; allow all; }
    location ~ /\.  { deny all; log_not_found off; access_log off; return 404; }

    location / {
        try_files $uri $uri/ /index.php?$args;
    }

    location ~ \.php$ {
        try_files $uri =404;
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass unix:/var/run/php/php8.1-fpm.sock; # Adjust the PHP version if needed
        fastcgi_index index.php;
        fastcgi_param   SCRIPT_FILENAME $request_filename;
        include fastcgi_params;
    }

    location ~ /\.ht {
        deny all;
    }

    location ~* \.(css|js|gif|jpe?g|png)$ {
        expires max;
        log_not_found off;
    }

    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }
    location /l/ {
        rewrite ^/l/([a-zA-Z0-9/]+)$ /l.php?i=$1 last;
    }
    location /t/ {
        rewrite ^/t/([a-zA-Z0-9/]+)$ /t.php?i=$1 last;
    }
    location /w/ {
        rewrite ^/w/([a-zA-Z0-9/]+)$ /w.php?i=$1 last;
    }
    location /unsubscribe/ {
        rewrite ^/unsubscribe/(.*)$ /unsubscribe.php?i=$1 last;
    }
    location /subscribe/ {
        rewrite ^/subscribe/(.*)$ /subscribe.php?i=$1 last;
    }
    location /confirm/ {
        rewrite ^/confirm/(.*)$ /confirm.php?i=$1 last;
    }
    location /new-brand {
        rewrite ^/new-brand/?$ /new-brand.php last;
    }
    location /search-all-brands {
        rewrite ^/search-all-brands/?$ /search-all-brands.php last;
    }
    location /login {
        rewrite ^/login/?$ /login.php last;
    }
    location /settings {
        rewrite ^/settings/?$ /settings.php last;
    }
    location /two-factor {
        if ($arg_i) {
            rewrite ^/two-factor$ /two-factor.php last;
        }
    }
    location = /create {
        if ($arg_i) {
            rewrite ^/create$ /create.php last;
        }
    }
    location = /rules {
        if ($arg_i) {
            rewrite ^/rules$ /rules.php last;
        }
    }
    location = /edit {
       if ($arg_i) {
            rewrite ^/edit$ /edit.php last;
        }
    }
    location = /app {
         if ($arg_i) {
             rewrite ^/app$ /app.php last;
          }
    }
    location = /list {
         if ($arg_i) {
            rewrite ^/list$ /list.php last;
         }
    }
    location = /reports {
        if ($arg_i) {
             rewrite ^/reports$ /reports.php last;
        }
    }
    location = /edit-brand {
        if ($arg_i) {
            rewrite ^/edit-brand$ /edit-brand.php last;
         }
    }
    location = /templates {
        if ($arg_i) {
           rewrite ^/templates$ /templates.php last;
        }
    }
    location = /report {
        if ($arg_i) {
            rewrite ^/report$ /report.php last;
        }
    }
    location = /send-to {
        if ($arg_i) {
            rewrite ^/send-to$ /send-to.php last;
        }
    }
    location = /autoresponders-emails {
        if ($arg_i) {
            rewrite ^/autoresponders-emails$ /autoresponders-emails.php last;
        }
    }
    location = /autoresponders-list {
        if ($arg_i) {
            rewrite ^/autoresponders-list$ /autoresponders-list.php last;
        }
    }
    location = /autoresponders-edit {
        if ($arg_i) {
            rewrite ^/autoresponders-edit$ /autoresponders-edit.php last;
        }
    }
    location = /segments-list {
        if ($arg_i) {
           rewrite ^/segments-list$ /segments-list.php last;
        }
    }
    location = /segment {
        if ($arg_i) {
           rewrite ^/segment$ /segment.php last;
        }
    }
    location = /create-template {
        if ($arg_i) {
           rewrite ^/create-template$ /create-template.php last;
        }
    }
    location = /edit-template{
        if ($arg_i) {
           rewrite ^/edit-template$ /edit-template.php last;
        }
    }
    location = /template-preview {
        if ($arg_i) {
            rewrite ^/template-preview$ /template-preview.php last;
        }
    }
    location = /new-list {
        if ($arg_i) {
            rewrite ^/new-list$ /new-list.php last;
        }
    }
    location = /subscribers {
         if ($arg_i) {
            rewrite ^/subscribers$ /subscribers.php last;
         }
    }
    location = /custom-fields {
         if ($arg_i) {
            rewrite ^/custom-fields$ /custom-fields.php last;
         }
    }
    location = /remove-duplicates {
         if ($arg_i) {
            rewrite ^/remove-duplicates$ /remove-duplicates.php last;
         }
    }
    location = /blacklist-blocked-domains {
         if ($arg_i) {
            rewrite ^/blacklist-blocked-domains$ /blacklist-blocked-domains.php last;
         }
    }
    location = /delete-from-list {
         if ($arg_i) {
            rewrite ^/delete-from-list$ /delete-from-list.php last;
         }
    }
    location = /blacklist-suppression {
         if ($arg_i) {
            rewrite ^/blacklist-suppression$ /blacklist-suppression.php last;
         }
    }
    location = /unsubscribe-from-list {
         if ($arg_i) {
            rewrite ^/unsubscribe-from-list$ /unsubscribe-from-list.php last;
         }
    }
    location = /update-list {
         if ($arg_i) {
            rewrite ^/update-list$ /update-list.php last;
         }
    }
    location ~ ^/housekeeping-(\w+)$ {
         rewrite ^/housekeeping-(\w+)$ /housekeeping-$1.php last;
    }

    access_log /var/log/nginx/sendy_access.log;
    error_log /var/log/nginx/sendy_error.log;
}
Enter fullscreen mode Exit fullscreen mode

For configure NGINX with SSL config

```server {
server_name your_sendy_domain.com www.your_sendy_domain.com;
root /var/www/sendy; # Change this to your Sendy installation directory

index index.php index.html index.htm;
autoindex off;

add_header X-Robots-Tag "noindex, noarchive";
add_header X-Frame-Options "SAMEORIGIN";
add_header X-XSS-Protection "1; mode=block";
add_header X-Content-Type-Options "nosniff";

location = /favicon.ico { log_not_found off; access_log off; }
location = /robots.txt { log_not_found off; access_log off; allow all; }
location ~ /\.  { deny all; log_not_found off; access_log off; return 404; }

location / {
    try_files $uri $uri/ /index.php?$args;
}

location ~ \.php$ {
    try_files $uri =404;
    fastcgi_split_path_info ^(.+\.php)(/.+)$;
    fastcgi_pass unix:/var/run/php/php8.1-fpm.sock; # Adjust the PHP version if needed
    fastcgi_index index.php;
    fastcgi_param   SCRIPT_FILENAME $request_filename;
    include fastcgi_params;
}

location ~ /\.ht {
    deny all;
}

location ~* \.(css|js|gif|jpe?g|png)$ {
    expires max;
    log_not_found off;
}

location / {
    try_files $uri $uri/ /index.php?$query_string;
}
location /l/ {
    rewrite ^/l/([a-zA-Z0-9/]+)$ /l.php?i=$1 last;
}
location /t/ {
    rewrite ^/t/([a-zA-Z0-9/]+)$ /t.php?i=$1 last;
}
location /w/ {
    rewrite ^/w/([a-zA-Z0-9/]+)$ /w.php?i=$1 last;
}
location /unsubscribe/ {
    rewrite ^/unsubscribe/(.*)$ /unsubscribe.php?i=$1 last;
}
location /subscribe/ {
    rewrite ^/subscribe/(.*)$ /subscribe.php?i=$1 last;
}
location /confirm/ {
    rewrite ^/confirm/(.*)$ /confirm.php?i=$1 last;
}
location /new-brand {
    rewrite ^/new-brand/?$ /new-brand.php last;
}
location /search-all-brands {
    rewrite ^/search-all-brands/?$ /search-all-brands.php last;
}
location /login {
    rewrite ^/login/?$ /login.php last;
}
location /settings {
    rewrite ^/settings/?$ /settings.php last;
}
location /two-factor {
    if ($arg_i) {
        rewrite ^/two-factor$ /two-factor.php last;
    }
}
location = /create {
    if ($arg_i) {
        rewrite ^/create$ /create.php last;
    }
}
location = /rules {
    if ($arg_i) {
        rewrite ^/rules$ /rules.php last;
    }
}
location = /edit {
   if ($arg_i) {
        rewrite ^/edit$ /edit.php last;
    }
}
location = /app {
     if ($arg_i) {
         rewrite ^/app$ /app.php last;
      }
}
location = /list {
     if ($arg_i) {
        rewrite ^/list$ /list.php last;
     }
}
location = /reports {
    if ($arg_i) {
         rewrite ^/reports$ /reports.php last;
    }
}
location = /edit-brand {
    if ($arg_i) {
        rewrite ^/edit-brand$ /edit-brand.php last;
     }
}
location = /templates {
    if ($arg_i) {
       rewrite ^/templates$ /templates.php last;
    }
}
location = /report {
    if ($arg_i) {
        rewrite ^/report$ /report.php last;
    }
}
location = /send-to {
    if ($arg_i) {
        rewrite ^/send-to$ /send-to.php last;
    }
}
location = /autoresponders-emails {
    if ($arg_i) {
        rewrite ^/autoresponders-emails$ /autoresponders-emails.php last;
    }
}
location = /autoresponders-list {
    if ($arg_i) {
        rewrite ^/autoresponders-list$ /autoresponders-list.php last;
    }
}
location = /autoresponders-edit {
    if ($arg_i) {
        rewrite ^/autoresponders-edit$ /autoresponders-edit.php last;
    }
}
location = /segments-list {
    if ($arg_i) {
       rewrite ^/segments-list$ /segments-list.php last;
    }
}
location = /segment {
    if ($arg_i) {
       rewrite ^/segment$ /segment.php last;
    }
}
location = /create-template {
    if ($arg_i) {
       rewrite ^/create-template$ /create-template.php last;
    }
}
location = /edit-template{
    if ($arg_i) {
       rewrite ^/edit-template$ /edit-template.php last;
    }
}
location = /template-preview {
    if ($arg_i) {
        rewrite ^/template-preview$ /template-preview.php last;
    }
}
location = /new-list {
    if ($arg_i) {
        rewrite ^/new-list$ /new-list.php last;
    }
}
location = /subscribers {
     if ($arg_i) {
        rewrite ^/subscribers$ /subscribers.php last;
     }
}
location = /custom-fields {
     if ($arg_i) {
        rewrite ^/custom-fields$ /custom-fields.php last;
     }
}
location = /remove-duplicates {
     if ($arg_i) {
        rewrite ^/remove-duplicates$ /remove-duplicates.php last;
     }
}
location = /blacklist-blocked-domains {
     if ($arg_i) {
        rewrite ^/blacklist-blocked-domains$ /blacklist-blocked-domains.php last;
     }
}
location = /delete-from-list {
     if ($arg_i) {
        rewrite ^/delete-from-list$ /delete-from-list.php last;
     }
}
location = /blacklist-suppression {
     if ($arg_i) {
        rewrite ^/blacklist-suppression$ /blacklist-suppression.php last;
     }
}
location = /unsubscribe-from-list {
     if ($arg_i) {
        rewrite ^/unsubscribe-from-list$ /unsubscribe-from-list.php last;
     }
}
location = /update-list {
     if ($arg_i) {
        rewrite ^/update-list$ /update-list.php last;
     }
}
location ~ ^/housekeeping-(\w+)$ {
     rewrite ^/housekeeping-(\w+)$ /housekeeping-$1.php last;
}

access_log /var/log/nginx/sendy_access.log;
error_log /var/log/nginx/sendy_error.log;

listen 443 ssl http2;
ssl_certificate /path/to/your/ssl_certificate.crt;
ssl_certificate_key /path/to/your/ssl_certificate_key.key;
Enter fullscreen mode Exit fullscreen mode

}

server {
if ($host = your_sendy_domain.com) {
return 301 https://$host$request_uri;
}
listen 80;
server_name your_sendy_domain.com;
return 404;
}```

Save the file and create a symbolic link to it in the sites-enabled directory:

sudo ln -s /etc/nginx/sites-available/sendy.conf /etc/nginx/sites-enabled/

Test the NGINX configuration:

sudo nginx -t

If the test is successful, reload NGINX:

sudo service nginx reload

Step 2: Update Sendy Configuration

Edit the Sendy settings file:

nano /var/www/sendy/includes/config.php

Update the following lines with your server information:

```define('APP_PATH', 'https://your_sendy_installation_url');

/* MySQL database connection credentials (place values between the apostrophes) */
$dbHost = ''; //MySQL Hostname
$dbUser = ''; //MySQL Username
$dbPass = ''; //MySQL Password
$dbName = ''; //MySQL Database Name

/* Set this if you use a non standard MySQL port. */
$dbPort = 3306; ```

Save the changes and exit.

Step 3: Test the Configuration

Open your web browser and navigate to your Sendy domain. If everything is configured correctly, you should see the Sendy login page.

Billboard image

The Next Generation Developer Platform

Coherence is the first Platform-as-a-Service you can control. Unlike "black-box" platforms that are opinionated about the infra you can deploy, Coherence is powered by CNC, the open-source IaC framework, which offers limitless customization.

Learn more

Top comments (0)

Qodo Takeover

Introducing Qodo Gen 1.0: Transform Your Workflow with Agentic AI

Rather than just generating snippets, our agents understand your entire project context, can make decisions, use tools, and carry out tasks autonomously.

Read full post