How I Installed Postfix, Dovecot and Roundcube on my Bitnami LAMP Stack

In addition to my previous article about installing PostfixAdmin, I am now summing up my findings that I picked up along the way of installing Postfix, Dovecot and and Roundcube on my Bitnami LAMP stack.

To get it all working I had to go over a dozen of articles and tutorials, and a few days and some headaches later I was finally able to send and receive mail, although there are still some trust related challenges to overcome.

First and foremost, if you have followed some sort of tutorial, and haven’t got it working, I suggest you start from scratch. But even removing Postfix and Dovecot can be troublesome.

How to remove APT packages completely

When I was trying to remove and reinstall Dovecot I got the following kind of error messages:

Not replacing deleted config file /etc/dovecot/dovecot.conf

What ever I tried, they didn’t stop showing up on a new install. But eventually I found the trick, which is this sequence:

sudo apt-get remove dovecot-core dovecot-imapd
sudo dpkg -P dovecot-core
sudo dpkg -P dovecot-imapd
sudo rm -rf /etc/dovecot
sudo rm -rf /var/lib/dovecot
sudo apt-get --purge autoremove
sudo apt-get --purge autoclean

Then finally reinstalling with the following command:

sudo apt-get install dovecot-core dovecot-imapd

You will see the following kind of messages when it finally works:

Creating config file /etc/dovecot/dovecot.conf with new version

Installing Postfix

Basically, there is not much to it, however the configuration of Postfix is where the finetuning goes. First of all execute the following command to install it:

sudo apt-get install postfix
sudo postconf -e 'smtpd_sasl_local_domain ='
sudo postconf -e 'smtpd_sasl_auth_enable = yes'
sudo postconf -e 'smtpd_sasl_security_options = noanonymous'
sudo postconf -e 'broken_sasl_auth_clients = yes'
sudo postconf -e 'smtpd_recipient_restrictions = permit_sasl_authenticated,permit_mynetworks,reject_unauth_destination'
sudo postconf -e 'inet_interfaces = all'
sudo postconf -e 'smtp_tls_security_level = may'
sudo postconf -e 'smtpd_tls_security_level = may'
sudo postconf -e 'smtpd_tls_auth_only = no'
sudo postconf -e 'smtp_tls_note_starttls_offer = yes'
sudo postconf -e 'smtpd_tls_key_file = /opt/bitnami/apache2/conf/server.key'
sudo postconf -e 'smtpd_tls_cert_file = /opt/bitnami/apache2/conf/server.crt'
sudo postconf -e 'smtpd_tls_CAfile = /etc/ssl/certs/ca-certificates.crt'
sudo postconf -e 'smtpd_tls_loglevel = 1'
sudo postconf -e 'smtpd_tls_received_header = yes'
sudo postconf -e 'smtpd_tls_session_cache_timeout = 3600s'
sudo postconf -e 'tls_random_source = dev:/dev/urandom'
sudo postconf -e 'myhostname = yourdomain.com'

How to install JavaScript dependencies for Roundcube

First of all go to the Roundcube installation folder. If you did it the proper way you have installed Roundcube inside the /opt/bitnami/apps/ folder. After you have cd’ed into it, execute the following command to install all Roundcube JavaScript dependencies:

cd /opt/bitnami/apps/roundcube
sudo bin/install-jsdeps.sh

How to Install PostfixAdmin on a Bitnami LAMP Stack

I was been searching for this topic myself but didn’t find a good post/ tutorial, hence again I will provide you with a short briefing of my own findings while researching how to install PostfixAdmin on a Bitnami Ubuntu setup on AWS.

Credit is due where credit is deserved, and to be honest the following post on Linuxize has helped me a lot, although it had some challenges:

Some things to bear in mind are:

  • Check which version is the latest. The article says 3.1 while the latest PostfixAdmin release is 3.2.
  • All PostfixAdmin PHP files have moved to the postfixadmin/public/ directory, including upgrade.php, so make sure to update your path as follows:
/var/www/postfixadmin/public/upgrade.php
  • And finally, the PostfixAdmin-CLI has another add admin command, so I suggest you use the following which walks you through the configuration for adding a super user:
sudo bash /var/www/postfixadmin/scripts/postfixadmin-cli admin add

To make it work, you will have to set-up your VirtualHost configuration as follows:

<VirtualHost _default_:443>
  ServerName mail.domain.com
  DocumentRoot "/var/www/postfixadmin/public"

  SSLEngine on
  SSLCertificateFile "/opt/bitnami/apache2/conf/server.crt"
  SSLCertificateKeyFile "/opt/bitnami/apache2/conf/server.key"

  <Directory "/var/www/postfixadmin/">
    Options Indexes
    AllowOverride None

    <IfVersion < 2.3 >
      Order allow,deny
      Allow from all
    </IfVersion>
    <IfVersion >= 2.3 >
      Require all granted
    </IfVersion>
  </Directory>
</VirtualHost>

And finally, you can access the PostfixAdmin configuration panel on the subdomain you configured, which is mail.domain.com in the example given.

PHPMyAdmin 404 with Bitnami vhosts Enabled

Here’s a quick and neat solution if you are unable to access PHPMyAdmin after adding vhosts‘ on your Bitnami LAMP stack on, for example, when you’re hosting a site Amazon AWS or Google Cloud Platform. I came to this solution after doing some research, since the “Not Found” error was giving me a headache.

Basically, the only thing you need to do is to set up separate Virtual Hosts for each of your applications or websites. And to make sure that I don’t have to this research all-over, I am sharing my solution with you.

Make PHPMyAdmin great again!

First of all, remove (but make sure to copy your configuration so that you don’t have to do it all over) your Virtual Hosts from httpd-vhosts.conf, which is located here:

/opt/bitnami/apache2/conf/extra/httpd-vhosts.conf

Then, comment out the following line in your httpd.conf, just to do things the right way, as follows:

#Include conf/extra/httpd-vhosts.conf

Your httpd.conf is located here, by the way:

/opt/bitnami/apache2/conf/httpd.conf

Now, in your app – or website configuration folder, you will have to create a new httpdvhosts.conf file. I prefer to use the Nano editor. Here’s how it’s done:

sudo nano /opt/bitnami/apache2/htdocs/yourdomain.com/conf/httpd-vhosts.conf

OR

sudo nano /opt/bitnami/apps/yourapp/conf/httpd-vhosts.conf

Copy your previous Virtual Host configuration into this file and hit [ctrl]+[x] to exit and save the file.

Finally you need to include your newly created httpdvhosts.conf into the main Apache configuration file. Remember, it’s located here:

/opt/bitnami/apache2/conf/httpd.conf

Add either of the following lines, depending on your specific configuration, at the bottom of your httpd.conf file:

Include "/opt/bitnami/apache2/htdocs/yourdomain.com/conf/httpd-app.conf"

OR

Include "/opt/bitnami/apps/yourapp/conf/httpd-vhosts.conf"

That’s it. Restart Apache, and you will now be able to access both your Virtual Host and PHPMyAdmin on your Bitnami LAMP stack.

Installing Apache Module mod_maxminddb

On several of my sites, I target visitors based on their GEO location. To be able to do this I have installed an Apache module called mod_maxminddb which is the former mod_geoip2.

Installation is fairly easy. Download and extract the latest tarball file from Github:

For instance, get release 1.1.0 as follows:

wget https://github.com/maxmind/mod_maxminddb/releases/download/1.1.0/mod_maxminddb-1.1.0.tar.gz

Then extract the file to a temporary folder as follows:

tar xvzf mod_maxminddb-1.1.0.tar.gz

The next step is to install the module, so first ‘CD’ into the extracted directory, then follow these steps:

./configure
make install

The next step is to download the database and place it on your server. Again use wget and tar to do so, but first ‘CD’ to the proper directory where you want to store the mod_maxminddb database file:

wget https://geolite.maxmind.com/download/geoip/database/GeoLite2-City.tar.gz
tar xvzf GeoLite2-City.tar.gz

Finally, you have to enable it.

You can enable mod_maxminddb in your httpd.conf (/etc/httpd/conf/httpd.conf), in an include file such as httpd-phpmodules.conf (/etc/httpd/conf/extra/httpd-phpmodules.conf), or in an .htaccess file.

I personally prefer to put it in the include file. Here’s an example:

<IfModule mod_maxminddb.c>
    MaxMindDBEnable On
    MaxMindDBFile CITY_DB /usr/local/share/GeoIP/GeoLite2-City.mmdb

    MaxMindDBEnv MM_COUNTRY_CODE CITY_DB/country/iso_code
    MaxMindDBEnv MM_COUNTRY_NAME CITY_DB/country/names/en
</IfModule>

And now that we got it all working, here’s a real-life example of a site using the mod_maxminddb module:

You can see the flags on several locations determining if a visitor can use a certain betting site or not, and displaying the right content in the right order to visitors.

Create a Local Development Environment on a Mac

Open Terminal

I usually do this by open the search option and search for Terminal.

Install Homebrew aka Brew

The first thing we do is install Homebrew. With Homebrew you can really turn your Mac into the development machine of your dreams.

Here’s how you do it:

/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

Install Wget and Unzip

The next step is to install everything the other packages depend on. I am not getting into too much detail here. Here’s the list, just copy the command into Terminal and hit enter

Brew install wget
Brew install unzip
Brew install re2c

Install Apache

Brew install httpd

Add the Apache server to your start-up list so that it automatically starts when you reboot your Mac. Do this as follows:

brew services start httpd

Install and config PHP

Brew install php

Add PHP to your start-up list so that it automatically starts when you reboot your Mac. Do this as follows:

brew services start php

Edit php.ini. Mine is located in /usr/local/etc/php/7.3/.

Get SSH2 working on a Mac

Brew install openssl
Brew install libssh2

Download and install the PHP 7 module for SSH2. I personally like to keep my Mac as clean as possible, and if you also wish to do that I suggest you create a ‘src’ dir in your root, the CD into that dir and download and extract the zip file as stated below:

wget https://github.com/Sean-Der/pecl-networking-ssh2/archive/php7.zip
unzip php7.zip
cd pecl-networking-ssh2-php7
phpize
./configure
make
sudo make install

Now here comes the most tricky part of all.

If you are as unlucky as me you get a bunch of errors and warnings after running the make command. It took me half a day to figure out how to work around it, so here’s my solution:

The errors occur because they forgot to typecast variables in C, so we need to do this ourselves to get to the next step in this installation guide.

Edit ssh2_fopen_wrappers.c, I personally prefer doing this in an IDE like Visual Studio Code.

We only need to solve the errors, in my case three, since these are the reason the installation of the PHP module for SHH2 failed. I have bolded the invalid operants and will show you the fix below.

/src/pecl-networking-ssh2-php7/ssh2_fopen_wrappers.c:1248:42: error: invalid operands to binary expression (‘zend_string’ (aka ‘struct _zend_string’) and ‘int’)
if (resource->path && resource->path[0] == ‘/’) {

/src/pecl-networking-ssh2-php7/ssh2_fopen_wrappers.c:314:24: error: invalid operands to binary expression (‘zend_string’ (aka ‘struct _zend_string’) and ‘int’)
if (resource->host[0] == 0 && context &&

/src/pecl-networking-ssh2-php7/ssh2_fopen_wrappers.c:300:24: error: invalid operands to binary expression (‘zend_string’ (aka ‘struct _zend_string’) and ‘int’)
if (resource->host[0] == 0 && context && psftp &&

Looking at the details of the error message we can see that we need to typecast integers into strings, and therefore we wrap the (bolded) variables with typecast functions itoa().

  • itoa(resource->path[0]) == ‘/’
  • itoa(resource->host[0]) == 0
  • itoa(resource->host[0]) == 0

That’s it, we can now move on, run make once more, and finish this part of the installation by running sudo make install. But remember where the files are installed, you well need to use this location later. Mine are placed in /usr/local/Cellar/libssh2/1.8.0.

Edit php.ini again and add extension=ssh2.so.

Brew install autoconf

Install MySQL server

Brew install mysql

Again, if you want to have MySQL in your start-up list, you can do so with the following command:

brew services start mysql

The first time you will have to log in as the root user, and you don’t need a password.

mysql -u root

Once logged in we will have to create a new user, grant him the required privileges and the alter him so the user can also log into phpMyAdmin. Here’s how you do it:

CREATE USER 'giorgio'@'localhost' IDENTIFIED BY 'PASSWORD';

GRANT ALL PRIVILEGES ON *.* TO 'giorgio'@'localhost'
WITH GRANT OPTION;

ALTER USER 'giorgio'@'localhost' IDENTIFIED WITH mysql_native_password BY 'PASSWORD';

You can, of course, use any username, and don’t forget to change the default password ‘PASSWORD’ into something slightly more secured…

Since this is my development machine, I prefer to keep user root without a password. It might save me a lot of frustration at some point.

To exit MySQL you can type \q and hit enter.

Install PHPMyAdmin

To install PHPMyAdmin and make it work, you will also have to edit the httpd.conf file. Here are the steps to take:

Brew install phpmyadmin

To enable phpMyAdmin you will have to add the following code to httpd.conf:

Alias /phpmyadmin /usr/local/share/phpmyadmin
<Directory /usr/local/share/phpmyadmin/>
   Options Indexes FollowSymLinks MultiViews
   AllowOverride All
   <IfModule mod_authz_core.c>
      Require all granted
   </IfModule>
   <IfModule !mod_authz_core.c>
      Order allow,deny
      Allow from all
   </IfModule>
</Directory>

Finally, restart Apache and browse to http://localhost/phpmyadmin, and voilà!

Here’s a really good guide about SASS, I suggest you scan it to understand what SASS is all about.

Install SASS

If you are a web developer like me, you might find it cool to install SASS as well. Here’s how you do it with Homebrew:

brew install sass/sass/sass

(Note to self) Here’s how you compile and compress (minify) your sass files:

sass style.scss:../stylesheets/style.css --style compressed

Install Pure-FTPD

Brew install pure-ftpd

I will add some more details about creating a Pure-FTPD user and everything related. But first, here’s a bonus:

Add a domain to your host file for local development

sudo nano /etc/hosts

And add your domain as follows, pointing to 127.0.0.1 which is your localhost:

127.0.0.1    domain.com    www.domain.com

And don’t forget, you must also flush your Mac’s DNS cache with the following command:

sudo killall -HUP mDNSResponder

Install Laravel and Homestead

Step by step guide to install Laravel including Homestead:

  1. Download Composer
  2. Download (the installer) and install Laravel using the following command in Terminal:
    composer global require "laravel/installer"
  3. Download VirtualBox, then double-click the package to install it
  4. Download Vagrant, then double-click the package to install it
  5. Add the Vagrant box to Laravel using the following command in Terminal:
    vagrant box add laravel/homestead
  6. Make sure to pick choice 3 (which stands for the VirtualBox provider) when asked
  7. Clone the Homestead GIT repository using the following command in Terminal:
    git clone https://github.com/laravel/homestead.git ~/Homestead
  8. Change to the Homestead directory using the following command in Terminal:
    cd ~/Homestead
  9. Check out the latest Homestead GIT repository using the following command in Terminal:
    git checkout v7.17.0

    Note: Make sure to pick the latest stable Homestead GIT repository version here

  10. Terminal:
    bash init.sh

    Note: This will generate the initial Homestead.yaml file in the Homestead install directory, which I’ll explain in more details below

Homestead.yaml

The Homestead.yaml comes with default settings. The most important changes I make are folders, sites, and databases.

Folders

folders:
- map: path/to/your/host-os/directory
  to:  path/to/your/guest-os/directory

The host-os directory is where your project’s files will be stored. Here’s a real-life example:

folders:
- map: /Applications/MAMP/htdocs/vagrant/code/project1
  to:  /home/vagrant/code/project1

Sites

sites:
- map: project1.dev
  to:  /home/vagrant/code/project1/public

You must also edit your local host file, using the following Terminal command:

sudo nano /etc/hosts

For example:

192.168.10.10 project1.dev # The IP should be the same as set in the Homestead.yaml configuration file.

When ready use the following Terminal command:

vagrant up

Or in case of an edit use the following Terminal command:

vagrant reload --provision

Troubleshooting Homestead

If you have a headache to get Homestead running as it should, perhaps because of the “No input file specified.” message like I have experienced, here comes the solution:

  • folders: map is the actual location of your files, locally
  • folders: to is the location on your virtual machine
  • sites: map is the name of your project (this is a dummy domain, don’t forget to edit your hosts file)
  • sites: to is the location where your files are hosted on your virtual machine (comparable to the location on a remote server)

How to recover a deleted folder on a Mac

I accidentally deleted MAMP, including the htdocs folder containing most of my projects past my latest back-up dating from February 2018. This happened yesterday when I was making a back-up from my MacBook Pro which I wanted to reinstall from scratch after being sick of its slow performance.

I uninstalled MAMP actually, however, this should be kind of the same as deleting it. Now I want my files back! But how?

I am trying various kind of recovery programs and had some success before using Prosoft’s Data Rescue and TestDisk. So I am running these again.

For Data Rescue, I had to buy a new external hard drive (which I needed anyway) to create a so-called Data Recovery Drive. I first tried to install this on an SD card, but this seemed to take forever, so I canceled it. But also on the external HD, it is really bothering slow!

TestDisk, on the other hand, is a small app that runs in Terminal. It’s a little bit more complicated without a GUI, but the documentation is pretty clear. Best of all this one is free! The forum is also quite helpful, you can find it here. At the time being I have posted a question, and by the looks of it they even get answered, so let’s see how long it takes.

To be continued…

Updating mod_pagespeed can be a pain in the @ss

Just a quick reminder to self, since simply updating mod_pagespeed doesn’t seem to be able by just running yum update. If you have installed mod_pagespeed building from the source, as I have, you will probably run into the following issue:

"httpd >= 2.2 is needed by mod-pagespeed"

Here is a quick and dirty solution that has worked for me.

1) Remove the old version with this command:

yum remove mod-pagespeed-stable.x86_64

2) Follow these steps to update mod_pagespeed to the latest version:

cd ~
yum install at
wget https://dl-ssl.google.com/dl/linux/direct/mod-pagespeed-stable_current_x86_64.rpm
rpm -i --nodeps mod-pagespeed-stable_current_x86_64.rpm