How To Install Linux, Apache, MySQL, PHP (LAMP) Stack on Debian 9 Stretch

I

am a new user of Debian 9 operating system. Can you tell me how to setup and install LAMP stack on a Debian 9 (Stretch)?

 

LAMP is an acronym for four open source software frequently used to develop the web applications (such as forums, blogs, and business sites):

Linux operating system

Apache web server

MySQL/MariaDB relational database management system (RDBMS)

PHP server-side programming language

This tutorial shows you how to install LAMP (Apache version 2, PHP version 7, MariaDB version 10.2) stack on a Debian 9 Linux server along with firewall settings to open tcp port 80, 22, and 443.

Step 1: Apply patches if any

Type the following apt-get command/apt command to update the system:

$ sudo apt update

 

Sample outputs:

Hit:1 http://security.debian.org stretch/updates InRelease

Hit:2 http://cdn-fastly.deb.debian.org/debian stretch InRelease

Reading package lists… Done

Building dependency tree

Reading state information… Done

38 packages can be upgraded. Run  apt list –upgradable  to see them.

To patch it with the latest updates, run:

$ sudo apt-get upgrade

 

Sample outputs:

Reading package lists… Done

Building dependency tree

Reading state information… Done

Calculating upgrade… Done

The following packages will be upgraded:

apt bash debconf debian-archive-keyring debianutils dpkg file gcc-6-base init init-system-helpers libapt-pkg5.0 libc-bin libc-l10n libc6 libcryptsetup4 libdns-export162

libelf1 libgcc1 libgcrypt20 libisc-export160 libmagic-mgc libmagic1 libpam-modules libpam-modules-bin libpam-runtime libpam0g libssl1.0.2 libssl1.1 libstdc++6

libsystemd0 libudev1 locales login multiarch-support passwd perl-base systemd systemd-sysv

38 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.

Need to get 26.3 MB of archives.

After this operation, 82.9 kB of additional disk space will be used.

Do you want to continue? [Y/n] y

Get:1 http://cdn-fastly.deb.debian.org/debian stretch/main amd64 debianutils amd64 4.8.1.1 [100 kB]

Get:2 http://cdn-fastly.deb.debian.org/debian stretch/main amd64 bash amd64 4.4-5 [1427 kB]

….

..

Setting up libmagic1:amd64 (1:5.30-1) …

Setting up libssl1.0.2:amd64 (1.0.2l-2) …

Processing triggers for libc-bin (2.24-11) …

Setting up libssl1.1:amd64 (1.1.0f-3) …

Setting up libc-l10n (2.24-11) …

Setting up locales (2.24-11) …

Generating locales (this might take a while)…

en_US.UTF-8… done

Generation complete.

Setting up init (1.48) …

Setting up libdns-export162 (1:9.10.3.dfsg.P4-12.3) …

Setting up file (1:5.30-1) …

Processing triggers for libc-bin (2.24-11) ..

Step 2: Install Apache http server

Type the following command:

$ sudo apt install apache2

 

Sample outputs:

Reading package lists… Done

Building dependency tree

Reading state information… Done

The following additional packages will be installed:

apache2-bin apache2-data apache2-utils libapr1 libaprutil1 libaprutil1-dbd-sqlite3 libaprutil1-ldap liblua5.2-0 ssl-cert

Suggested packages:

www-browser apache2-doc apache2-suexec-pristine | apache2-suexec-custom openssl-blacklist

The following NEW packages will be installed:

apache2 apache2-bin apache2-data apache2-utils libapr1 libaprutil1 libaprutil1-dbd-sqlite3 libaprutil1-ldap liblua5.2-0 ssl-cert

0 upgraded, 10 newly installed, 0 to remove and 0 not upgraded.

Need to get 0 B/2143 kB of archives.

After this operation, 7137 kB of additional disk space will be used.

Do you want to continue? [Y/n] y

ebconf: delaying package configuration, since apt-utils is not installed

Selecting previously unselected package mime-support.

(Reading database … 13992 files and directories currently installed.)

Preparing to unpack …/00-mime-support_3.60_all.deb …

Unpacking mime-support (3.60) …

Selecting previously unselected package libapr1:amd64.

….

..

Enabling module filter.

Enabling module deflate.

Enabling module status.

Enabling module reqtimeout.

Enabling conf charset.

Enabling conf localized-error-pages.

Enabling conf other-vhosts-access-log.

Enabling conf security.

Enabling conf serve-cgi-bin.

Enabling site 000-default.

Created symlink /etc/systemd/system/multi-user.target.wants/apache2.service ? /lib/systemd/system/apache2.service.

Created symlink /etc/systemd/system/multi-user.target.wants/apache-htcacheclean.service ? /lib/systemd/system/apache-htcacheclean.service.

Processing triggers for libc-bin (2.24-11) …

Processing triggers for systemd (232-25) …

You can view default page by typing the IP address of your server. To find the IP address of your server use the ip command/ifconfig command as follows:

$ ifconfig eth0

$ ip a show eth0

$ ip a show eth0 | grep -w inet

 

Sample outputs:

inet 10.114.13.8/24 brd 10.114.13.255 scope global eth0

Fire a web browser and type the following url:

http://10.114.13.8

 

Sample outputs:

Fig.01: Default Debian 9 Apache 2 page

 

The Apache HTTP server successfully installed on your server. You can change the default page by editing the index.html file located in /var/www/html/ directory:

$ sudo vi /var/www/html/index.html

How do I stop/start/restart/reload Apache HTTP server?

The syntax is as follows:

$ sudo systemctl {start|stop|restart|reload|status|graceful-stop|force-reload} apache2

 

To stop Apache 2 server, run:

$ sudo systemctl stop apache2

 

To start Apache 2 server, run:

$ sudo systemctl start apache2

 

To restart Apache 2 server, run:

$ sudo systemctl restart apache2

 

To reload Apache 2 server, run:

$ sudo systemctl reload apache2

 

To see status of Apache 2 server, run:

$ sudo systemctl status apache2

 

Fig.02: Controlling Apache 2 server with systemctl command

How do I change configuration of Apache HTTP server?

You need to edit files located in /etc/apache2/ directory:

$ cd /etc/apache2/

$ ls -l

 

Sample outputs:

total 32

-rw-r–r– 1 root root  7224 Jan 25 22:59 apache2.conf

drwxr-xr-x 2 root root     7 Jun 13 18:46 conf-available

drwxr-xr-x 2 root root     7 Jun 13 18:46 conf-enabled

-rw-r–r– 1 root root  1782 Jan 25 21:16 envvars

-rw-r–r– 1 root root 31063 Jan 25 21:16 magic

drwxr-xr-x 2 root root   138 Jun 13 18:46 mods-available

drwxr-xr-x 2 root root    31 Jun 13 18:46 mods-enabled

-rw-r–r– 1 root root   320 Jan 25 21:16 ports.conf

drwxr-xr-x 2 root root     4 Jun 13 18:46 sites-available

drwxr-xr-x 2 root root     3 Jun 13 18:46 sites-enabled

You need to edit or add a new config file in /etc/apache2/conf-available/ directory. Here is a default config file:

$ cat /etc/apache2/sites-enabled/000-default.conf

 

Sample outputs:

<VirtualHost *:80>

# The ServerName directive sets the request scheme, hostname and port that

# the server uses to identify itself. This is used when creating

# redirection URLs. In the context of virtual hosts, the ServerName

# specifies what hostname must appear in the request s Host: header to

# match this virtual host. For the default virtual host (this file) this

# value is not decisive as it is used as a last resort host regardless.

# However, you must set it for any further virtual host explicitly.

#ServerName www.example.com

 

ServerAdmin webmaster@localhost

DocumentRoot /var/www/html

 

# Available loglevels: trace8, …, trace1, debug, info, notice, warn,

# error, crit, alert, emerg.

# It is also possible to configure the loglevel for particular

# modules, e.g.

#LogLevel info ssl:warn

 

ErrorLog ${APACHE_LOG_DIR}/error.log

CustomLog ${APACHE_LOG_DIR}/access.log combined

 

# For most configuration files from conf-available/, which are

# enabled or disabled at a global level, it is possible to

# include a line for only one particular virtual host. For example the

# following line enables the CGI configuration for this host only

# after it has been globally disabled with  a2disconf .

#Include conf-available/serve-cgi-bin.conf

</VirtualHost>

 

# vim: syntax=apache ts=4 sw=4 sts=4 sr noet

See Apache Name Based VirtualHost Example for more info on how to configure virtual hosting on Debian 9.

Step 3: Install MariaDB server

MariaDB is RDBMS and drop in replacement for original MySQL server. It is one of the most popular database servers in the world. It’s made by the original developers of MySQL and guaranteed to stay open source. To install MariaDB server, run:

$ sudo apt install default-mysql-server

 

OR

$ sudo apt install mariadb-server

 

Sample outputs:

Reading package lists… Done

Building dependency tree

Reading state information… Done

The following additional packages will be installed:

galera-3 gawk libaio1 libarchive13 libcgi-fast-perl libcgi-pm-perl libdbd-mysql-perl libdbi-perl libencode-locale-perl libfcgi-perl libhtml-parser-perl

libhtml-tagset-perl libhtml-template-perl libhttp-date-perl libhttp-message-perl libio-html-perl libjemalloc1 liblwp-mediatypes-perl liblzo2-2 libmariadbclient18

libmpfr4 libreadline5 libreadline7 libsigsegv2 libterm-readkey-perl libtimedate-perl liburi-perl mariadb-client-10.1 mariadb-client-core-10.1 mariadb-common

mariadb-server-10.1 mariadb-server-core-10.1 mysql-common psmisc readline-common socat

Suggested packages:

gawk-doc lrzip libclone-perl libmldbm-perl libnet-daemon-perl libsql-statement-perl libdata-dump-perl libipc-sharedcache-perl libwww-perl mailx mariadb-test

netcat-openbsd tinyca readline-doc

The following NEW packages will be installed:

default-mysql-server galera-3 gawk libaio1 libarchive13 libcgi-fast-perl libcgi-pm-perl libdbd-mysql-perl libdbi-perl libencode-locale-perl libfcgi-perl

libhtml-parser-perl libhtml-tagset-perl libhtml-template-perl libhttp-date-perl libhttp-message-perl libio-html-perl libjemalloc1 liblwp-mediatypes-perl liblzo2-2

libmariadbclient18 libmpfr4 libreadline5 libreadline7 libsigsegv2 libterm-readkey-perl libtimedate-perl liburi-perl mariadb-client-10.1 mariadb-client-core-10.1

mariadb-common mariadb-server-10.1 mariadb-server-core-10.1 mysql-common psmisc readline-common socat

0 upgraded, 37 newly installed, 0 to remove and 0 not upgraded.

Need to get 0 B/27.1 MB of archives.

After this operation, 195 MB of additional disk space will be used.

Do you want to continue? [Y/n] y

debconf: delaying package configuration, since apt-utils is not installed

Selecting previously unselected package libmpfr4:amd64.

(Reading database … 14762 files and directories currently installed.)

Preparing to unpack …/libmpfr4_3.1.5-1_amd64.deb …

….

..

Setting up libdbd-mysql-perl (4.041-2) …

Setting up mariadb-client-10.1 (10.1.23-9+deb9u1) …

Setting up mariadb-server-10.1 (10.1.23-9+deb9u1) …

Created symlink /etc/systemd/system/mysql.service ? /lib/systemd/system/mariadb.service.

Created symlink /etc/systemd/system/mysqld.service ? /lib/systemd/system/mariadb.service.

Created symlink /etc/systemd/system/multi-user.target.wants/mariadb.service ? /lib/systemd/system/mariadb.service.

Setting up default-mysql-server (1.0.2) …

Processing triggers for libc-bin (2.24-11) …

Processing triggers for systemd (232-25) …

How do I secure MariaDB mysql server?

Type the following command:

$ sudo mysql_secure_installation

 

Sample session:

Fig.03: Keeping your MariaDB database server safe

Please note that MariaDB/mysql root account and system root account are two different accounts. This is not the root account used for your server management. So make sure you set different passwords.

How do I test my MariaDB installation?

Type the following command:

$ mysql -u root -p

 

You will greeted with MariaDB mysql prompt. You can type sql commands to see databases, version and much more:

MariaDB [(none)]> show databases;

MariaDB [(none)]> exit

 

Sample outputs:

Fig.04: Testing MariaDB/MySQL server installation

 

See the following tutorials for additional tasks such as adding a new database, users and SSL config:

Mysql User Creation: Setting Up a New MySQL User Account

Create a MySQL Database, Tables and Insert Data

How to setup MariaDB SSL and secure connections from clients

Step 4: Install PHP version 7

PHP version 7 is at least 30-50% faster as compare to PHP 5.6. So let us install PHP version 7 along with php modules for on a Debian 9 server:

$ sudo apt install php7.0 libapache2-mod-php7.0 php7.0-mysql php7.0-gd php7.0-opcache

 

Sample outputs:

Reading package lists… Done

Building dependency tree

Reading state information… Done

The following additional packages will be installed:

fontconfig-config fonts-dejavu-core libfontconfig1 libfreetype6 libgd3 libjbig0 libjpeg62-turbo libpng16-16 libtiff5 libwebp6 libx11-6 libx11-data libxau6 libxcb1

libxdmcp6 libxpm4 php-common php7.0-cli php7.0-common php7.0-json php7.0-readline

Suggested packages:

php-pear libgd-tools

The following NEW packages will be installed:

fontconfig-config fonts-dejavu-core libapache2-mod-php7.0 libfontconfig1 libfreetype6 libgd3 libjbig0 libjpeg62-turbo libpng16-16 libtiff5 libwebp6 libx11-6 libx11-data

libxau6 libxcb1 libxdmcp6 libxpm4 php-common php7.0 php7.0-cli php7.0-common php7.0-gd php7.0-json php7.0-mysql php7.0-opcache php7.0-readline

0 upgraded, 26 newly installed, 0 to remove and 0 not upgraded.

Need to get 0 B/8,129 kB of archives.

After this operation, 25.9 MB of additional disk space will be used.

Do you want to continue? [Y/n] y

debconf: delaying package configuration, since apt-utils is not installed

Selecting previously unselected package libxau6:amd64.

(Reading database … 15880 files and directories currently installed.)

Preparing to unpack …/00-libxau6_1%3a1.0.8-1_amd64.deb …

….

..

..

Setting up libx11-6:amd64 (2:1.6.4-3) …

Setting up php7.0-cli (7.0.19-1) …

update-alternatives: using /usr/bin/php7.0 to provide /usr/bin/php (php) in auto mode

update-alternatives: using /usr/bin/phar7.0 to provide /usr/bin/phar (phar) in auto mode

update-alternatives: using /usr/bin/phar.phar7.0 to provide /usr/bin/phar.phar (phar.phar) in auto mode

 

Creating config file /etc/php/7.0/cli/php.ini with new version

Setting up libxpm4:amd64 (1:3.5.12-1) …

Setting up libapache2-mod-php7.0 (7.0.19-1) …

 

Creating config file /etc/php/7.0/apache2/php.ini with new version

Module mpm_event disabled.

Enabling module mpm_prefork.

apache2_switch_mpm Switch to prefork

apache2_invoke: Enable module php7.0

Setting up libgd3:amd64 (2.2.4-2) …

Setting up php7.0 (7.0.19-1) …

Setting up php7.0-gd (7.0.19-1) …

 

Creating config file /etc/php/7.0/mods-available/gd.ini with new version

Processing triggers for libc-bin (2.24-11) …

Processing triggers for libapache2-mod-php7.0 (7.0.19-1) …

This will install:

PHP version 7 for Apache 2

PHP 7 mysql connectivity module

PHP 7 OpCache module to speed up scripts

PHP 7 GD module for graphics

You can search and install additional PHP modules using the following syntax:

[search php7 modules] ##

$ apt-cache search php7 | grep module

$ apt search php7 | grep mysql

$ apt-cache search php7 | egrep  mysql|gd|zip

$ apt-cache search php7 | more

$ apt search php7 | more

[search php7 modules] ##

$ sudo apt install {module-name-here}

 

Finally, restart Apache 2 HTTP server, run:

$ sudo systemctl restart apache2

 

To test PHP installation, create a script called test.php in /var/www/html/ directory:

$ sudo vi /var/www/html/test.php

 

Append the following PHP code in it:

<?php phpinfo(); ?>

Fire a web-browser and type the following url:

http://10.114.13.8/test.php

 

Sample outputs:

Fig.05: Testing PHP 7 with Apache 2

 

PHP now installed and running on your server. It is time to secure PHP, see:

Linux: 25 PHP Security Best Practices For Sys Admins

At this stage you have a full fledged LAMP server running a Debian 9.

Step 5: Configure firewall to open port 80 and 443

Type the following command to install ufw firewall frontend:

$ sudo apt install ufw

 

Sample outputs:

Reading package lists… Done

Building dependency tree

Reading state information… Done

The following NEW packages will be installed:

ufw

0 upgraded, 1 newly installed, 0 to remove and 0 not upgraded.

Need to get 164 kB of archives.

After this operation, 848 kB of additional disk space will be used.

Get:1 http://mirrors.kernel.org/debian stretch/main amd64 ufw all 0.35-4 [164 kB]

Fetched 164 kB in 0s (180 kB/s)

Preconfiguring packages …

Selecting previously unselected package ufw.

(Reading database … 43888 files and directories currently installed.)

Preparing to unpack …/archives/ufw_0.35-4_all.deb …

Unpacking ufw (0.35-4) …

Setting up ufw (0.35-4) …

 

Creating config file /etc/ufw/before.rules with new version

 

Creating config file /etc/ufw/before6.rules with new version

 

Creating config file /etc/ufw/after.rules with new version

 

Creating config file /etc/ufw/after6.rules with new version

Created symlink /etc/systemd/system/multi-user.target.wants/ufw.service ? /lib/systemd/system/ufw.service.

Processing triggers for systemd (232-25) …

Processing triggers for man-db (2.7.6.1-2) …

Processing triggers for rsyslog (8.24.0-1) …

You must allow access to SSH port 22:

$ sudo ufw allow 22

Rules updated

Rules updated (v6)

 

Open port 80 and 443

$ sudo ufw allow 80

$ sudo ufw allow 443

 

Now you have default policy and ssh port including 80/443 allowed. It is safe to start enable the firewall, enter:

$ sudo ufw enable

 

Sample outputs:

Command may disrupt existing ssh connections. Proceed with operation (y|n)? y

Firewall is active and enabled on system startup

To see firewall rules, run:

$ sudo ufw status verbose

 

Sample outputs:

Status: active

Logging: on (low)

Default: deny (incoming), allow (outgoing), disabled (routed)

New profiles: skip

 

To                         Action      From

—                         ——      —-

22                         ALLOW IN    Anywhere

80                         ALLOW IN    Anywhere

443                        ALLOW IN    Anywhere

22 (v6)                    ALLOW IN    Anywhere (v6)

80 (v6)                    ALLOW IN    Anywhere (v6)

443 (v6)                   ALLOW IN    Anywhere (v6)

And there you have it, LAMP installed and running sucessfully on a Debian 9 system. Take a look at other tutorials for more info:

Securing Your Linux Server

Securing Your OpenSSH Server

 

 

Leave a Reply

Your email address will not be published. Required fields are marked *