###Initial installation and configuration Install Git for Windows which includes Git Bash.
Install VirtualBox and Vagrant.
Note: These fixes were not originally done for VirtualBox 5.0 and Vagrant 1.7.4. They are for the previous versions instead: VirtualBox 4.3.30 and Vagrant 1.7.3. Some of these fixes may not be needed now. For example, I recently upgraded to VirtualBox 5.0 and Vagrant 1.7.4 and I did not have to alter the Vagrant ruby (.rb) files as shown in part of this Gist below. I'll soon try from a fresh install (not upgrade) and update this Gist accordingly.
In Git Bash (always run as administrator), type cd ~
to get to your "home" directory, ie.C:\Users\David
, and run these commands:
$ vagrant box add laravel/homestead
When prompted: choose option #1: virtualbox. Now clone (here I show clone command for php7 homestead box...although memcached isn't ready yet for php7):
$ git clone -b php-7 https://github.com/laravel/homestead.git Homestead
Now navigate to the Homestead directory and run the bash init.sh
command to create the Homestead.yaml
configuration file:
$ bash init.sh
Create your SSH keys using Git bash. I like to have the keys (.ssh
folder) in the "home" directory as well. ie. C:\Users\David\.ssh
:
$ ssh-keygen -t rsa -C "david@homestead"
(and then just press [enter] through each prompt)
Note: If you are using PhpStorm, you may already have an ssh key made. You could use that one if you wish. Just update the ssh section of your Homestead.yaml file to point to that key.
Now here is my C:\Users\David\.homestead\Homestead.yaml
file with some adjustments I made, and with things pointing to the ~
home directory:
(You may use the absolute Windows path instead of what I have done with ~/projects/sites
here, just make sure you capitalize the drive letter)
---
ip: "192.168.10.10"
memory: 3072
cpus: 1
provider: virtualbox
authorize: ~/.ssh/id_rsa.pub
keys:
- ~/.ssh/id_rsa
folders:
- map: ~/projects/sites
to: /home/vagrant/sites
sites:
- map: my-homestead-blog.loc
to: /home/vagrant/sites/blog/public
databases:
- homestead
variables:
- key: APP_ENV
value: local
This example will look for a folder at C:\Users\David\projects\sites
, so ensure you have created that folder there.
(Note: Be careful you don't add Tabs when editing Homestead.yaml)
###Shared mounted folder configuration and Laravel install
Run the guest box additions plugin and the winnfsd plugin (in Git bash):
$ vagrant plugin install vagrant-vbguest
$ vagrant plugin install vagrant-winnfsd
And add/update these parts of your C:\Users\David\Homestead\scripts\homestead.rb
file like this:
# Add this new section
# Reorder folders for winnfsd plugin compatilibty
# see https://github.com/GM-Alex/vagrant-winnfsd/issues/12#issuecomment-78195957
settings["folders"].sort! { |a,b| a["map"].length <=> b["map"].length }
# Configure A Few VirtualBox Settings
config.vm.provider "virtualbox" do |vb|
vb.name = 'homestead'
vb.customize ["modifyvm", :id, "--memory", settings["memory"] ||= "2048"]
vb.customize ["modifyvm", :id, "--cpus", settings["cpus"] ||= "1"]
vb.customize ["modifyvm", :id, "--natdnsproxy1", "on"]
vb.customize ["modifyvm", :id, "--natdnshostresolver1", "on"]
vb.customize ["modifyvm", :id, "--ostype", "Ubuntu_64"]
# add this to turn on symlink ability (so we can do 'npm installs')
vb.customize ["setextradata", :id, "VBoxInternal2/SharedFoldersEnableSymlinksCreate/v-root", "1"]
end
# Register All Of The Configured Shared Folders
if settings.include? 'folders'
settings["folders"].each do |folder|
mount_opts = []
if (folder["type"] == "nfs")
mount_opts = folder["mount_opts"] ? folder["mount_opts"] : ['actimeo=1']
end
# config.vm.synced_folder folder["map"], folder["to"], type: folder["type"] ||= nil, mount_options: mount_opts
# add this manual mount option line:
config.vm.synced_folder folder["map"], folder["to"], :nfs => { :mount_options => ["dmode=777","fmode=777"] }
end
end
To fix the issue with long path names in Windows:
- Update
C:\HashiCorp\Vagrant\embedded\gems\gems\vagrant-1.7.3\plugins\providers\virtualbox\driver\version_4_3.rb
near line 499 by replacing the hostpath declaration to look like this now (and notice the if condition below is now commented out):
def share_folders(folders)
folders.each do |folder|
hostpath = '\\\\?\\' + folder[:hostpath].gsub(/[\/\\]/,'\\')
#if Vagrant::Util::Platform.windows?
# hostpath = Vagrant::Util::Platform.windows_unc_path(hostpath)
#end
- Update
C:\HashiCorp\Vagrant\embedded\gems\gems\vagrant-1.7.3\lib\vagrant\util\platform.rb
and comment out a big part of this section starting near line 111, like this:
```
# This expands the path and ensures proper casing of each part
# of the path.
def fs_real_path(path, **opts)
#path = Pathname.new(File.expand_path(path))
#
# if path.exist? && !fs_case_sensitive?
# # Build up all the parts of the path
# original = []
# while !path.root?
# original.unshift(path.basename.to_s)
# path = path.parent
# end
#
# # Traverse each part and join it into the resulting path
# original.each do |single|
# Dir.entries(path).each do |entry|
# if entry.downcase == single.encode('filesystem').downcase
# path = path.join(entry)
# end
# end
# end
#end
#
# if windows?
# # Fix the drive letter to be uppercase.
# path = path.to_s
# if path[1] == ":"
# path[0] = path[0].upcase
# end
#
# path = Pathname.new(path)
#end
path
end
```
Now navigate to your ~/Homestead directory in Git bash and vagrant up
. (if you get a strange error, run vagrant up
once more and you should be good. I'll look into this strange behavior later.)
Note: you won't be able to manage the homestead box using the VirtualBox manager GUI since you'll need this 'vagrant up' configuration each time. Use vagrant halt
to power-down and vagrant up
to restart. If you need to destroy it and start all over, do vagrant destroy --force
followed by another vagrant up
.
Then vagrant ssh
and go into your sites folder and install Laravel or Lumen (I'm installing Lumen here):
$ composer global require "laravel/lumen-installer=~1.0"
$ lumen new blog
Now navigate to: http://localhost:8000. You should update your C:\Windows\System32\drivers\etc\hosts
file to use the site name like you specificed in your Homestead.yaml file:
192.168.10.10 my-homestead-blog.loc
192.168.10.10 my-second-blog.loc
192.168.10.10 my-third-blog.loc
Note: If you see "no input file specified", then nginx can't find any file for your site. Probably your Homestead.yaml sites "to" path is not matching were your actual public folder is for Laravel or Lumen.
###NPM Install problems
You will most surely have problems with sudo npm install
on the ubuntu guest machine, in the shared folder. You may get problems like:
- symlink input/output error
- Cannot find module 'laravel-elixir'
- and more
Here's what to do:
- Before you do these steps, you need to ensure you have opened Git Bash with 'run as administrator'.
- Now create a folder outside of the shared folder (just create some folder one level up from the shared folder), and manually create a
package.json
file there (just manually re-type the file, don't perform acp
command), and runsudo npm install
there. - If you mess up for some reason and need to remove the node_modules folder with a
sudo rm -rf node_modules
, it may fail on first try, but try running the command again. - Then change directories to your Laravel/Lumen project folder (that has the
composer.json
file in it) and now run the symlink command (you must be inside the shared folder for symlinking command to work):
sudo ln -s /home/vagrant/some-folder/node_modules node_modules
- Now you can run
gulp
(run it withoutsudo
):
gulp --production
You'll need to perform all npm installs in the folder you created above (ie. /home/vagrant/some-folder/). Here's some useful gulp plugins you might want to install:
sudo npm install gulp-less
sudo npm install gulp-minify-css
sudo npm install gulp-uglify
sudo npm install gulp-concat
sudo npm install gulp-add-src
sudo npm install gulp-sourcemaps
###How can I access my site from another PC/Device?
- Just go to your command prompt (cmd.exe) in Windows and do:
ipconfig
to get your host's IP (ie. 192.168.x.x). Then, from any other pc on the network, enter the host IP address followed by a:8000
to access the VM/site (ie. 192.168.x.x:8000/foo/bar). - If you want to access the site using the domain then you will need to edit the hosts files of the other computers as well. However those host files will point to the 192.168.x.x:8000 ip address. If you have multiple sites (my-homestead-blog.loc, my-second-blog.loc, etc.) then you will need to do this. If you are trying to access your site form a rooted mobile device that doesn't let you modify the hosts file, then set one of your sites as the nginx default_server in your sites-available and sites-enabled files. This will allow you to just use the ip and map whichever site you want to view at a time:
server {
listen 80 default_server;
listen 443 ssl;
server_name my.homestead-blog.loc;
root "/home/vagrant/sites/blog/public";
...
}
Then don't forget to sudo service nginx restart
.
###Caching issues
-
Update
/etc/nginx/nginx.conf
to havesendfile off;
-
Then find the location of opcache.so:
$ sudo find / -name 'opcache.so' /usr/lib/php5/20131226/opcache.so`
-
Add the following to opcache.ini:
$ sudo nano /etc/php5/mods-available/opcache.ini zend_extension=/usr/lib/php5/20131226/opcache.so opcache.memory_consumption=128 opcache.interned_strings_buffer=8 opcache.max_accelerated_files=4000 opcache.revalidate_freq=0 opcache.validate_timestamps=on opcache.fast_shutdown=1
-
Update the timezone:
sudo dpkg-reconfigure tzdata
-
Update the time so it's older than the host OS. You will have to do this each time you
vagrant up
your box if your box's time loses sync (I'm currently not experiencing this issue on Windows 8.1.). If your Host OS is at 11:01:00, then set your VM to:$ sudo date --set 11:00:50 $ sudo service nginx restart // You can set the full date with: // $ sudo date --set "Thu, 4 Jun 2015 11:00:50"
-
For local/developing environment, you can add/update your lumen
.env
file on your local machine to cache usingarray
like so:APP_ENV=local APP_DEBUG=true ... CACHE_DRIVER=array ...
-
In Laravel, you can run
php artisan clear-compiled
(the opposite of optimize) to clear vendor/compiled.php and other things. You can also runphp artisan cache:clear
in Lumen and Laravel. -
If you are using HHVM, I've not confirmed if HHVM caches anything that would be problematic for developer working local, but try without it (re-serve your site).
Note: For Lumen, in your bootstrap file, make sure you have Dotenv::load(__DIR__.'/../');
uncommented in the file so you can use your .env settings
###HHVM
####Changing a site to HHVM
$ cd /etc/nginx/sites-enabled
$ sudo rm my-homestead-blog.loc
$ cd /etc/nginx/sites-available
$ sudo rm my-homestead-blog.loc
$ sudo service nginx restart
$ cd /vagrant/scripts
$ sudo sh serve-hhvm.sh my-homestead-blog.loc /home/vagrant/sites/blog/public 80
$ sudo service nginx restart
You can confirm the site is using HHVM in php with:
die(defined('HHVM_VERSION'));
####Some errors not showing?
Make sure you have these settings in your php.ini:
/etc/hhvm/php.ini
hhvm.server.implicit_flush = true
hhvm.error_handling.call_user_handler_on_fatals = true
You can of course also tail errors at /var/log/hhvm/error.log
##PDO::FETCH_ASSOC
To change the 'fetch' => PDO::FETCH_CLASS,
setting in vendor/laravel/lumen-framework/config/databse.php just create a folder config just under your main project folder (ie. same level as your boostrap folder) and copy the file database.php file into it. Then change the line to: 'fetch' => PDO::FETCH_ASSOC,
and you'll get arrays returned from queries. Then do a php artisan cache:clear
.
##Bower
Create bower.json
in project folder (same folder where composer.json & package.json are):
{
"name": "laravel"
}
Create .bowerrc
in project folder:
{
"directory": "resources/assets/bower"
}
Install dependencies:
$ sudo bower install jquery --save --allow-root
$ sudo bower install bootstrap --save --allow-root
Update Less
Change:
@import "bootstrap/bootstrap";
to:
@import "../bower/bootstrap/less/bootstrap";
Update gulpfile.js
, update all references in the blade templates, remove old resources/assets/less/bootstrap
folder, and then run gulp
or gulp --production
(to minify).
(note: you may need to clear bower cache from time to time: bower cache clean some-package --force --allow-root
)
##Publishing Assets from Packages
You can use the artisan publish command to publish your assets from packages. For Lumen, you just need to add your own artisan command (look at Laravel's) or use the one found here: https://github.com/irazasyed/larasupport.
However, I prefer to avoid using artisan for this since I'm already maintaining a Less file and a Gulpfile. I simply update my gulpfile.js to have paths that pull directly from the vendor's package. See my gulpfile below.
Note: I don't use Laravel elixir.
In gulpfile.js
var gulp = require('gulp'),
less = require('gulp-less'),
minifyCSS = require('gulp-minify-css'),
uglify = require('gulp-uglify'),
concat = require('gulp-concat'),
addsrc = require('gulp-add-src'),
sourcemaps = require('gulp-sourcemaps');
var paths = {
'assets': 'resources/assets/',
'bower': 'resources/assets/bower/',
'vendor': 'vendor/',
'public': 'public/'
};
// CSS & Less
gulp.task('css', function(){
gulp.src(paths.assets + 'less/core.less')
.pipe(sourcemaps.init())
.pipe(less())
.pipe(minifyCSS())
.pipe(sourcemaps.write('source-maps'))
.pipe(gulp.dest('public/css'));
});
// Javascript
gulp.task('js', function() {
gulp.src(paths.bower + 'selectize-extended/dist/js/standalone/selectize.js')
.pipe(addsrc.append(paths.bower + 'smalot-bootstrap-datetimepicker/js/bootstrap-datetimepicker.js'))
.pipe(addsrc.append(paths.bower + 'bootstrap-table/dist/bootstrap-table.js'))
.pipe(addsrc.append(paths.bower + 'bootstrap-table/locale/bootstrap-table-en-US.min.js'))
.pipe(addsrc.append(paths.assets + 'js/core.js'))
.pipe(sourcemaps.init())
.pipe(concat('core.js'))
.pipe(uglify({mangle: false}))
.pipe(sourcemaps.write('source-maps'))
.pipe(gulp.dest('public/js'));
});
gulp.task('default',['css','js']);
You'll need to do a chmod -R 777 public
so Gulp can write files to your public directory.
@vincenttouzet
I still haven't got on Win10. But here's this:
winnfsd/vagrant-winnfsd#12
"I've just changed actimeo=1 to nolock,vers=3,udp and set compatibility to w8.
It works like a charm! I'm using Windows 10 64 bit."