The following steps are required for a typical web developer stack for php and some front-end development. This is for a developer machine and not for a live environment!
The OS for this DevEnv will be Antergos, an arch based, rolling release Linux distro to keep all you packages always up-to-date. Download and install Antergos. In the installation wizard please enable the following features:
- Arch User Repository (AUR) Support
- Extra Truetype Fonts
- Printing Support
- Uncomplicated Firewall
- Windows sharing SMB
The rest of the installation is straightforward.
In the following stepts we will install the basic php and webserver components.
Let's start with php, because that's why you are here, right?
sudo pacman -S php php-fpm php-apcu php-gd php-imap php-intl php-mcrypt php-memcached php-pgsql php-sqlite php-cgi xdebug
Well, that was anticlimactic. We're already done with the php part.
Next we install nginx as our webserver.
sudo pacman -S nginx
...and mariadb for our database.
sudo pacman -S mariadb
sudo mysql_install_db --user=mysql --basedir=/usr --datadir=/var/lib/mysql
To simplify administration, we will install mysql-workbench and phpmyadmin as a front-end.
sudo pacman -S dbeaver
Now we install three more databases. You can't have enough databases!
sudo pacman -S redis postgresql sqlite
sudo -u postgres initdb --locale $LANG -E UTF8 -D '/var/lib/postgres/data'
As a fast, in-memory cache we use memcached. The php extension is already installed, now we install the server.
sudo pacman -S memcached
Sometimes you have tasks that can take a long while to process. Like sending emails, generating thumbnails or making external api requests. For those tasks you should use a queue, to push the process in the background and process it later when the user is not waiting. One of the tools we can use to make a queue is beanstalkd. You can also use Redis which is already installed.
yaourt -S beanstalkd
And last but not least, install this one. I will tell you what it does later.
sudo pacman -S dnsmasq
Now we can start to install a few general utilities to make our developer-life easier.
Starting off with git. Git is already installed in arch, but we can set a few Settings.
git config --global color.branch auto
git config --global color.diff auto
git config --global color.status auto
git config --global user.name "John Doe"
git config --global user.email johndoe@example.com
Unless your name is actually John Doe, you should probably replace that with your name.
Composer is.. well I should not have to explain what composer is. If you don't know it, you're doing php development the wrong way.
sudo pacman -S composer
And the same goes for npm and front-end development.
sudo pacman -S nodejs npm
sudo npm install -g webpack gulp
To ensure that our code is psr2 compliant we can use php-cs-fixer. It will go through all your files and check them against the psr2 standard and will fix all the styling mistakes you make.
sudo wget http://get.sensiolabs.org/php-cs-fixer.phar -O /usr/local/bin/php-cs-fixer
sudo chmod a+x /usr/local/bin/php-cs-fixer
By now we have installed everything we need. Let's start with the configuration. And like before we will start with:
sudo sed -i "s/error_reporting = .*/error_reporting = E_ALL/" /etc/php/php.ini
sudo sed -i "s/display_errors = .*/display_errors = On/" /etc/php/php.ini
sudo sed -i "s/;cgi.fix_pathinfo=1/cgi.fix_pathinfo=0/" /etc/php/php.ini
sudo sed -i "s/memory_limit = .*/memory_limit = 512M/" /etc/php/php.ini
sudo sed -i "s/upload_max_filesize = .*/upload_max_filesize = 100M/" /etc/php/php.ini
sudo sed -i "s/post_max_size = .*/post_max_size = 100M/" /etc/php/php.ini
sudo sed -i "s/;date.timezone.*/date.timezone = UTC/" /etc/php/php.ini
sudo sed -i "s/short_open_tag = .*/short_open_tag = On/" /etc/php/php.ini
and we need to enable a few php extensions:
sudo sed -i "s/;extension=memcached.so/extension=memcached.so/" /etc/php/conf.d/memcached.ini
sudo sed -i "s/;extension=bcmath.so/extension=bcmath.so/" /etc/php/php.ini
sudo sed -i "s/;extension=bz2.so/extension=bz2.so/" /etc/php/php.ini
sudo sed -i "s/;extension=curl.so/extension=curl.so/" /etc/php/php.ini
sudo sed -i "s/;extension=exif.so/extension=exif.so/" /etc/php/php.ini
sudo sed -i "s/;extension=ftp.so/extension=ftp.so/" /etc/php/php.ini
sudo sed -i "s/;extension=gd.so/extension=gd.so/" /etc/php/php.ini
sudo sed -i "s/;extension=iconv.so/extension=iconv.so/" /etc/php/php.ini
sudo sed -i "s/;extension=imap.so/extension=imap.so/" /etc/php/php.ini
sudo sed -i "s/;extension=intl.so/extension=intl.so/" /etc/php/php.ini
sudo sed -i "s/;extension=mcrypt.so/extension=mcrypt.so/" /etc/php/php.ini
sudo sed -i "s/;extension=mysqli.so/extension=mysqli.so/" /etc/php/php.ini
sudo sed -i "s/;zend_extension=opcache.so/zend_extension=opcache.so/" /etc/php/php.ini
sudo sed -i "s/;extension=sqlite3.so/extension=sqlite3.so/" /etc/php/php.ini
sudo sed -i "s/;extension=pdo_mysql.so/extension=pdo_mysql.so/" /etc/php/php.ini
sudo sed -i "s/;extension=pdo_pgsql.so/extension=pdo_pgsql.so/" /etc/php/php.ini
sudo sed -i "s/;extension=pdo_sqlite.so/extension=pdo_sqlite.so/" /etc/php/php.ini
sudo sed -i "s/;extension=soap.so/extension=soap.so/" /etc/php/php.ini
sudo sed -i "s/;extension=sockets.so/extension=sockets.so/" /etc/php/php.ini
sudo sed -i "s/;extension=zip.so/extension=zip.so/" /etc/php/php.ini
We will set php-fpm to run under our user, so that files written by php can always be read by you and the other way around. This is something you should never ever do in production!
sudo sed -i "s/user = .*/user = $USER/" /etc/php/php-fpm.d/www.conf
sudo sed -i "s/group = .*/group = users/" /etc/php/php-fpm.d/www.conf
sudo sed -i "s/listen.owner = .*/listen.owner = $USER/" /etc/php/php-fpm.d/www.conf
sudo sed -i "s/listen.group = .*/listen.group = users/" /etc/php/php-fpm.d/www.conf
We will generate a ssl certificate for our development-domain. It will be a self-signed certificate and because we are creating a wildcard certificate for a TLD (*.local), which is technically not allowed, browsers won't accept this certificate. So you will get a warning when you first visit the site. But it is always a good idea to match your dev-env as closely as you can get to your production environment. Because you're using SSL in production, right?
sudo mkdir -p /etc/ssl/webDev
sudo openssl req -nodes -newkey rsa:2048 -keyout /etc/ssl/webDev/webdev.local.key -out /etc/ssl/webDev/webdev.local.csr -subj "/CN=*.local, *.lh"
sudo openssl x509 -req -days 3650 \
-in /etc/ssl/webDev/webdev.local.csr \
-signkey /etc/ssl/webDev/webdev.local.key \
-out /etc/ssl/webDev/webdev.local.crt
Now we configure nginx. I will use the config file attached to this Gist. Review it before you download, never blindly trust some random guy on the internet!
sudo curl -L https://gist.github.com/rhwilr/ce7338a972ef0c5585ce0c01e54bb13b/raw/nginx.conf -o /etc/nginx/nginx.conf
sudo sed -i "s/user johndoe users;/user $USER users;/" /etc/nginx/nginx.conf
sudo sed -i "s/\/home\/johndoe/\/home\/$USER/" /etc/nginx/nginx.conf
As you can see, nginx will server your websites from a webDev
directory in your home. So lets create it
mkdir -p ~/webDev/log
Remember when i told you I will tell you what DNSMasq does. Now it's time:
So we have nginx which serves all websites ending with .local or .lh. It will grab the first part of the url and looks for a folder inside ~/webDev
with that name. So to be extra cool we can use DNSMasq as a local DNS server listening for any request for a .local domain and redirect you to localhost:80
. Nginx is listening on that port and will automatically serve you the correct website.
So let's set this up:
sudo sed -i "s/^#conf-dir=\/etc\/dnsmasq.d\/,\*\.conf/conf-dir=\/etc\/dnsmasq.d\/,\*\.conf/" /etc/dnsmasq.conf
sudo mkdir /etc/dnsmasq.d/
echo address=/.local/127.0.0.1 | sudo tee /etc/dnsmasq.d/webDev.conf
echo address=/.lh/127.0.0.1 | sudo tee -a /etc/dnsmasq.d/webDev.conf
echo nameserver 127.0.0.1 | sudo tee /etc/resolv.conf.head
To make all of the services we use to start up automatically, we have to enable them.
sudo resolvconf -u
sudo systemctl enable nginx.service php-fpm.service dnsmasq.service mysqld.service redis.service postgresql.service memcached.service beanstalkd
sudo systemctl start nginx.service php-fpm.service dnsmasq.service mysqld.service redis.service postgresql.service memcached.service beanstalkd
To test that everything is working me create a index.php
in ~/webDev/me/public/
mkdir -p ~/webDev/me/public
cat > ~/webDev/me/public/index.php << EOL
<?php
phpinfo();
EOL
Now open your browser end go to http://me.local/ and you should see the output of phpinfo
All that's left to do is to set up your IDE. I use PhpStorm but you can use what ever you want. You will most likely find everything in the AUR.
yaourt -S phpstorm
yaourt -S smartgit
To allow your IDE and Git-Clients to watch for file changes, we should increase the limit on how many watchers per user are allowed.
echo fs.inotify.max_user_watches = 524288 | sudo tee /etc/sysctl.d/99-sysctl.conf
#Xdebug To use Xdebug we first have to enable it.
sudo sed -i "s/;zend_extension=xdebug.so/zend_extension=xdebug.so/" /etc/php/conf.d/xdebug.ini
sudo sed -i "s/;xdebug.remote_enable=on/xdebug.remote_enable=on/" /etc/php/conf.d/xdebug.ini
sudo sed -i "s/;xdebug.remote_host=127.0.0.1/xdebug.remote_host=127.0.0.1/" /etc/php/conf.d/xdebug.ini
sudo sed -i "s/;xdebug.remote_port=9000/xdebug.remote_port=9000/" /etc/php/conf.d/xdebug.ini
sudo sed -i "s/;xdebug.remote_handler=dbgp/xdebug.remote_handler=dbgp/" /etc/php/conf.d/xdebug.ini
Enable Xdebug in your IDE. In PhpStorm you go to Run -> Edit Configurations... and add a new 'PHP Web Application' config.
Use the Xdebug helper Chrome-extension to use it from the Browser.
Thank you for your gist :)