A Chef cookbook to set up an nginx webserver and install sites from a data bag.
This cookbook can be used for static sites, PHP scripts, and WordPress installations. nginx will always be installed, but all other packages (like php-fpm
for example) will only be installed if a node actually needs that part of the stack for the sites that it runs.
You can (and should!) also configure SSL certificates for your sites, although it is optional.
Assuming you want your site files to be installed by Chef (alternatively you could just drop the files in later), they should be on Github, with a tree something like
├── nginx
│ └── nginx.conf
├── ssl
│ ├── certs
│ └── keys
└── www
Your site['web_root']
should be a subdirectory (www
by default), because web projects generally have a few files (scripts, logs, configs, secrets, etc) that should be checked into the repo, but should not be served by nginx. I also recommend adding ssl/
to your .gitignore, since it will be populated with files by Chef.
If you provide Github OAuth token with the repo
scope, then a deploy key will be created for the site['owner']
and added to your site repo automatically for each node. If your site repo is private, then a deploy key is required or Chef cannot sync it.
If you like, you can also add extra nginx configuration files to your repo at nginx/*.conf
, and they will be loaded. This is not required.
Using Berkshelf, add the website
cookbook to your Berksfile.
cookbook 'website', github: 'logankoester/chef-website', branch: 'master'
Then run berks
to install it.
In the simplest case (no sites), including the default recipe in the run list will do nothing more than install, enable and start the nginx with any configuration at /etc/nginx/sites/*.conf
.
To start writing site definitions, create a data bag called sites
and refer to the examples below.
Next, set the attribute node['sites']
to an array of sites you want installed. Depending on your goals, you can have multiple sites on just node, one site running on several nodes, or any combination.
An item in the sites
data bag should look something like this.
"sites": {
"simple.example": {
"root": "/srv/http/simple.example"
}
}
In this barebones example, nginx
will serve traffic on port 80 for http://simple.example
from the /sites/simple.example
directory (which will be created if it does not exist).
If any sites have a truthy php
property, then php-fpm
will be installed and configured.
{
"php": true
}
If you want a reverse proxy, you can create a site with the proxy_pass
string set instead of a web root.
{
"proxy_pass": "http://localhost:8000"
}
If a site has the optional ssl
attribute, then an SSL certificate will be created and nginx
will be configured to listen on port 443 in addition to port 80.
{
"ssl": {
"common_name": "simple.example"
}
}
You can create a self-signed certificate (default), or read a custom one from attributes, data bags or chef-vaults.
See the ssl_certificate cookbook for details.
If the optional redirect_insecure
attribute is set to true
, then the site will redirect all http traffic to https.
{
"redirect_insecure": true
}
If you specify an owner
, that user will be created if missing and added to the http
group. If no owner is specified, a default http
user will be used. A home directory will be created at /home/#{owner}
.
If you prefer to skip the user
recipe altogether for a site, enable the { "skip_user": true }
option.
If you want Chef to deploy your site from a private repo, you must authorize it by setting the deploy_key
object.
To obtain a token, you will need to register an application at https://github.com/settings/applications
(or the equivilant page for your Github Organization), and then follow the OAuth Web Application Flow (easiest with an API testing tool like Postman).
"deploy_key": {
"credentials": {
"token": "AUTHORIZED_GITHUB_OAUTH_TOKEN"
},
"repo": "username/site-repo"
}
If a site has a valid deploy_key
object, a deploy key will be added to your site repo for each node that needs one, and the site['owner']
's home directory will be populated with these files:
.gitconfig
.ssh/config
.ssh/deploy_wrapper.sh
.ssh/deploy_key
If any of these files already exist, they will be left alone, so you can add sites to existing accounts if you want to - but you may need to tweak things if you want to deploy.
See the deploy_key cookbook for authorization details.
Note that if you want to use different deploy keys for different sites you must separate them by putting those sites under a different owner).
If you're using GitLab rather than Github, you can specify that like this:
"deploy_key": {
"credentials": {
"token": "GITLAB_TOKEN"
},
"repo": "project_id",
"provider": "gitlab",
"provider_host": "git.yoursite.example"
}
- New! See attributes.
This cookbook uses the Foodcritic linter, ChefSpec for unit testing, and ServerSpec for integration testing via Test Kitchen with the kitchen-docker driver.
It's not as complicated as it sounds, but you will need to have Docker installed.
git clone git@github.com:logankoester/chef-website.git
cd chef-website
bundle install
bundle exec rake
This will run all of the tests once. While developing, run bundle exec guard start
and the relevant tests will run automatically when you save a file.
Copyright (c) 2014-2019 Logan Koester. Released under the MIT license. See LICENSE
for details.