Organising a Web Server
Note: This is a historical post. I don't recommend moving Nginx's default directories.
I've been using a RamNode VPS for over 3 years now. It's extremely low-end, having only 128MB of RAM, so something as lightweight and fast as Nginx was perfect to host my static website.
At the time I was new to provisioning a web server from scratch and ended up doing a lot of things just to get to a working state. Over time it's evolved as I learnt new tricks, leaving a mess in the process.
This seems to be a problem with any project in both the cyber and physical world. As you create more of something, you need to decide where to put them and reorganise everything else. Making it refactoring essentially.
Anyway, for this article I'm strictly talking about directory structures and where to put files used by a web server. No matter which web server you're using, the solution probably applies equally.
Setup
Nginx, as I'm using it requires these types of files:
- Configuration - e.g.
nginx.conf
- Logs - e.g.
access.log
,error.log
- Assets - e.g. HTML, CSS, JavaScript files
- Proxy Cache - If you want to proxy a request but don't want to hit the origin with every request.
Before my changes, this is the mess it was in:
/etc/nginx/
- Configuration. Default location when installing Nginx via YUM./etc/nginx/nginx.conf
/etc/nginx/conf.d/{server}.conf
- Server-specific configuration.server
being the subdomain ofjahed.dev
/etc/nginx/includes/{name}.include.conf
- Common partial configurations such as adding CORS headers.
/var/log/nginx
- Logs/srv/www/{folder}
- Assets.folder
being arbitrary so I could serve different files for different Nginxservers
/srv/cache/{zone_name}
- Proxy Cache
A lot of these are default locations and I was essentially overriding defaults with my own configuration. So when Nginx updates, it'll dump new files in the default directories which may cause issues.
There's also a lack of conventions.:
/srv
shouldn't contain cache data as they're temporary.includes
can mean anything.- Assets being place in
folder
makes it hard to know what's using it. server
doesn't map directly to an Nginxserver_name
so if I have 2 servers,abc.jahed.dev
andabc.something.com
, they'll conflict.
Solution
The nginx
command doesn't have to be run using the defaults. Using the -p
and -c
flags we can launch a server with any given "prefix" and "configuration" respectively. The defaults being /etc/nginx
and nginx.conf
.
Here's the new structure I came up with:
/etc/www/nginx
- Configuration/etc/www/nginx/servers/{server_name}
- Server-specific configuration. Whereserver_name
corresponds to the Nginxserver_name
/etc/www/nginx/partials/_{name}.conf
- Common partial configurations. Such as adding CORS headers.
/var/log/www/nginx
- Logs/srv/www/{server_name}
- Server-specific assets./var/tmp/www/{zone_name}
- Proxy Cache
All web-related files are now prefixed with www
no matter where they are in the hierarchy. This makes it obvious what they're used for. So if I introduce another web-related service that isn't using Nginx, it'll still fall under the www
prefix. It also means the files are bound to the service they provide as well as the applications they're used in, rather than just the latter.
To cover my previous list of problems:
- Cached data now goes in
/var/tmp
as they're temporary; being constantly updated as caches are renewed and expired./var/tmp
files, unlike/tmp
aren't cleared on system reboots. - Following conventions from static site generators and other tools, partials are now indicated using an underscore prefix (
_
). - Assets are now in directories named after the Nginx
server_name
they're being used by. - Server-specific configuration is now named by
server_name
That's essentially all there is to it. I'm pretty happy with this approach. Of course, I'm bound to change some things as time goes on but the foundations seem solid.