Introduction
About a month ago, Freek Van der Herten wrote some Laravel Homestead tips on his blog. The item that stood out for me was avoiding having to edit the hosts file. I won't go into much more detail here, but essentially this uses a utility called dnsmasq
to tell your computer to resolve configured domains locally.
Have a read over Freek's article and get dnsmasq
up and running and we'll continue.
Update May 6, 2016: I'd advise against the use of *.dev
due to Google's proposed usage and potential name collisions. Since writing this post, I've switched to *.test
; the remainder of the post remains unchanged.
Wildcard hosts
Now that you've setup dnsmasq
, you can resolve *.test
to your Homestead machine easily, but you still need that manual step of either configuring a new domain in your Homestead.yaml
file or using the serve
command within the virtual machine itself.
Whilst neither of these methods take a particularly long time to complete, it's still a few seconds of repetition that can be avoided with some tweaking of your default nginx configuration using wildcard hosts.
What we'll be doing, is telling nginx to listen for anything sent to it that isn't explicitly configured and look for the domain name in your (default) /home/vagrant/Code
directory.
Configuring nginx
Create a new file called /etc/nginx/sites-available/test_domains
and add the following:
1server { 2 listen 80 default_server; 3 # Only if you want SSL 4 # listen 443 ssl; 5 server_name _; 6 root /home/vagrant/Code/$host/public; 7 8 index index.html index.htm index.php; 9 10 charset utf-8;11 12 location / {13 try_files $uri $uri/ /index.php?$query_string;14 }15 16 location = /favicon.ico { access_log off; log_not_found off; }17 location = /robots.txt { access_log off; log_not_found off; }18 19 access_log off;20 error_log /var/log/nginx/test_domains-error.log error;21 22 sendfile off;23 24 client_max_body_size 100m;25 26 location ~ \.php$ {27 fastcgi_split_path_info ^(.+\.php)(/.+)$;28 fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;29 fastcgi_index index.php;30 include fastcgi_params;31 fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;32 fastcgi_intercept_errors off;33 fastcgi_buffer_size 16k;34 fastcgi_buffers 4 16k;35 fastcgi_connect_timeout 300;36 fastcgi_send_timeout 300;37 fastcgi_read_timeout 300;38 }39 40 location ~ /\.ht {41 deny all;42 }43 44 # Only if you want SSL45 # ssl_certificate /etc/nginx/ssl/test_domains.crt;46 # ssl_certificate_key /etc/nginx/ssl/test_domains.key;47 }
The bulk of this config is the default created by Homestead using the serve
or Homestead.yaml
provisioning methods, but take note of a couple of key changes:
1server { 2 listen 80 default_server; 3 listen 443 ssl; 4 server_name _; 5 root /home/vagrant/Code/$host/public; 6 7 # ... 8 9 error_log /var/log/nginx/test_domains-error.log error;10 11 # ...12 13 # Only if you want SSL14 # ssl_certificate /etc/nginx/ssl/test_domains.crt;15 # ssl_certificate_key /etc/nginx/ssl/test_domains.key;16 }
This tells nginx to listen on port 80 (HTTP) and 443 (HTTPS), setting 80 as the default_server
. We can then use the special variable for server_name _;
in order to catch domains names not explicitly configured.
Next, the root
variable is set to /home/vagrant/Code/$host/public
. nginx will convert $host
to the domain name that is being used for the request. For example, if you want to use sometestdomain.test
, you would configure a directory with the domain name in /home/vagrant/Code/sometestdomain.test
, which would contain a public
directory.
This means that providing you name your project directories <something>.test
and map their parent directory - default ~/Code
- directly to /home/vagrant/Code
, you won't have to configure a standard Laravel environment manually again.
Next, link the test_domains
configuration to nginx's sites-enabled
directory:
1$ cd /etc/nginx/sites-enabled2$ sudo ln -s /etc/nginx/sites-available/test_domains ./test_domains
Lastly, restart nginx - sudo service nginx restart
- and you will now be able to get to any *.test
domain at http://<something>.test
, as long as a directory exists in /home/vagrant/Code
named the same as your domain and contains a public
directory.
Configuring wildcard SSL
For those of who like to test with SSL, you can configure a wildcard SSL certificate as well.
From your Homestead environment:
1$ sudo openssl genrsa -out /etc/nginx/ssl/test_domains.key 2048 2$ sudo openssl req -new -key /etc/nginx/ssl/test_domains.key -out /etc/nginx/ssl/test_domains.csr 3Country Name (2 letter code) [AU]: 4State or Province Name (full name) [Some-State]:South Australia 5Locality Name (eg, city) []:Adelaide 6Organization Name (eg, company) [Internet Widgits Pty Ltd]: 7Organizational Unit Name (eg, section) []: 8Common Name (e.g. server FQDN or YOUR name) []:*.test 9Email Address []:10$ sudo openssl x509 -req -days 365 -in /etc/nginx/ssl/test_domains.csr -signkey /etc/nginx/ssl/test_domains.key -out /etc/nginx/ssl/test_domains.crt
You can now uncomment the two SSL configuration lines at the end of the /etc/nginx/sites-available/test_domains
file and restart nginx again.
Conclusion
Keep in mind that when using a self-signed certificate, your browser will likely complain about it initially, but you will be able to 'continue anyway' after the first visit.
The last thing to note, is that nginx doesn't support variables in the error_log
configuration option. This means that we can't easily separate each host's error messages into separate files, however, as you're working in a local environment, the chances of you working in multiple sites simultaneously means this shouldn't be too much of an issue.