FAMP Stack
A web server consisting of :
- FreeBSD or compatible operating system (TrueNAS in this case)
- Apache web server
- MySQL database server
- PHP scripting language interpreter
The FreeBSD Jail system is ideal for creating an encapsulated installation of a FAMP stack and other supporting software to host a single web site. The Jail can be treated as an independent entity running on the TrueNAS server. Each hosted web site will be placed in its own Jail to prevent unwanted interaction between them, whether caused by software problems or malicious activity.
Preparing the Jail
1. Log in to your TrueNAS server as root using SSH or the Shell option of the TrueNAS Web Portal.
2. Make some decisions and define some variables.
# Tailor each of these examples for your own situation
DOMAIN_NAME="wiki.example.com" # the fully qualified domain name of the web site you're going to set up
JAIL_NAME="${DOMAIN_NAME%%.*}" # name of the jail containing this instance of a FAMP stack ("wiki" in this example)
RELEASE_NAME="12.2-RELEASE" # which release this jail run (usually best to choose the latest available)
LAN_IP="192.168.7.35" # IP address within your normal LAN for this jail
GATEWAY_IP="192.168.7.1" # IP address of your gateway to the internet
DNS_IP="${GATEWAY_IP:?}" # IP address of your DNS server (usually the same as the internet gateway)
PHP_VER="74" # Which version of PHP you want to install (for PHP v7.4 specify "74")
3. Delete any old jail with the same name - e.g. if you're setting this same jail up again. Most people do not need to perform this step. Be careful you don't delete a jail that you still want to keep!
iocage destroy --force "${JAIL_NAME:?}"
4. Create the new jail.
iocage create \ --name "${JAIL_NAME:?}" \ --release "${RELEASE_NAME:?}" \ vnet=yes \ bpf=no \ allow_raw_sockets=1 \ boot=yes \ ip4_addr=${LAN_IP:?}/24 \ ip6_addr=none \ defaultrouter=${GATEWAY_IP:?} \ defaultrouter6=none \ resolver="nameserver ${DNS_IP:?}"
5. Define the domain name, so this jail knows who it is.
jexec "ioc-${JAIL_NAME:?}" /bin/sh -c \ "echo \"${LAN_IP:?} ${DOMAIN_NAME:?} ${DOMAIN_NAME%%.*}\" >> /etc/hosts"
6. Prepare the package manager.
jexec "ioc-${JAIL_NAME:?}" \ pkg update
Apache Web Server
1. Install the Apache web server.
pkg \ -j "ioc-${JAIL_NAME:?}" \ -install apache24
2. Tell the web server who it is.
jexec "ioc-${JAIL_NAME:?}" /bin/sh -c \ "echo \"ServerName ${DOMAIN_NAME:?}\" >> /usr/local/etc/apache24/httpd.conf"
3. Enable the web server so it starts when the jail boots up.
jexec "ioc-${JAIL_NAME:?}" \ sysrc apache24_enable=YES
4. Start the web server now.
jexec "ioc-${JAIL_NAME:?}" \ service apache24 start
MySQL Database Server
1. Install the MySQL software.
pkg \ -j "ioc-${JAIL_NAME:?}" \ install mysql80-client mysql80-server
2. Enable the database server so it starts when the jail boots up.
jexec "ioc-${JAIL_NAME:?}" \ sysrc mysql_enable=YES
3. Start the database server now.
jexec "ioc-${JAIL_NAME:?}" \ service mysql-server start
4. Generate a random root password for the database server.
echo "M${RANDOM}y${RANDOM}S${RANDOM}Q${RANDOM}L"
5. Secure and configure the database server.
jexec "ioc-${JAIL_NAME:?}" \ mysql_secure_installation
- Would you like to setup VALIDATE PASSWORD component? No (Assuming you are the only user, and you trust yourself)
- Please set the password for root here. (Use the random password generated at step 4).
- Remove anonymous users? Yes
- Disallow root login remotely? Yes
- Remove test database and access to it? Yes
- Reload privilege tables now? Yes
5. Remember the root password for the database.
jexec "ioc-${JAIL_NAME:?}" \ mysql_config_editor set --host=localhost --user=root --password
Use the random password generated at step 4.
PHP Software
1. Install the PHP software.
pkg \ -j "ioc-${JAIL_NAME:?}" \ install \ php${PHP_VER:?} \ php${PHP_VER:?}-bcmath \ php${PHP_VER:?}-bz2 \ php${PHP_VER:?}-ctype \ php${PHP_VER:?}-curl \ php${PHP_VER:?}-dom \ php${PHP_VER:?}-gd \ php${PHP_VER:?}-gmp \ php${PHP_VER:?}-iconv \ php${PHP_VER:?}-pecl-imagick \ php${PHP_VER:?}-imap \ php${PHP_VER:?}-intl \ php${PHP_VER:?}-json \ php${PHP_VER:?}-mbstring \ php${PHP_VER:?}-pdo_mysql \ php${PHP_VER:?}-opcache \ php${PHP_VER:?}-posix \ php${PHP_VER:?}-readline \ php${PHP_VER:?}-pecl-redis \ php${PHP_VER:?}-SimpleXML
2. Configure PHP
jexec "ioc-${JAIL_NAME:?}" \ cp /usr/local/etc/php.ini-production /usr/local/etc/php.ini
You may want to amend the configuration manually
jexec "ioc-${JAIL_NAME:?}" \ vi /usr/local/etc/php.ini
3.Configure Apache to use PHP
jexec "ioc-${JAIL_NAME:?}" /bin/sh -c \ "cat >| /usr/local/etc/apache24/modules.d/001_mod-php.conf" \ <<END <IfModule dir_module> DirectoryIndex index.php index.html <FilesMatch "\.php$"> SetHandler application/x-httpd-php </FilesMatch> <FilesMatch "\.phps$"> SetHandler application/x-httpd-php-source </FilesMatch> </IfModule> END
4. Ensure the Apache configuration is ok.
jexec "ioc-${JAIL_NAME:?}" \ apachectl configtest
5. Restart the Apache server with the new configuration.
jexec "ioc-${JAIL_NAME:?}" \ apachectl restart
Create a Database for your Web Site
1. Make some decisions and define some variables.
DB_NAME="${JAIL_NAME:?}" DB_USER="${DB_NAME:?}" DB_PASS="M${RANDOM}y${RANDOM}S${RANDOM}Q${RANDOM}L" set | grep "^DB_"
Make a note of this information. You'll need to configure your web site with the same details.
2. Create the user login.
echo "CREATE USER '${DB_USER:?}'@'localhost' IDENTIFIED BY '${DB_PASS:?}' ;" \ | jexec "ioc-${JAIL_NAME:?}" mysql
3. Create the database.
echo "CREATE DATABASE \`${DB_NAME:?}\` CHARACTER SET utf8 COLLATE utf8_unicode_ci ;" \ | jexec "ioc-${JAIL_NAME:?}" mysql
4. Allow full access to the database for the user.
echo "GRANT ALL ON ${DB_NAME:?}.* TO '${DB_USER:?}'@'localhost' ;" \ | jexec "ioc-${JAIL_NAME:?}" mysql
Install your Web Site files
Tip: To make it easier to find your Document Root folder in future, it's probably best to create a symbolic link.
jexec "ioc-${JAIL_NAME:?}" \ ln -s /usr/local/www/apache24/data /www
You can find your Document Root folder hereā¦
cd /mnt/*/iocage/jails/${JAIL_NAME:?}/root/www