Before today, if you’d asked me to throw down a LAMP server based on Ubuntu, I’d have been able to do it in my sleep. Ubuntu 18.04 LTS is different enough from 16.04 to make the job non-trivial. Getting a LAMP stack with phpMyAdmin and Snipe-It installed took some doing. After a few nights of tinkering, here’s what I came up with.
Requirements:
- Hardware. I’m running my server on ESXi 6.5 with 2 processors, 2 GB memory, and 16gb of disk. The process shouldn’t be all that different on a different hypervisor or with physical hardware.
- A freshly installed Ubuntu server. The Ubuntu Server 18.04 LTS iso, which can be found around here.
- PuTTY or a similar SSH client. Unless you prefer manually typing to copy-pasting.
- About 30 minutes, if you’re on a half decent internet connection.
DISCLAIMER
If you follow these instructions, you’ll end up with a working PHP, MySQL, and Apache server. I do not guarantee that these instructions follow all best practices. Actually, I guarantee that they do not. Ye be warned.
Add a static IP address
Before I get too much farther, I wanted to touch on something that gave me a lot of trouble. In 18.04, Ubuntu switched to Netplan. Instead of the old /etc/network/interfaces and /etc/resolv/resolv.conf edits that I was used to, you edit a YAML file and have netplan apply it. In theory, this is great, however, I had trouble with DNS resolution not working on records for my local domain. Public DNS records from local DNS server worked fine, but pinging “vm.local” would return “Temporary failure in name resolution”. Editing the static resolv.conf file wasn’t an option because it would be wiped on startup. Turns out, most of the documentation I found missed a crucial line that fixed everything for me. Helps to read the documentation sometimes. Here’s how I edited my Netplan config:
# This is a lazy way of doing this. It could bite you if
# you have more than one file there, but on a fresh Ubuntu
# Ubuntu system, there should only be one. Mine was named
# 50-cloud-init.yaml
sudo nano /etc/netplan/*.yaml
I edited my file to look like this:
network:
ethernets:
ens160:
addresses: [192.168.12.214/24]
gateway4: 192.168.12.1
nameservers:
# Split into two lines for readability
addresses: [192.168.12.249, 8.8.8.8]
addresses: [8.8.4.4, 4.2.2.2]
# THIS FIXED URRYTHING
search: [fancycomputer.local]
dhcp4: no
dhcp6: no
version: 2
The “search” line allowed me to specify local domains that I had in place on my local server. After running a sudo netplan apply and restarting my machine, the static IP still stuck and name resolution worked everywhere, every time. Adiamo.
Add repositories
Ubuntu 18.04 seems to be a little more security-minded than previous releases, and it seems like there are fewer pre-configured repositories installed than I was used to in previous releases. Many packages wouldn’t install with the default repositories (like libmcrypt-dev). Fixing that is easy. According to Ubuntu’s documentation, Universe repositories contain “community-maintained free and open-source software” aka practically everything that doesn’t come installed by default. Open your /etc/apt/sources.list in your favorite text editor (mine is Nano because I’m bad at this) and add “universe” to the end of each line so that you end up with this:
deb http://archive.ubuntu.com/ubuntu bionic main universe
deb http://archive.ubuntu.com/ubuntu bionic-security main universe
deb http://archive.ubuntu.com/ubuntu bionic-updates main universe
Once you’ve saved that, run updates and upgrade all the existing packages on your system:
sudo apt-get update && sudo apt-get upgrade -y
Install everything
Snipe-It’s general system requirements are listed here. At the time of this writing, it needed PHP>=5.6.4, MySQL or MariaDB, and a few PHP extensions. I used PHP7.2 and MySQL for my install. Most requirements can be installed via a big ol’ Apt install. A note: some of these are not strictly required to install Snipe-It specifically. Some of these may also be redundant.
# Install PHP, MySQL, and a bunch of common PHP modules.
sudo apt-get -y install php-pear libmcrypt-dev php7.2-dev apache2 php7.2 mysql-server mysql-client php7.2-mbstring php7.2-curl php7.2-ldap php7.2-bcmath php7.2-zip php-imagick libapache2-mod-php7.2 php7.2-mysql php7.2-gd php7.2-recode php7.2-tidy php7.2-xmlrpc unzip composer
# phpMyAdmin will ask you a bunch of questions.
# 1) Select apache2
# 2) Select "Yes" to configure dbconfig-common.
# 3) Pick a good password
sudo apt-get install -y phpmyadmin
# Install the mcrypt PHP extension.
sudo pecl install mcrypt-1.0.1
# Add mcrypt path to config files.
sudo bash -c "echo extension=/usr/lib/php/20170718/mcrypt.so > /etc/php/7.2/cli/conf.d/mcrypt.ini"
sudo bash -c "echo extension=/usr/lib/php/20170718/mcrypt.so > /etc/php/7.2/apache2/conf.d/mcrypt.ini"
# Finish MySQL install; answer "yes" to pretty much everything.
sudo mysql_secure_installation
If you stop here, you’ll have a hard time accessing MySQL via anything but the console. There are good instructions here for getting around this. I chose to create a new MySQL user and to leave root alone, and the commands I have below will differ from the ones in the link slightly.
# Get logged into MySQL with your system credentials
sudo mysql -u root
You should end up at a mysql> prompt. If so, enter these commands:
USE mysql;
CREATE USER 'myadmin'@'localhost' IDENTIFIED BY 'muhpassword';
GRANT ALL PRIVILEGES ON *.* TO 'myadmin'@'localhost';
FLUSH PRIVILEGES;
exit;
You should be back at a bash prompt now.
# Restart the MySQL service.
sudo service mysql restart
Change web root permissions
Having to sudo everything in /var/www is a pain. These commands will let you change things in that directory without horking up permissions too badly:
sudo addgroup webmasters
sudo adduser $USER webmasters
sudo adduser www-data webmasters
sudo chown -R www-data:webmasters /var/www
sudo find /var/www -type f -exec chmod 664 {} \;
sudo find /var/www -type d -exec chmod 775 {} \;
sudo find /var/www -type d -exec chmod g+s {} \;
Get Snipe-IT
The factory recommended method of getting Snipe-It is via git, which conveniently comes pre-installed on 18.04. For now, we’ll just drop the files in so that way Apache doesn’t gripe about missing directories later on.
git clone https://github.com/snipe/snipe-it /var/www/snipe-it
I’m going to sort of blow past setting up Apache virtual hosts. If you’re curious, there are some good documentation and examples to be found. Obviously, if you’re going to set up vhosts that have a ServerName set, you’ll need to update your DNS zone files accordingly. Open /etc/apache2/sites-enabled/000-default.conf and overwrite it with the following:
# Default vhost for visitors who type in anything but the
# host names specified in the vhosts below.
<VirtualHost _default_:80>
DocumentRoot /var/www/html
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>
<VirtualHost *:80>
<Directory /var/www/snipe-it/public>
Options Indexes FollowSymLinks MultiViews
AllowOverride All
Order allow,deny
allow from all
</Directory>
ServerName snipeit.fancycomputer.party
DocumentRoot /var/www/snipe-it/public
ErrorLog /var/www/snipe-it/error.log
CustomLog /var/www/snipe-it/access.log combined
</VirtualHost>
Just a few more commands:
# Running this turns on mod rewrite.
sudo a2enmod rewrite
# Restart apache and set it to run on startup.
sudo systemctl enable apache2.service
sudo service apache2 restart
Check in
Still here? Let’s recap what’s happened so far. We’ve got an Apache, PHP, MySQL server set up. We’ve got phpMyAdmin accessible at http://yourserversipaddress/phpmyadmin with the user you created. We’ve got everything we need to get starting configuring Snipe-It.
I’ll go over the steps to complete the install, but definitely give the docs a good read first.
Create your database user
While this could probably be done via phpMyAdmin, it’s faster to just hop into the MySQL console and paste in some commands.
# Get logged into MySQL with your system credentials again
sudo mysql -u root
As before you should end up at a mysql> prompt. If so, enter these commands:
create database snipeit;
create user 'snipe_user'@'localhost' identified by 'THIS_PASSWORD_THAT_YOU_NEED_TO_REMEMBER';
grant all on snipeit.* to 'snipe_user'@'localhost';
exit;
Edit that config
# Copy the example config.
cp /var/www/snipe-it/.env.example /var/www/snipe-it/.env
# Open'er up for editing
nano /var/www/snipe-it/.env
Only a few edits need to be made right now. Here’s the top of my .env file:
# --------------------------------------------
# REQUIRED: BASIC APP SETTINGS
# --------------------------------------------
APP_ENV=production
APP_DEBUG=false
APP_KEY=ChangeMe
APP_URL=http://snipeit.fancycomputer.party
APP_TIMEZONE='America/Chicago'
APP_LOCALE=en
# --------------------------------------------
# REQUIRED: DATABASE SETTINGS
# --------------------------------------------
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_DATABASE=snipeit
DB_USERNAME=snipe_user
DB_PASSWORD=THIS_PASSWORD_THAT_YOU_REMEMBERED
DB_PREFIX=null
DB_DUMP_PATH='/usr/bin'
DB_CHARSET=utf8mb4
DB_COLLATION=utf8mb4_unicode_ci
You’ll also need to configure your outgoing mail settings, but I won’t get into that here.
Install dependencies
Installing dependencies is easy enough. Remember when we performed a global install of composer? That means that a few commands should pull down everything that Snipe-It needs:
cd /var/www/snipe-it
composer install --no-dev --prefer-source
This is one of those go-make-a-pot-of-coffee situations. Composer will pull down packages and drop them into your Snipe-It install exactly where they belong, but it’ll take the better part of 5 minutes to finish. Also, you can ignore any warnings about the lock file being out sync with the composer.json file.
Now that your dependencies are installed, you can run the following command (From the very awesome Laravel framework) to generate an app key in your .env file. Neat.
php artisan key:generate
# You don't *have* to do this, but I prefer this to risking a
# timeout on the pre-flight page to do the same thing.
php artisan migrate
Now’s also a good time to set some directory permissions.
chmod -R 755 /var/www/snipe-it/storage
chmod -R 755 /var/www/snipe-it/public/uploads
chmod -R 755 /var/www/snipe-it/bootstrap/cache
Moment of truth
At this point, you should be able to browse to your Snipe-It install (http://snipeit.fancycomputer.party in my case) and see the Pre-Flight check. If not, you may want to change APP_DEBUG to true in your .env file and try again. This will spit out a more descriptive error message and make troubleshooting easier. Just remember to change it back when you’re up and running.
Whew
You did it! You now have a server that runs Snipe-It and (AND) can run any number of PHP applications at the same time. Are you patting yourself on the back yet?
I love love love Snipe-It and am often in disbelief that the software is free. Open-source software doesn’t run on wishes and dreams. If you like Snipe-It and have some $$$ to spare because you didn’t have to shell out for asset management software, send them a few bucks.