Skip to content

Learning C through nginx

This guide assumes that the reader knows the basics of C, is an intermediate programmer, looking for practical examples, and willing to figure out the theoretical parts themselves.

Learning C is hard, not because the language is complex or low-level, because I've used higher-level languages for so long that my ADHD-ridden brain cannot sit through a video course, or god-forbid, a PDF file.
So here's now I plan to learn C:

Find software that I've used before and that is written in C and figure out how it uses C to do whatever it does.

Which brings me to nginx and my first challenge.

Can we compile nginx locally?

This page mentions using configure but doesn't mention where to find it. This page mentions that build scripts are present in the auto folder. I'm using Ubuntu 24.10 with all the defaults.

bash
$ git clone git@github.com:nginx/nginx.git
$ cd nginx
$ auto/configure
$ make

Whew! This was much easier than most other C software I've compiled (a tiny sample size).

Can we run nginx compiled from source locally?

What did make do?

bash
$ git status
plain
On branch master
Your branch is up to date with 'origin/master'.

Untracked files:
  (use "git add <file>..." to include in what will be committed)
	Makefile
	objs/

nothing added to commit but untracked files present (use "git add" to track)

This tells me that the objs folder is new. It must contain the compiled binaries.

bash
$ cd objs
$ ./nginx
plain
nginx: [alert] could not open error log file: open() "/usr/local/nginx/logs/error.log" failed (2: No such file or directory)
2024/09/06 08:19:23 [emerg] 8576#0: open() "/usr/local/nginx/conf/nginx.conf" failed (2: No such file or directory)

nginx needs log and configuration files to run. There fastest way to get it started is to create the files that it needs and start nginx as root.

bash
/objs$ sudo mkdir -p /usr/local/nginx/logs
/objs$ sudo cp -r ../conf /usr/local/nginx
/objs$ sudo ./nginx

The command exits immediately starting the nginx processes in the background.

bash
$ ps aux | grep nginx
plain
root        9843  0.0  0.0   4688   948 ?        Ss   08:39   0:00 nginx: master process ./nginx
nobody      9844  0.0  0.0   6540  3380 ?        S    08:39   0:00 nginx: worker process
ramit-m+    9977  0.0  0.0   9144  2176 pts/1    S+   08:42   0:00 grep --color=auto nginx

I can see the default 404 page served by nginx on opening localhost:80 in a browser. What I also know from past experience is that I can check the access logs for the web server.

bash
$ tail /usr/local/nginx/logs/access.log
plain
127.0.0.1 - - [06/Sep/2024:08:44:23 +0530] "GET / HTTP/1.1" 404 153 "-" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:130.0) Gecko/20100101 Firefox/130.0"

That brings me to my next challenge: How does nginx write to files?