To get started, I've put together an example chef-repo (a.k.a 'kitchen') chef-server-with-vagrant, which was setup with knife-solo, Berkshelf, and Vagrant.
This kitchen was created by performing knife solo init . to turn the current directory into a new chef-repo. Here are the contents of this kitchen
.
├── Berksfile
├── Berksfile.lock
├── Gemfile
├── Gemfile.lock
├── MIT-LICENSE
├── README.md
├── Vagrantfile
├── chefserver
├── cookbooks
├── data_bags
├── environments
├── nodes
│  ├── chefserver.json
│  ├── vagrant.json
│  └── web.node.json
├── roles
│  ├── base.json
│  ├── chefserver.json
│  ├── node_base.json
│  └── vagrant_chefserver.json
└── site-cookbooks
├── apt
│  ├── CHANGELOG.md
│  ├── README.md
│  ├── attributes
│  │  └── default.rb
│  ├── files
│  │  └── default
│  │  └── apt-proxy-v2.conf
│  ├── libraries
│  │  ├── helpers.rb
│  │  └── network.rb
│  ├── metadata.json
│  ├── metadata.rb
│  ├── providers
│  │  ├── preference.rb
│  │  └── repository.rb
│  ├── recipes
│  │  ├── cacher-client.rb
│  │  ├── cacher-ng.rb
│  │  └── default.rb
│  ├── resources
│  │  ├── preference.rb
│  │  └── repository.rb
│  └── templates
│  ├── debian-6.0
│  │  └── acng.conf.erb
│  ├── default
│  │  ├── 01proxy.erb
│  │  └── acng.conf.erb
│  └── ubuntu-10.04
│  └── acng.conf.erb
├── build-essential
│  ├── CHANGELOG.md
│  ├── README.md
│  ├── attributes
│  │  └── default.rb
│  ├── metadata.json
│  ├── metadata.rb
│  └── recipes
│  ├── debian.rb
│  ├── default.rb
│  ├── fedora.rb
│  ├── mac_os_x.rb
│  ├── omnios.rb
│  ├── rhel.rb
│  ├── smartos.rb
│  ├── solaris2.rb
│  └── suse.rb
├── chef-client
│  ├── CHANGELOG.md
│  ├── README.md
│  ├── attributes
│  │  └── default.rb
│  ├── files
│  │  └── default
│  │  └── tests
│  │  └── minitest
│  │  ├── config_test.rb
│  │  ├── cron_test.rb
│  │  ├── delete_validation_test.rb
│  │  ├── service_test.rb
│  │  └── support
│  │  └── helpers.rb
│  ├── libraries
│  │  └── helpers.rb
│  ├── metadata.json
│  ├── metadata.rb
│  ├── recipes
│  │  ├── arch_service.rb
│  │  ├── bluepill_service.rb
│  │  ├── bsd_service.rb
│  │  ├── config.rb
│  │  ├── cron.rb
│  │  ├── daemontools_service.rb
│  │  ├── default.rb
│  │  ├── delete_validation.rb
│  │  ├── init_service.rb
│  │  ├── launchd_service.rb
│  │  ├── runit_service.rb
│  │  ├── service.rb
│  │  ├── smf_service.rb
│  │  ├── task.rb
│  │  ├── upstart_service.rb
│  │  ├── windows_service.rb
│  │  └── winsw_service.rb
│  └── templates
│  ├── arch
│  │  ├── conf.d
│  │  │  └── chef-client.conf.erb
│  │  └── rc.d
│  │  └── chef-client.erb
│  ├── default
│  │  ├── chef-client.pill.erb
│  │  ├── client.rb.erb
│  │  ├── com.opscode.chef-client.plist.erb
│  │  ├── debian
│  │  │  ├── default
│  │  │  │  └── chef-client.erb
│  │  │  ├── init
│  │  │  │  └── chef-client.conf.erb
│  │  │  └── init.d
│  │  │  └── chef-client.erb
│  │  ├── redhat
│  │  │  ├── init.d
│  │  │  │  └── chef-client.erb
│  │  │  └── sysconfig
│  │  │  └── chef-client.erb
│  │  ├── solaris
│  │  │  ├── chef-client.erb
│  │  │  └── manifest.xml.erb
│  │  ├── suse
│  │  │  ├── init.d
│  │  │  │  └── chef-client.erb
│  │  │  └── sysconfig
│  │  │  └── chef-client.erb
│  │  ├── sv-chef-client-log-run.erb
│  │  └── sv-chef-client-run.erb
│  └── windows
│  └── chef-client.xml.erb
├── chef-server
│  ├── Berksfile
│  ├── CHANGELOG.md
│  ├── CONTRIBUTING.md
│  ├── LICENSE
│  ├── README.md
│  ├── TESTING.md
│  ├── Thorfile
│  ├── Vagrantfile
│  ├── attributes
│  │  └── default.rb
│  ├── chefignore
│  ├── libraries
│  │  ├── dev_helper.rb
│  │  └── omnitruck_client.rb
│  ├── metadata.rb
│  ├── recipes
│  │  ├── default.rb
│  │  └── dev.rb
│  └── templates
│  └── default
│  └── chef-server.rb.erb
├── cron
│  ├── CHANGELOG.md
│  ├── README.md
│  ├── metadata.json
│  ├── metadata.rb
│  ├── providers
│  │  └── d.rb
│  ├── recipes
│  │  ├── default.rb
│  │  └── test.rb
│  ├── resources
│  │  └── d.rb
│  └── templates
│  └── default
│  └── cron.d.erb
├── logrotate
│  ├── CHANGELOG.md
│  ├── README.md
│  ├── attributes
│  │  └── default.rb
│  ├── definitions
│  │  └── logrotate_app.rb
│  ├── libraries
│  │  └── logrotate_config.rb
│  ├── metadata.json
│  ├── metadata.rb
│  ├── recipes
│  │  ├── default.rb
│  │  └── global.rb
│  └── templates
│  └── default
│  ├── logrotate-global.erb
│  └── logrotate.erb
├── omnibus_updater
│  ├── CHANGELOG.md
│  ├── Cheffile
│  ├── Cheffile.lock
│  ├── Gemfile
│  ├── Gemfile.lock
│  ├── README.md
│  ├── attributes
│  │  └── default.rb
│  ├── libraries
│  │  ├── omnibus_checker.rb
│  │  └── omnitrucker.rb
│  ├── metadata.json
│  ├── metadata.rb
│  └── recipes
│  ├── default.rb
│  ├── downloader.rb
│  ├── installer.rb
│  ├── old_package_cleaner.rb
│  └── remove_chef_system_gem.rb
└── vim
├── README.md
├── attributes
│  └── default.rb
├── metadata.json
├── metadata.rb
└── recipes
└── default.rb
73 directories, 150 files
Get started with the README.md and once you're all setup, start off with
vagrant up
This will spawn three virtual instances
* chef # Visit http://10.33.33.33, this is our test chef server
* chef_client # Bootstrap your first node @ 10.33.33.50
* chefserver # Use Knife-solo to bootstrap a chef server @ 10.33.33.40;
The focus of this example is to be able to play with an example Chef-server, and this will be made available at http://10.33.33.33. For the purposes of this demo, the chef-server is forced to operate over HTTP rather than HTTPS, which needs an SSL certificate.
Follow the README.md to upload the various roles to the chef server — for this example, we will only be dealing with roles. Typically, you will also upload cookbooks, nodes etc. to the chef server.
You can then proceed to bootstrap a new node using your knife
-> % knife bootstrap 10.33.33.50 -x vagrant -P vagrant --sudo --node-name web.node
Bootstrapping Chef on 10.33.33.50
10.33.33.50 --2013-11-11 13:19:33-- https://www.opscode.com/chef/install.sh
10.33.33.50 Resolving www.opscode.com (www.opscode.com)... 184.106.28.82
10.33.33.50 Connecting to www.opscode.com (www.opscode.com)|184.106.28.82|:443... connected.
10.33.33.50 HTTP request sent, awaiting response... 200 OK
10.33.33.50 Length: 6790 (6.6K) [application/x-sh]
10.33.33.50 Saving to: `STDOUT'
10.33.33.50
100%[======================================>] 6,790 --.-K/s in 0s
10.33.33.50
10.33.33.50 2013-11-11 13:19:35 (1.19 GB/s) - written to stdout [6790/6790]
10.33.33.50
10.33.33.50 Downloading Chef 11.8.0 for ubuntu...
10.33.33.50 Installing Chef 11.8.0
10.33.33.50 Selecting previously unselected package chef.
(Reading database ... 51095 files and directories currently installed.)
10.33.33.50 Unpacking chef (from .../chef_11.8.0_amd64.deb) ...
10.33.33.50 Setting up chef (11.8.0-1.ubuntu.12.04) ...
10.33.33.50 Thank you for installing Chef!
10.33.33.50 Starting Chef Client, version 11.8.0
10.33.33.50 Creating a new client identity for web.node using the validator key.
10.33.33.50 resolving cookbooks for run list: []
10.33.33.50 Synchronizing Cookbooks:
10.33.33.50 Compiling Cookbooks...
10.33.33.50 [2013-11-11T13:20:37+00:00] WARN: Node web.node has an empty run list.
10.33.33.50 Converging 0 resources
10.33.33.50 Chef Client finished, 0 resources updated
You will notice you didn't have to do anything to create the example chef server, so how does one setup a chef server on a VPS? Simple, use your knife to do that!
The third virtual environment chefserver is there for this purpose; it is a vanilla installation of Ubuntu Precise 64 (12.04 LTS). Once again, simply follow the README.md to bootstrap a working chef-server on the chefserver node using your knife. The Opscode Omnibus installer makes bootstrapping new nodes a breeze.
Troubleshooting Vagrant
Use vagrant long enough and you'll experience vagrant up hanging at "Waiting for VM to boot. This can take a few minutes"; thankfully the vagrant wiki has suggestions on tackling this.
Powering the VM down, booting with Virtualbox directly ensuring only the NAT interface is enabled — allowed me to login with u/p as vagrant/vagrant to run
$ sudo rm -Rf /var/lib/dhcp/*
$ sudo /etc/init.d/networking restart
This worked as vagrant up managed to bring the VM back online (as headless).