When I want to create a new application or a site, I need to edit nginx configuration: create a new site, add or remove security headers, proxify application, etc. But we make mistakes all the time. And there were a few cases when I wanted to rollback some changes, but I forgot what I'd changed. So, I decided to store these configuration files inside a git repository.
First thing I've attempted to do was to google some articles about best practices. All I found were these options:
- Place a repository anywhere in the system (usually, in a home directory)
and include that directory in
nginx.conf
. - Create a git repository inside nginx directory.
- Place a repository anywhere in the system and use a deploy script to copy files.
Placing a repository anywhere and using an include
First option doesn't seem to me like a good decision security-wise. I'm sure there is a reason for default files to be editable only by superuser.
Repository in /etc/nginx
I've decided to implement a second option. It's a simple and quick approach
where you only have to git init
inside /etc/nginx
and you are all set.
First disadvantage was that you either have to run git as a superuser to
make a commit or to change an owner of the .git
directory to yourself.
It was alright until I had to reconfigure the server from the ground up.
You can't clone a repository into a non-empty directory. I found a few
workarounds for that problem, but thought that I had to do some changes to that
workflow.
Placing a repository anywhere and using a deploy script
The next thing I've done was to move configuration repository out of /etc/nginx
to some other place. Then, I've created a script to deploy and apply my changes.
All it does is checks for superuser rights, rsync's files from the repository,
compiles my custom error pages (I hate default ones) and reloads nginx.
And to simplify adding or editing configuration files, I've created a node.js script that watches for changes executes the above-mentioned script on each change.
One note here is that you can't just use node.js method fs.watch
with
recursive option. I had to use node-watch
module from npm.
Closing words
Overall, now I'm using the third approach, placing a repository anywhere and utilizing a deploy script. This approach minimizes possible security issues and still allows to easily edit configuration while preserving history of edits.