MrCruz
By:
MrCruz

Which one to use for my App back-end: Nginx or Apache?

March 4, 2017 1.6k views
Apache Nginx Applications Ubuntu 16.04

I have this app/social network i'm about to launch.
The back-end uses PHP+ MySQL to serve the Mobile app (iOS and Android)
I read a lot of things but they are very confused. They are not CLEAR if an application using APACHE (get data from database receiving in json, load images, load and send messages, post text, etc) will really be faster just because it's a dynamic content WHEN we're scaling (like many people using at the same time).
Some say it's the same, some say apache is faster, some test i saw showed nginx faster than apache even for dynamic content when there's more than 10 requests at the same time.
Anyone would tell me if an API (php+mysql) for a mobile app would be faster on APACHE or NGINX? (DEFAULT installation, im not talking about ninja tricks)
??

1 comment
16 Answers
hansen March 4, 2017
Accepted Answer

@MrCruz
Apache with mod_php is a bit faster than Nginx with php-fpm.
I love the simplicity of Nginx and would always go with that. And I find it much easier setting up multiple Nginx in load balancing, which is great for scaling.

But talking about speed and serving dynamic content, then it really hasn't much to do with Apache or Nginx.
Since you need to make sure your application will respond as fast as possible, so it doesn't hold up one of the connections in Apache/Nginx.
So this leads us to PHP and MySQL.

You'll get much more difference in what version of PHP you're running. Nothing below version 7.0 is worth looking at, since it's almost twice as fast as earlier versions.

You might want to switch from MySQL to MariaDB, since it has some extra features.
And remember to create correct indexes in your database, since that can easily make 10x the speed difference.
Actually you should be using PostgreSQL with it's JSON storage, but that would be a big change, so let's skip that.

Make sure everything is cut to the bone and optimized. Optimization/tweaking/tuning actually makes a huge difference. If you're not interested in that, then just spend more on CPU/RAM and that'll "fix" it.

I would do a Nginx, php-fpm, MariaDB, and cache with memcached or Redis. All of these can be setup on the same server or each on their own server and multiplied for scale.

Dang, just reloaded and saw the typical great answer from @jtittle :-)

  • And even though .htaccess and .htpasswd might be convenient in Apache, they're actually one of the main reasons Apache is slower than Nginx.
    And the mod_rewrite in Apache is terrible compared to the simplicity of Nginx location regular expressions.

    • @hansen - Thanks -- much appreciated :-).

      That's definitely one reason Apache is normally slower than NGINX (.htaccess). Another is because of how mod_php works with Apache. Since it's a module, it's loaded in at runtime so if, for example, you've set PHP's Memory Limit to something such as 128-256M, each of the processes spawned by Apache can use up to that much -- it's not collective.

      So you could end up spawning a dozen processes each using 256M, which is 3GB of RAM -- that may be just enough to cause a crash/failure.

      Beyond that, configuring the MinServers, MaxSevers, ChildServers, etc is a pain. Yes, it's true that PHP-FPM has similar settings, but they are far easier to work with and much easier to troubleshoot.

      A little basic math (which is actually detailed in the configuration file that's used by default) and you're set. I can't say the same for Apache. What works one day may crash on you another :-). With PHP-FPM, if you configure it wrong, it probably won't even start -- which is better than running with configuration that may inevitably crash on you.

      Don't get me wrong, I'm not an NGINX snob. I use Caddy too -- though it's configuration is much like NGINX, so it was a easy transition.

      • Sorry for piggy bagging on your thread @MrCruz but think you'll learn even more from our geeky talk :)

        @jtittle
        I totally agree. mod_php is heavy on resources, but it does make requests faster than php-fpm, since everything is in memory. But it's few milliseconds of difference. And I too prefer the way php-fpm is configured and managed.

        I looked at Caddy a couple of months ago, but didn't know why I should use it compared to Nginx.
        One thing I've really been wanting to play with is HTTP/2 Server Push, which Nginx currently doesn't want to implement even though CloudFlare has provided some code.
        Caddy don't have that either - until 12 days ago! Now it supports Push - awesome!
        https://github.com/mholt/caddy/pull/1215

@MrCruz

Personally, I'd recommend NGINX over Apache. I find that configuring + optimizing NGINX is far less a chore than it is with Apache, it works out of the box with fastcgi using PHP-FPM (without having to use a module), and it's also very simple to configure as a web server, reverse proxy, or even a load balancer.

That being said, while the default configuration may work short-term, at some point, to achieve a level of performance needed for your application to scale, you will have to modify configuration and begin tweaking configuration files. There's really no way around that. The default configuration with NGINX and Apache is meant to get you started, but it's not really intended for full-on production usage.

The same can be said of PHP/PHP-FPM, MySQL/MariaDB/Percona, etc. Base or stock installations are just a means to get you started. At some point, you'll have to dive in or hire a sysadmin to do the work for you if you plan on scaling as there's only so many cases where you can throw hardware at an issue before it no longer works. In doing so, you'll also end up spending more trying to cope with load than you would hiring a sysadmin to manage it for you (if you're not comfortable or capable of working from the CLI on your own).

@MrCruz

LTS = Long-Term Support Release. This means that Ubuntu 16.04 will continue to receive updates for a period of 5 years from the date of release. A non-LTS release, such as 16.10, will not.

As far as Ubuntu 16.04 goes, the commands to add the MariaDB repository would be:

sudo apt-get install software-properties-common
sudo apt-key adv --recv-keys --keyserver hkp://keyserver.ubuntu.com:80 0xF1656F24C74CD1D8
sudo add-apt-repository 'deb [arch=amd64,i386,ppc64el] http://nyc2.mirrors.digitalocean.com/mariadb/repo/10.1/ubuntu xenial main'
sudo apt-get update
sudo apt-get -y install mariadb-server

@MrCruz

In regards to creating an API, neither NGINX or Apache would be handling any more than the initial request made by the user, which is then passed on to PHP (mod_php) or PHP-FPM (NGINX).

Your application would be responsible for handling everything else, such as encoding or decoding a JSON GET or POST request using PHP's json_encode() or json_decode() functions, differentiating the requests (i.e. GET, POST, HEAD, etc), querying MySQL using PDO or MySQLi, etc.

NGINX and Apache simply function as web servers. They accept an incoming request and route it to a location depending on your configuration, if possible, else they throw an error. That error can be one that is setup to be handled by NGINX or Apache using configuration, or your application can handle it by using native PHP functions.

NGINX, in my experience, uses far less CPU and RAM to serve requests than Apache does, which is also one reason I prefer and use it myself, as well as on client websites that I manage or am hired to setup.

If you have any other specific questions, feel free to ask, I'm always happy to help!

@jtittle and @hansen
Yeah i agree with booth of you.
My concerns really were if by choosing NGINX (over Apache), it would perceptibly affect the performance of the overall response of requests, "using standards at the beginning for nginx or apache" in case i get like 40k new users per week, for example.
I never used NGINX before, so i don't know.
And i really already know that most of the work is done by my code as you guys mentioned. I have scaled other apps with different servers, but in different scenarios. (i didn't have to setup all servers myself)
I pay the most attention to my codes than to anything else. And have created my own techniques over time.
I barely rely (or never) on the chosen platform, database or anything like that to deal with the logic, data processing, security, etc.

(I know most [99% are average] programmers will be like* "your code won't ever be better than theirs, don't re-invent the wheel"* but that i disagree)
Yet i know the importance of taking the advantages from whatever we're using, from hardware and low-level programming for performance. I started coding with c, c++ and Assembly. But i'm not a Masochist and like evolution too lol
It's cool that you guys mentioned MariaDB. I say MySQL but in fact i ALWAYS used MariaDB. So i'm happy you guys made it easier for me to decide keeping using it.
PHP 7 i saw some people saying devs should wait it gets older and more stable. But looks like it's a 100% GO, right? I will go for the PHP7.
So..
This time i want to set up the server myself for the beginning and only the essential for now.
IF my plan works, more money will be injected and of course, someone will be doing advanced settings modifications, etc as you guys wisely pointed out.

  • @MrCruz
    Just go with Nginx - if you bump into any problems, we're here to help.
    If you don't like it after first setup, it's fairly easy to change to Apache or another web server.

    You say, you expect 40k users per week. But is that the amount of requests to your app? Because that's the important thing, when talking loads/speeds/connectivity/etc.
    With a $20 single server, unless your app is extremely heavy, you should easily be able to serve 2-4 million requests per month.
    That's about 1-2 request per second. But if you have peak periods, then you might need to tweak, scale or add cache/etc.

    Cool with MariaDB - when you have time, look into PostgreSQL - it's JSON feature might be something you want to play with. And use MariaDB 10.1 (it's highly stable - I'm using it in many high load projects, but looking forward to 10.2)
    After a few days with high activity, try running this tuner - and see what it recommends - and run it again on a weekly basis for a month or every time you make big schema/query changes.
    https://github.com/major/MySQLTuner-perl

    About PHP - it's BS to say version 7 is not stable. It's very stable. There has just been some changes, which did so older code didn't work, so that's why people didn't like it in the beginning. Compared to HHVM, it's a lot more stable. And it's even faster.
    I'm running 7 and 7.1 in high production and I find it just as stable as 5.6
    Since you control all your code, then I would recommend 7.1 - you'll see instantly if anything is failing, by going through the logs - and your app not working :)

    @jtittle Anything you think I missed - or you want to give your take on?

@jtittle @hansen
I need some help.
While trying to install the NGINX i got this error:

Job for nginx.service failed because the control process exited with error code. See "systemctl status nginx.service" and "journalctl -xe" for details.
invoke-rc.d: initscript nginx, action "start" failed.
dpkg: error processing package nginx-core (--configure):
 subprocess installed post-installation script returned error exit status 1
dpkg: dependency problems prevent configuration of nginx:
 nginx depends on nginx-core (>= 1.10.0-0ubuntu0.16.04.4) | nginx-full (>= 1.10.0-0ubuntu0.16.04.4) | nginx-light (>= 1.10.0-0ubuntu0.16.04.4) | nginx-extras (>= 1.10.0-0ubuntu0.16.04.4); however:
  Package nginx-core is not configured yet.
  Package nginx-full is not installed.
  Package nginx-light is not installed.
  Package nginx-extras is not installed.
 nginx depends on nginx-core (<< 1.10.0-0ubuntu0.16.04.4.1~) | nginx-full (<< 1.10.0-0ubuntu0.16.04.4.1~) | nginx-light (<< 1.10.0-0ubuntu0.16.04.4.1~) | nginx-extras (<< 1.10.0-0ubuntu0.16.04.4.1~); however:
  Package nginx-core is not configured yet.
  Package nginx-full is not installed.
  Package nginx-light is not installed.
  Package nginx-extras is not installed.

dpkg: error processing packagNo apport report written because the error message indicates its a followup error from a previous failure.
                                   e nginx (--configure):
 dependency problems - leaving unconfigured
Processing triggers for systemd (229-4ubuntu16) ...
Processing triggers for ureadahead (0.100.0-19) ...
Processing triggers for ufw (0.35-0ubuntu2) ...
Errors were encountered while processing:
 nginx-core
 nginx
E: Sub-process /usr/bin/dpkg returned an error code (1)

What should i do?

  • @MrCruz
    How did you install it? apt install nginx ? It should say it needs to install a handful of other things, which you should say yes to.

    • yes i used:
      sudo apt-get update
      sudo apt-get install nginx

      From the site's tutorial lol

      • That's the first time ever I've seen that fail - it's like it doesn't try to install the dependencies.
        Can you try with sudo apt-get install nginx-full

        • @hansen

          Preparing to unpack .../nginx-full_1.10.0-0ubuntu0.16.04.4_amd64.deb ...
          Unpacking nginx-full (1.10.0-0ubuntu0.16.04.4) ...
          Processing triggers for man-db (2.7.5-1) ...
          Setting up nginx-full (1.10.0-0ubuntu0.16.04.4) ...
          Job for nginx.service failed because the control process exited with error code. See "systemctl status nginx.service" and "journalctl -xe" for details.
          invoke-rc.d: initscript nginx, action "start" failed.
          dpkg: error processing package nginx-full (--configure):
           subprocess installed post-installation script returned error exit status 1
          dpkg: dependency problems prevent configuration of nginx:E: Sub-process /usr/bin/dpkg returned an error code (1)
          

          This is weird. Maybe my droplet already has Apache, is it possible to be the problem?
          The only thing i picked pre-installed for Ubuntu was the PHPMyAdmin.

@MrCruz

What I would do is start fresh. Deploy a clean Ubuntu 16.04 64bit image and start off running:

apt-get update
apt-get -y upgrade
apt-get -y install nginx

or copy and paste:

apt-get update && apt-get -y upgrade && apt-get -y install nginx

Once NGINX is installed, you'll find all the available configuration in /etc/nginx.

The nginx.conf file is the main configuration file for NGINX -- this is where you can really tweak and tune NGINX to perform better.

The sites-available directory is the main directory where config files for your website(s) are stored. They are symlinked to the sites-enabled directory (you have to do this by hand, except for the default which is already done for you) and as per nginx.conf, it'll load all configuration from this directory.

From there, it's a matter of setting up actual configuration for your website either in the default.conf configuration file, or a new one.

  • Thanks! @jtitle @hansen
    Now my problem is correctly install MariaDB.
    Do you have a step-by-step to install it on DigitalOcean droplet correctly?

    • Make sure you didn't accidentally add MySQL while installing PHP. But MariaDB should complain if it's installed during installation (I think).
      I generally install MariaDB first, then Nginx and then PHP-FPM.

      I'm not completely sure if this key is still valid for the general mirror, otherwise go to https://downloads.mariadb.org/mariadb/repositories/ and find the mirror in your data center and scroll down to see the key and repository. It's official repositories.

      sudo apt-key adv --recv-keys --keyserver hkp://keyserver.ubuntu.com:80 80E7349A06ED541C
      sudo add-apt-repository 'deb [arch=amd64,i386] http://mirrors.digitalocean.com/mariadb/repo/10.1/ubuntu trusty main'
      
      sudo apt-get update
      sudo apt install mariadb-server
      

      If you add the following official repository, then you'll always get the stable version of Nginx - instead of version 1.10.x included in Ubuntu 16.04

      sudo add-apt-repository ppa:nginx/stable
      
      sudo apt-get update
      sudo apt install nginx
      

      I don't think you can install PHP 7.1 on Ubuntu 16.04 without the following repository - otherwise you will get 7.0
      But do note that this is an un-official repository. Though it's massively used by many people and is referenced in almost every PHP tutorial on DigitalOcean.

      sudo LC_ALL=C.UTF-8 add-apt-repository ppa:ondrej/php
      

      Depending on what you need in PHP, you should only install the modules you need. If you are installing 7.1, then replace all 7.0 below. This is a list of common modules, which allows you to use many frameworks (or phpMyAdmin) without them complaining about missing modules. I've only tested this list with the ppa:ondrej/php repository listed above.

      sudo apt-get update
      sudo apt install php7.0 php7.0-common php-common php-gettext php-pear php7.0-fpm php7.0-cli php7.0-mysql php7.0-curl php7.0-gd php7.0-intl php7.0-json php7.0-mcrypt php7.0-readline php7.0-opcache php7.0-mbstring php7.0-xml php7.0-zip php7.0-bz2 php7.0-soap
      

      And finally, just for good measures. This will update the index, do upgrades (also kernel upgrades), remove non-used packages, and cleanup old downloaded packages - and finally reboot:

      sudo apt-get update
      sudo apt-get dist-upgrade
      sudo apt-get autoremove
      sudo apt-get autoclean
      
      sudo reboot
      
    • @MrCruz

      MariaDB can be installed using:

      apt-get -y install mariadb-server
      

      Once the installation is complete, you'll want to run:

      mysql_secure_installation
      

      ... from the CLI to set a root password.

      As far as PHP goes, I prefer 7.1.x, and I use the ppa:ondrej/php repo to stay up to date. You can add it using:

      add-apt-repository -y ppa:ondrej/php
      

      You'll then need to update/sync the packages:

      apt-get update
      

      Once the update finishes, you can run the command below to search for all available packages for that PHP version:

      apt-cache search php7.1 --names-only
      

      At minimum, you'll want to install php7.1-fpm, php7.1-cli, and php7.1-mysql, though I tend to install quite a few more than that, which you could do by using:

      apt-get -y install php7.1-cli php7.1-dev php7.1-fpm php7.1-bcmath php7.1-bz2 php7.1-common php7.1-curl php7.1-gd php7.1-gmp php7.1-imap php7.1-intl php7.1-json php7.1-mbstring php7.1-mysql php7.1-readline php7.1-recode php7.1-soap php7.1-sqlite3 php7.1-xml php7.1-xmlrpc php7.1-zip php7.1-opcache php7.1-xsl php-yaml
      

@hansen @jtittle
Guys, i found from MariaDB website.
16.10 "yakkety"
16.04 LTS "xenial"
I have Ubuntu 16.04 .. Should i get the MariaDB 16.10 ?
What's the LTS stand for here?

  • No!
    You should only install packages that matches your operating system. And you've installed Ubuntu 16.04 Xenial.
    LTS means Long Term Support, which in Ubuntu terms means that they'll support the system with security updates for 5 years. For 16.04 it's supported until April 2021.
    https://wiki.ubuntu.com/Releases

@hansen @jtittle
Guys, THANK YOU VERY VERY MUCH..
IT IS WORKING LIKE A CHARM.. Everything
MariaDB, PHP, Nginx, HTTPS .. my app connected using secure connection.. pretty cool..
Now, there's only one thing bothering me.. the Mailing from PHP.. idk if i installed the sendmail wrong.. idk.. but it isn't working as it does at my old server.
My PHP signup script has to send an email to the user.. The MX records are already set and working with gmail account.
But currently the PHP mailing isn't working
Do you guys have anything for me to allow my PHP script to send emails?

  • @MrCruz Awesome!
    I can only recommend using Postfix, and having it relay the mail to Google Apps, Mailgun, Amazon SES, or another quality provider you're using. Postfix is also a drop-in-replacement to sendmail (just like MariaDB is to MySQL).

    @jtittle Do you agree?

    I would not recommend sending mails from your droplet directly to the receiver, since there would be a high chance of the mail ending up in their spam-folder.

    Mail is difficult. In one of my companies, we send about 200k mails per day. That has taken me countless days to get it right and to make sure we weren't marked as spam. And I still use an external provider for relaying.

    By the way, when you think you've setup everything, I would actually recommend that you take a snapshot of the server and re-install a clean Ubuntu and start all over. Just to make sure you've nailed everything and written everything down (in case of disaster). I know you probably don't have time, but it's a life saver to have good notes. And please, please, please remember to have multiple backups.

    • @hansen @MrCruz

      I would definitely recommend using Google Apps (G Suite), MailGun, SendGrid, or Amazon for mail over trying to setup up a mail server. While their are bash scripts and various other applications that will do it for you, it's not the setup that's the hard part -- it's management.

      Keeping up with SPF, DKIM, DMARC, and whatever new tech that comes out in the not too distant future can be a lot to manage when coupled with tweaking spam filters, IP blocks, preventing bounces/delays, etc.

      The services above manage the majority of those for you. You'll have to add a few entries to your DNS zone, though beyond that, you'll use their SMTP server(s), IP ranges, etc. If you're actually developing your own application, I would recommend getting familiar with one of the API's and using it over SMTP. You'll have far more control over how mail gets sent and received than you do with just SMTP.

      MailGun has a very simple API, probably the most simplistic of them all. I've worked with it in the past (PHP) and it really wasn't all that hard to setup and run.

@hansen @jtittle
Boy i feel dumb. EVERYTHING works fine but the damn PHP mailing (using smtp trying to login to google account - G Suite)
I tried Postfix and Sendmail many times, installing and re-installing, one or the other or both.
None get my PHP code to work. With sendmail using terminal it says it works (it shows sent mails) but it doesn't send emails to anybody. And i need it to be done through PHP code.
But using gmail.com the account i created using my domain, it works just fine. It receives emails and it sends emails.
But can't even use any Mail.php or anything similar to connect to via smtp using PHP.
I feel like it's something very small and stupid that i missed.

@MrCruz Hmmm....
If you've installed Postfix, then Sendmail isn't used any longer. But I have no idea if you've messed around in some of the general files used by both - like /etc/mailhost and more.

If you only have access to a regular Gmail account (gmail.com), then that is not going to suffice and will also look unprofessional. And I don't remember the limit on Gmail, but I think it's 500 mails per day. When I said Google Apps (aka G Suite, stupid name), it has a much higher limit and will send as yourdomain.tld
I agree with @jtittle that using an API to send mail will give you more control, but I usually recommend SMTP-relays, since it allows you to connect to almost every application.
You need something that will allow you to send 40k emails weekly at minimum, since that's the number of new users you expect - and you want to send from welcome@yourdomain.tld - so Gmail is not an option at all. Mailgun, SendGrid, Amazon SES will allow that, and I'm actually unsure if Google Apps will allow that limit.

And you need to show the failure of your PHP mailing script - add debug level.
If PHP doesn't fail (makes a script failure), then we need to see /var/log/mail.log and /var/log/mail.err

  • It is not Gmail, It is G Suite..
    G Suite (according to the site) allows 2000 emails per day.
    I was checking on Mailgun.
    I believe i'm gonna use it instead. $$$$

    • It's actually higher - but the number is a bit fussy, since it depends on the amount of user account you have in your Suite, but in general don't expect more than 10k/day:
      https://support.google.com/a/answer/2956491

      If you've setup a working SMTP-relay on your end, then you can start out with Suite unless you expect the user sign-up rate to explode very rapidly.

      I'm using different external providers for different projects - both Suite, Mailgun, Aweber and lesser known country specific providers. Suite works great if you don't have massive loads.
      I used Mandrill until MailChimp bought them - now I use Mailgun instead.
      And I'm trying to play around with Sendy.co but not ready to give it thumbs up or down yet.

      It all comes down to what type of communication you need to do and how you want it integrated.
      Like we said - mail is difficult - so choosing a provider that fits your needs will make your life much easier.
      After you've setup everything, then validate your email sending with a tool:
      https://dmarc.org/resources/deployment-tools/#Message_Validation

@MrCruz @hansen

Quick note about G Suite and using SMTP Relay -- via
https://support.google.com/a/answer/2956491#sendinglimitsforrelay

"A registered G Suite user can't relay more than 10,000 messages in a 24-hour period, and can't relay messages to more than 10,000 unique recipients per 24-hour period. Users exceeding either of these limits see the error 550 5.4.5 Daily SMTP relay limit exceeded for user."

...

If you're using PHP's mail() function alone, that's going to be your issue. Your best option would be to use something like SwiftMail or PHPMailer, which will allow you to connect over SMTP with ease.

...

Why? PHP's mail function can be setup to use defined configuration in your php.ini file, though it's a hassle and what you set there applies globally. If you need to change, you have to modify that file to instead of simply defining in-app. There's really no reason to use php.ini as it's counterproductive (in this specific case).

Unless you have a valid, working local mail server setup with at least SPF + DKIM (confirmed valid), the majority of mail sent will land in SPAM/Junk, if it's not rejected altogether.

The reason for the above is pretty simple; it's super-easy to abuse PHP's mail() function and it takes very little code to do it. A simple foreach() or while() loop with a timer could send tens of thousands of e-mails in no time.

For example, let's look at something very basic. This won't actually work as there's no data -- even with data, it's still relying on PHP's mail() function, so it'll all go to SPAM/Junk, but it serves a purpose for this example.

Note: This is a quick 5 minute script, it's not meant to be clean, pretty, etc. It's just an example :-).

<?php
/**
 * Returns a random key from the provided array.
 */
function pickRand( array $from )
{
    return array_rand( $from );
}

/**
 * Sends way too many e-mails. If this actually caused mail to
 * land in a users inbox, it'd be relatively easy to flood an
 * inbox in seconds or minutes.
 */
function mailBomb( array $to, array $subjects, array $messages, $delay = 5 )
{    
    foreach ( $to as $recipient )
    {
        $subjectKey = pickRand( $subjects );
        $message    = ( array_key_exists( $randomSubjectKey, $messages ) )
                    ? $messages[ $randomSubjectKey ]
                    : $messages[ pickRand( $messages ) ];

        foreach ( $to as $recipient )
        {
            mail(
                $recipient,
                $subjects[ $subjectKey ],
                $message,
                'From: well.known@company.com' . "\r\n" .
                'Reply-To: fake.email@spammer.com'
            );

            sleep( $delay );
        }
    }
}

/**
 * Fictional array containing 10,000+ e-mail addresses.
 * i.e. user.name@domain.ext ...
 */
$to         =   [];

/**
 * Fictional array containing 10,000+ e-mail subjects.
 * i.e. You've Won XYZ from PBC....
 */
$subjects   =   [];

/**
 * Fictional array containing 10,000+ e-mail messages.
 * For the purpose of this example, the key would match
 * a key in our $subject array.
 */
$messages   =   [];

/**
 * Run mailBomb Function
 */
mailBomb( $to, $subjects, $messages );

Now, the above would easily send any number of e-mails with a randomly selected subject and message using a fake e-mail as the sender (which may appear as if it's coming from a reputable company) and a reply-to set as the spammers e-mail. If you didn't look at the headers (and most people don't), you might just reply.

Now you might say well when they reply back, they'll reveal their real e-mail; not so. They could be filtering e-mail through a PHP script and then sending mail back out through another designed to keep the forged e-mail in-tact.

That's why you don't use mail() alone and why you either:

1). Setup a real mail server (on a separate server) and make sure it's in working order, or;

2). Use MailGun, SendGrid, Amazon, etc.

When combined with the mail libraries I noted above, those in #2 will help you to land your e-mail where it belongs instead of troubleshooting #1.

  • @MrCruz

    That said, as @hansen mentioned, and if you're dead-set on running your own mail server over using an external provider, I would run Postfix over Sendmail. You need to setup SPF and DKIM at the minimum, but that's really just the start.

    Beyond SPF, DKIM, and potentially DMARC, your PTR (Reverse DNS) record also comes in to play with many providers (Google, Yahoo, Outlook, etc). An invalid PTR, or a PTR that points to a server that's different than what's expected can also result in mail being rejected.

    PTR records are setup when you create a Droplet. When you name your Droplet, you'd need to name it using a Fully Qualified Domain Name or Hostname.

    i.e. instead of using mail as the name of your Droplet, you'd use mail.yourdomain.com as that's what will correctly set your PTR record at DigitalOcean; only using mail won't work. This also applies to any Droplet. You could name it web01 and the PTR wouldn't actually be valid since it doesn't resolve to a FQDN; you'd need to use web01.yourdomain.com.

    It sounds like a lot and I am by no means trying to deter you from running your own mail server, but there's a lot of work that goes in to it, and afterwards, a lot of maintenance.

    Scripts/Applications such as MailCow do make the setup a bit more simple, but they don't take all of the management out of the service. You'd still need to know how to troubleshoot, update, upgrade, patch, etc -- in addition to responding to any complains for SPAM.

    External providers, such as those mentioned, take all the hassle out of the process and let you either use SMTP on their servers, or an API that you can integrate.

@jtittle @hansen
Do you guys know if it's true that ONLY MySQL (after 5.7.5) can have InnoDB with spatial indexes and MariaDB and Percona can't?
If they can't i will switch to MySQL.. localized index is a huge point for my design.I can't ignore it

@MrCruz

"On MyISAM and Aria tables, as well as on InnoDB tables from MariaDB 10.2.2, MariaDB can create spatial indexes (an R-tree index) using syntax similar to that for creating regular indexes, but extended with the SPATIAL keyword. Currently, columns in spatial indexes must be declared NOT NULL."

https://mariadb.com/kb/en/mariadb/spatial-index/

  • Error
    SQL query:

    ALTER TABLE General ADD SPATIAL INDEX(gps)
    MySQL said: Documentation

    1464 - The storage engine InnoDB doesn't support SPATIAL indexes
    • damnit.. it's 10.1 . it needs 10.2

      • @MrCruz
        10.2 is very close to become stable - I'm using it in a project, which is set to launch in a month or so, since I believe it's stable enough.
        You're the first person I've come across, that knows anything about this - cool!

      • It sucks because in fact i wanted to switch over to Percona (because of the fast InnoDB ) but it seems like Percona doesn't have it.. and i can't find people even talking about Percona and InnoDB with Spatial Indexes

        • @MrCruz
          But are you using it for geo data - if so, then PostgreSQL is probably much closer to what you want, since it has GIS and JSON.
          Not that you should change right now, just have a look at it at some point. Try MariaDB 10.2 - if you don't like it, just uninstall it and install MySQL 5.7.5+

          • I will do it. But have you heard of Percona with InnoDB and Spatial Indexes? They don't even talk about it in their forums.. it's weird,. they talk about Mysql but not about Percona dealing with it

          • @MrCruz No, I can't find any info on that, but after MariaDB came to life, I stopped using Percona.

@MrCruz

Yeah, it's only on 10.2.x right now, which is an RC (Release Candidate) -- thus it may not be as stable.

You can remove the existing repository by removing the entry from either:

/etc/apt/sources.list

or by removing the file from:

/etc/apt/sources.list.d/

and then add the 10.2.x repository using:

sudo add-apt-repository 'deb [arch=amd64,i386,ppc64el] http://nyc2.mirrors.digitalocean.com/mariadb/repo/10.2/ubuntu xenial main'
sudo apt-get update
service mysql stop
sudo apt-get -y upgrade

Which should upgrade the release for you.

  • Do i have to re-install the PhpMyAdmin? It stopped working.. can't login after the upgrade

    • What does the error log say? /var/log/nginx/error.log - unless you've changed it.

      • Via Browser PhpMyAdmin login:

        2002 - No such file or directory
        The server is not responding (or the local server's socket is not correctly configured).

        Connection for controluser as defined in your configuration failed.

      • I just fixed it.. I just had to reboot the MariaDB.. it was down

  • No Spatial Index allowed//
    I checked the version:

    ii libmariadbclient18 10.1.21+maria-1~xenial amd64 MariaDB database client library
    ii mariadb-client-10.1 10.1.21+maria-1~xenial amd64 MariaDB database client binaries
    ii mariadb-client-core-10.1 10.1.21+maria-1~xenial amd64 MariaDB database core client binaries
    ii mariadb-common 10.2.4+maria~xenial all MariaDB database common files (e.g. /etc/mysql/conf.d/mariadb.cnf)
    ii mariadb-server 10.1.21+maria-1~xenial all MariaDB database server (metapackage depending on the latest version)
    ii mariadb-server-10.1 10.1.21+maria-1~xenial amd64 MariaDB database server binaries
    ii mariadb-server-core-10.1 10.1.21+maria-1~xenial amd64 MariaDB database core server files

    Why do i have both?

      • @MrCruz

        Since 10.1.x is still showing up, you may need to fully remove all MariaDB packages and then reinstall. Normally upgrading takes care of this for you, though it appears not this go around.

        You'd want to run the following command (read the rest of this post first).

        sudo apt-get remove mariadb*
        

        Which will remove all packages. Unlike purge, this won't remove configuration or DB's, though I always recommend that you backup all databases before removing, so do that first.

        Then you can run the installer again:

        apt-get -y install mariadb-server
        

        If you want to fully wipe all packages, configuration and databases, and start clean, you can also purge. This will basically allow you to start clean.

        NOTE: Make absolutely sure you have valid backups of any data/databases as this will remove it all -- there's no recovery option here.

        apt-get -y purge mariadb*
        

        After the purge, you'd run the same install command.

        • SWEEEET @jtittle !
          Thanks bro!
          Now i have the Spatial Index working..
          But in a retrospect, i remember that Percona worked faster with InnoDB when making a lot of requests.
          I will investigate if they have something related to that.
          I believe it's the XtraDB, but i'm not sure. It doesn't seem to come with the Percona Server.. looks like something i have to add or something.
          About the MariaDB RC..
          Is it stable enough? It looks like it is.. anyways, it's working alright here

          • @MrCruz

            Generally RC's are stable, but not final. Some things could change, other things could be added, etc. Generally it's stable enough for use, but not always the best choice for full blown production unless you're capable of troubleshooting and willing to keep up with releases are they are made.

            For example, you may upgrade from the current RC to another RC release 4-5 times (or more) before it hits final. In such a case, you'd be removing and upgrading to make sure you stay current that many times.

            If you want a release that is deemed stable and don't want to hassle yourself with upgrading multiple times, an RC probably isn't the best choice (regardless of what you choose to use -- MySQL, MariaDB, or Percona).

          • @MrCruz
            MariaDB version 10.0.9+ actually uses XtraDB, but it might be branded as InnoDB.
            https://mariadb.com/kb/en/mariadb/xtradb-and-innodb/
            MariaDB and Percona actually share a lot of code and features. I would use Percona if I needed their consultant services, since they seems great, but MariaDB has also gotten that service, so I'm unsure which one to go with now.

Have another answer? Share your knowledge.