LAMP on Arch Linux

The Quantitative
10 min readNov 24, 2020
can you blame me for this one?

Let’s put it together, piece by piece, so we have a clear idea of what we’re running on our system and how to configure them.

If you want to install everything right now and configure later:
sudo pacman -S apache mariadb postgresql php php-apache php-pgsql
However, you might want to choose between MariaDB and PostgreSQL, unless you want to try both.

Apache

If you don’t have Apache / httpd installed, you’ll want that with something like:
sudo pacman -S apache
If you’re running soy-stemD.. I mean systemd, you can use these following commands to start/stop Apache, see if the Apache service is running, etc: systemctl status httpd.service
If you haven’t started it yet, you’ll see something like:
Active: inactive (dead)
Run something like: systemctl start httpd.service && systemctl status httpd.service
After this, you should see something like: Active: active (running) along with some other info about the service.
You can always run the status command to check on it at any point in the future as well.
Of course if you want Apache to start automatically when you start your computer, you can “enable” it with:
systemctl enable httpd.service
at which point you’ll see something like: Created symlink /etc/systemd/system/multi-user.target.wants/httpd.service -> /usr/lib/systemd/system/httpd.service.

We now must make one quick configuration check and change, if needed, to comment out the unique_id_module because, we’re focused on a local development setup, not serving traffic to customers here.
To do this, edit your httpd.conf file
sudo vim /etc/httpd/conf/httpd.conf
Make sure this line is commented:
#LoadModule unique_id_module modules/mod_unique_id.so
It was already commented on my Apache install, but it’s good to double check. If your version was already commented, you’re good to go. If you had to comment it out, restart Apache with: systemctl restart httpd.service

Now Apache is running. If you’re new to this, now you also know that “Apache” as known by Unix, is “httpd.”

LAMP or LAPP? …MySQL/MariaDB or PostgreSQL

Public Domain, https://commons.wikimedia.org/w/index.php?curid=77844026

So, now that you have the L and the A of the LAMP going, we’ll turn our attention to the database service. I’m a bit of a Postgresql fanatic, but choose as you like. At this point it’s either LAPP or LAMP. If you choose Postgresql, it’s double elephant mascots, so that’s great. I was going to say that the process to install either is well documented on the internet, but after a couple of searches, I take it back. I’ll outline the installation of both here, succinctly. If you view the MySQL Arch Wiki page, you’ll see that MySQL is developed by Oracle, and Arch favors the community-developed fork MariaDB. In fact, Arch dropped MySQL down from the core repo to the AUR.

MariaDB

Let’s install MariaDB instead of MySQL, since Arch favors it (since 2013), and it starts with an M so technically, the LAMP acronym will still apply.. haha.
Install it from the core repo with:
sudo pacman -S mariadb
At the time of writing, this command installs three packages: jemalloc-1:5.2.1–3 mariadb-clients-10.5.6–3 mariadb-10.5.6–3
Before starting the service, run:
sudo mariadb-install-db — user=mysql — basedir=/usr — datadir=/var/lib/mysql
This is a basic installation. You may choose to put your datadir in another spot, like an external hard drive or something like that.
At this point, there will be instructions in your terminal about how to start, auto-start, and test the service. For example:
cd /usr ; /usr/bin/mysqld_safe — datadir=/var/lib/mysql
which, after executing should return something like:
201023 14:54:42 mysqld_safe Logging to ‘/var/lib/mysql/p50.err’.
201023 14:54:42 mysqld_safe Starting mariadbd daemon with databases from /var/lib/mysql

At this point, you can start the service with soystemd like this:
sudo systemctl start mariadb.service && sudo systemctl status mariadb.service
At this point, you should see that it is active (running) and you may log into it with default / unhardened blank root password like this:
sudo mysql -u root -p
After hitting Enter to pass a blank password you should see something like this, indicating that the database service is up and running and you are logged into it:
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MariaDB connection id is 3
Server version: 10.5.6-MariaDB Arch Linux
Copyright © 2000, 2018, Oracle, MariaDB Corporation Ab and others.
Type ‘help;’ or ‘\h’ for help. Type ‘\c’ to clear the current input statement.
MariaDB [(none)]>

You can exit MariaDB for now by issuing the command: \q
Check the docs for further info about creating a user, granting it privileges, hardening initial security, further configuration, etc. We’ll discuss connecting to a test database in a bit.

Postgresql

If instead of, or in addition to, MariaDB, you’d like to have Postgresql installed, you can get a jump on this install and setup process by following along here. There are a few options I’ve played with over the last few months. If you want version 10, which I did initially because it was the engine version I was running in AWS RDS Postgresql, there is a nice option aur/postgresql-10-edb, courtesy of EDB, you can get from the AUR. At the time of writing, the regular pg-10 package aur/postgresql-10 10.13–1 has been recently orphaned. For now, I’ll walk you through install and setup of the latest, official version from the core repo. Install it with:
sudo pacman -S postgresql
At time of writing, the current version is postgresql-12.4–1
During installation, a user called postgres is created. You can check him like this:
cat /etc/passwd | grep postgres which will produce and output something like this: postgres:x:88:972:PostgreSQL user:/var/lib/postgres:/bin/bash
Next, we’ll need to initialize the db cluster. Before we do that, let’s switch to the postgres user. (Medium’s formatting is not allowing me to write “su <dash> postgres” without it looking like this “su — postgres”)

type this to become the postgres user

Now, that you are the postgres user, initialize the database cluster with:
initdb -D /var/lib/postgres/data
Just like MariaDB, you may put your data directory somewhere besides this location, but for right now, we’re sticking with basics.
After running the above command, you should see some output ending with:
Success. You can now start the database server using: pg_ctl -D /var/lib/postgres/data -l logfile start
It’s no surprise, you can also start and enable the service with our old friend soystemd. Just be sure to switch back to your regular user (by typing exit from your postgres session) before you do it like this:
systemctl start postgresql.service
If you want it to start automatically when you start your system, “enable” it with:
systemctl status postgresql.service
If you’d like to check it’s status, follow the same pattern:
systemctl status postgresql.service
Now that the cluster is initialized and the service is running, you can log into the PostgreSQL cluster using psql. You can either switch to the postgres user and simply run psql , or you can run: sudo -u postgres psql to do the same thing.
From here, continue to follow the docs to create users, databases, etc.
There is some assumption here, that you have some familiarity with MariaDB/MySQL or PostgreSQL if you are following along here.

PHP

Finally, the P in LAMP. If you’d like a specific version of PHP, there are various versions of php5 and php7 available if you search the AUR. If you want the official, latest version from the core repo, you can simply run:
sudo pacman -S php php-apache php-pgsql
At the time of writing, it is version php-7.4.11–1
Edit the PHP configuration by editing your php.ini file:
vim /etc/php/php.ini
Change display_errors = Off to display_errors = On and display_startup_errors = Off to display_startup_errors = On
You’ll also want to uncomment some of the extensions by removing the ; at the beginning of each line:
extension=pdo_mysql
extension=mysqli
extension=pdo_pgsql
extension=pgsql

After making these changes, you should restart Apache:
systemctl restart httpd.service && systemctl status httpd.service

LAMP

Now you have a LAMP (or a LAPP) stack.

By Vicki Nunn — Own work, Public Domain, https://commons.wikimedia.org/w/index.php?curid=12048968

We could end it here, assuming that readers will be able to connect the various pieces and have a good time, but we won’t. Some of the stories I write here get hundreds of thousands of eyeballs on them, so I have to assume there are some fresh faces that have made it this far and would appreciate something like a “Hello World” exercise to get all of this working and connected. It is for you that I continue :-)

Getting things connected and working

Sometimes life as a software engineer feels something like this image here. Actually, I’ve seen much worse IRL. At least in my world there are always problems to untangle. Engineering in general can be categorized as problem solving, even solving train-wreck-tier problems. This sort of thing is fun for folks like us, and if you’ve made it this far in this article, I imagine you, probably, like me, enjoying solving difficult problems. So, let’s continue.

Let’s test out Apache and make sure he is happy.

cd /srv/http
Now you’re in the directory that, by default, Apache is going to serve to your browser. Create a basic html file here. Something like:
sudo vim index.html
Then paste some html content like:

<html>
<title>Apache Testing</title>
<body>
<h2>Hey! Thanks, Tim B for helping me get Apache running on my local Arch Linux setup :-)</h2>
</body>
</html>

Then just type localhost into your browser and you should see something like this:

Let’s make sure Apache and PHP are playing well together

In order for Apache and PHP to become friends on your local setup, you must make a few more configuration changes to httpd.conf
vim /etc/httpd/conf/httpd.conf
Add this to the end of your httpd.conf:
# Tim B said to put this here
Include conf/extra/php7_module.conf
LoadModule php7_module modules/libphp7.so
AddHandler php7-script .php

This will work, but you might like to organize this a little differently by placing the Include at the end of the Include list section and the LoadModule andAddHandler in the LoadModule list if you want to be more a bit more tidy. Functionally, putting all three lines at the end accomplishes the same thing.
After these changes, restart Apache again:
systemctl restart httpd.service && systemctl status httpd.service
Now, you can test things out in the terminal and in the browser.
Create a file in /srv/http called info.php
sudo vim /srv/http/info.php
Populate it with this content:
<?php
phpinfo();
?>

Make it executable like this: sudo chmod +x /srv/http/info.php
Run it from the terminal with: php /srv/http/info.php
Then try it from the browser: http://localhost/info.php
Now, you should see something like this in your browser:

Now Apache and PHP are friends.

only showing public repos from github for obvious reasons

You can continue to work directly in /srv/http, but that’s probably not going to be a great experience. Rather, let’s create a symlink from here to the local copy of a Git repo you want to work in, or perhaps the local directory where you keep all of your Git repos, or something like that. In order to accomplish this, you need to have “FollowSymLinks” in your /etc/httpd/conf/httpd.conf file, but chances are, it’s already there by default, like this:
DocumentRoot “/srv/http”
<Directory “/srv/http”>
MultiViews
Options Indexes FollowSymLinks
AllowOverride None
Require all granted
</Directory>

I removed the comments for brevity, but here we can see that “Indexes” and “FollowSymLinks” options are enable by default.
The problem you’ll probably encounter has to do with permissions based on where to you want to symlink to. Let me give you a concrete example.
Instead of putting my code in /srv/http directly, I want to create a symlink from there to wherever my directory of Git repos lives. The catch is that there has to be executable permissions all the way to that directory down the entire file path. The solution is to put your “repos” directory here: “/repos”, or somewhere you don’t mind having executable permission from “/” to. Let me walk you through the steps I took:
1. Move my “repos” directory from /home/beach/repos to /repos
sudo mv /home/beach/repos /repos
2. Set appropriate permissions
sudo chmod 755 /repos
3. Create the symlink from /srv/http to /repos
ln -s /repos /srv/http/repos
Now, when we visit http://localhost/repos/ in the browser we can see everything in our /repos directory.
Our browser is following the symlink we put in /srv/http, and we can continue to work from a centralized “repos” directory.

To triple check, create a new directory in your repos directory and name it something like “aMediumTest.” In that directory name a new file “helloWorld.php” and populate it with the contents:
<?php
echo “Hello, World!”;

Then navigate to http://localhost/repos/aMediumTest/helloWorld.php and validate that you are seeing it show up in the browser.

We could walk through instantiating a database cluster, filling it with a test database, connecting to it and querying it through php, but this article is already getting a little too long, and if you’ve made it this far, I can probably assume you can get connected to a DB from here.
I will however include those steps in another article in the near future, at which point I will come back to this one and link to it from here. If you’re reading this and you don’t see the link, it means I haven’t gotten to writing that sister article yet.

Thanks for reading and I do hope someone found this helpful.
Best,
Tim Beach

--

--