This guide was written mainly for myself, as not to forget all the little things and not google all the answers again.
But of course anyone can use the guide to get a few pointers and ideas to improve their local developement stack. Note that most of the commands here have to be run with elevated permissions, so I omitted writing sudo
of #
in front of everything.
I am of course not responsible for breaking your system. Make sure you understand what you are doing, common sense etc.
When working on multiple projects at once, it is often practical to not have them all on the same domain. Entering localhost/foo
or localhost/bar
to switch can work, but sometimes integrations with frontend can lead to problems with relative paths. Sometimes you also need to parse domain names and/or paths and as most of your applications will run in the webroot I found it easier to just write foo.dev
or bar.dev
into the addressbar.
Browsers are also handle autocomplete on different domains better. I grow tired of having to enter credentials/fill forms when I am developing/fixing bugs.
Since google bought .dev
TLD (and is currently forcing https in chrome for these dmoains), you will have to use .test
instead. IMO using .test
and your own DNS server is more stylish but since I suck at networking I wasn't able to properly configure anything to work over both ipv4 and ipv6. But I found that the holy grail was in the system for the whole time.
The rest of this guide is written with .localhost
as your TLD and foo.localhost
as your domains.
Newer versions of systemd-resolve
automatically resolve domains .localhost
to localhost, so you can use whatever.localhost
easily.
Try ping whatever.localhost
and update systemd-resolve
if there is no answer
apt-get install dnsmasq
Append to /etc/dnsmasque.conf
echo "listen-address=127.0.0.1" >> /etc/dnsmasque.conf
Create zone file /etc/dnsmasq.d/test
echo "address=/test/127.0.0.1" > /etc/dnsmasq.d/test
Restart dnsmasque.
service dnsmasq restart
Add 127.0.0.1
to DHCP client as a DNS server
echo "prepend domain-name-servers=127.0.0.1" >> /etc/dhcp/dhcient.conf
Restart dhclient
service dhclient restart
Test ping foo.test
apt-get install apache2
Enable mod_rewrite
a2enmod rewrite
Enable vhost aliasing
a2enmod vhost_alias
Make wildcard vhosts file in /etc/apache2/sites-available/zzz-wildcard.conf
.
Edit the file zzz-wildcard.conf
in this gist to yor liking.
Setup a fallback error page when you inevitably enter a wrong domain name in the addressbar.
echo "<?php echo('Be original with your error message.');" > /var/www/notfound.php
Eanble ssl module in apache
a2enmod ssl
This guide aims to provide a simple method to get the green bar
in most browsers. Simply generating a random key might be sufficient in some cases, but for example chrome will not allow you to run service workers on 'unverified' domains.
As a certificate authority cannot sign certificates for TLDs (e.g. *.localhost
) but can sign wildcards for subdomins, our https server will be resolving the virtual hosts on https://*.https.localhost
. You could probably use mod_rewrite
magic to rewrite your URLs to exclude the https
part.
This is an abrigded version of this gist. If you wish to know what the hell you are doing, read it.
-
Configure openssl - you can copy
openssl-ca.conf
from this gist and edit it to suit your needs -
Make a Certificate Authority
openssl req -x509 -config openssl-ca.conf -newkey rsa:4096 -sha256 -nodes -out cacert.pem -outform PEM
-
Make a config for your server - you can copy
openssl-server.conf
from this gist and edit it to suit your needs
- Take note of the
alternate_names
section, as that is where your domains go
-
Generate a certificate request for your server
openssl req -config openssl-server.conf -newkey rsa:2048 -sha256 -nodes -out servercert.csr -outform PEM
-
Create a
index.txt
file for storing the database of certificatestouch index.txt
-
Create a serial file, so you can generate more certificates for your server(s)
echo '01' > serial.txt
-
Sign the certificate request with your certificate authority
openssl ca -config openssl-ca.conf -policy signing_policy -extensions signing_req -out servercert.pem -infiles servercert.csr
-
You will find
servercert.pem
andserverkey.key
in the directory. Copy these files into/etc/apache2/ssl
directory to keep them near the server configuration
mkdir /etc/apache2/ssl &&
cp servercert.pem /etc/apache2/ssl/zzz-wildcard.pem &&
cp serverkey.key /etc/apache2/ssl/zzz-wildcard.key
- Check
zzz-wildcard.conf
if your certificate path matches the certificates - Restart apache
service apache2 restart
As adding a CA into your browser/system is widely different for every piece of sotware, I will not describe every single option here. Just google how to import a certificate in firefox
and follow the tutorials. By default the authority you generate is named with ZZZ
in the beginning so it's always on the bottom of whatever list you put it in.
The certificate you want to import is the cacert.pem
file.
Now your connection to https://test.https.localhost
should be displayed as safe and trusted.
I found myself not needing a dedicated MySQL server that often. IMHO SQlite seems like a better fit for local development, as you can easily just delete the file if you want to start over or move/pass/share the whole databse without the need for dumps and renumbering of ids and whatnot.
Also keep in mind that transferring data between SQlite and MySQL can be... painful.
I would suggest using an ORM layer for database communication as most ORM implementations contain MySQL and SQlite connectors.
apt-get install mariadb-server
mysql_install_db
mysql_secure_installation
(Optional) Make MySQL root user can access with password, not only from user with elevated permissions
sudo mysql -u root
use mysql;
update user set plugin='' where User='root';
flush privileges;
exit;
If you want a different version, just add 7.0
, 7.1
or 7.2
after php
.
apt-get install php libapache2-mod-php php-mcrypt php-mysql php-cli php-curl php-sqlite3 php-intl php-mbstring php-xml php-opcache
+ whatever extensions needed
Enable apache2 mod
a2enmod php
Restart apache
service apache2 restart
ln -s /var/www ~/Sites/
usermod -a -G www-data $USER
mkdir /var/www/info && echo "<?php phpinfo();" > /var/www/info/index.php
You can make all files in /var/www/
accessible as the group www-data
. If you don't do this, there can be problems when you're creating the files by yourself. An example can be if you install a package using composer and that package needs an accessible folder for storing cached data. As apache runs as www-data
and you created the files as $USER
, the default umask
forbids the server to write in the directory.
This can be done by chmod
|chgrp
ing them every time your scripts fail, running apache as a different user or IMHO better using ACL.
Enable ACL for your filesystem in /etc/fstab
. ACL can be enabled on ext partitions only. Maybe on some others, I have no clue.
[/dev/sda1 | UUID=[whatever]] / ext4 errors=remount-ro,acl 0 1
Remount drive
mount -o remount,acl /
Set ACL for /var/www/
setfacl -d -m group:www-data:rwx /var/www
setfacl -m group:www-data:rwx /var/www
You can test this using the test-acl.php
script found in this gist. Download an copy to /var/www/test/
and set the owner and group of the directory to whoever
sudo chown root:root -R /var/www/test
Then test it by
curl -g http://test.localhost/test-acl.php