Image Overview: nginx
Minimal Wolfi-based nginx HTTP, reverse proxy, mail proxy, and a generic TCP/UDP proxy server
Download this Image
The image is available on cgr.dev
:
docker pull cgr.dev/chainguard/nginx:latest
Compatibility Notes
On May 3, 2023 the Chainguard nginx Image was rebuilt with several improvements, including breaking changes. You may need to take action to update your application.
Specifically, the config file was changed to bring the default configuration closer to that of the official nginx image. If you override the config with a custom configuration, you should not be affected.
The changes included:
- Moving the default port from
80
to8080
. This is required to run on Kubernetes as a non-privileged user. - Setting nginx to automatically determine the number of worker processes
- Moving the HTML directory to
/usr/share/nginx/html
If you are unable to update currently, you can use the last build of the previous image:
docker pull cgr.dev/chainguard/nginx@sha256:bcc6b0d052298112e4644b258de0fa4dc1509e3df8f7c0fba09e8c92987825e7
This digest corresponds to nginx version 1.24.0. This image is not updated and you should migrate to the new configuration as soon as possible.
Usage
To try out the image, run:
docker run -p 8080:8080 cgr.dev/chainguard/nginx
Following that, navigate to localhost:8080
in your web browser. There, you will find the default nginx welcome page.
You can also use the nginx Image to serve your own custom content. As an example, create a file named index.html
with the following command:
cat > index.html <<EOF
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Nginx</title>
</head>
<body>
<h2>Hello World from Nginx!</h2>
</body>
</html>
EOF
Then can instruct the the nginx Image to serve the index.html
file:
docker run -v $(pwd):/usr/share/nginx/html -p 8080:8080 cgr.dev/chainguard/nginx
If you navigate to localhost:8080
in your web browser, it will return Hello World from Nginx!
.
To use a custom nginx.conf
you can mount the file into the container, being sure to edit the -p 8080:8080
published port(s) to match your configuration’s listen
directive:
docker run -v $(pwd)/$CUSTOM_NGINX_CONF_DIRECTORY/nginx.conf:/etc/nginx/nginx.conf -p 8080:8080 cgr.dev/chainguard/nginx
Run in a read-only File System
If you want to run with read-only filesystem, you will need to mount the /var/run
and /var/lib/nginx/tmp
directories. The easiest way to do this is with --tmpfs
e.g:
docker run \
--read-only \
--tmpfs /var/lib/nginx/tmp/ --tmpfs /var/run/ \
--cap-drop=ALL \
-p 8080:8080
cgr.dev/chainguard/nginx
User Directive Warning
Starting the container gives the following warning:
nginx: [warn] the "user" directive makes sense only if the master process runs with super-user privileges, ignored in /etc/nginx/nginx.conf:2
The warning is telling us container is already running as the named user, so it doesn’t have anything to do. If the container is run as root, it would switch to the named user. We decided to leave this configuration in despite the warning for anyone that runs with --user
switch in Docker or an equivalent.
Differences from Official Docker Image
Wherever possible, the Chainguard nginx Image tries to follow the same configuration as the official Docker version. However, Chainguard designs Images with minimalism in mind; many Chainguard Images, by default, don’t include a shell or package manager. This means that it’s often impossible to achieve an identical configuration as the upstream version, as is the case between Chainguard’s nginx Image and the official image from Docker Hub. This section outlines the major differences between these images.
Users
The official Docker image starts as the root user and forks to a less privileged user. By contrast, the Chainguard nginx Image starts up as a less privileged user and no forking is required. For most users this shouldn’t make a difference, but note the “User Directive Warning” outlined previously.
Default port
To support the change to an unprivileged user, the default port was moved to 8080
, contrasting with port 80
used by the official image.
IPv6 Support
The official Docker image checks for the existence of /proc/net/if_inet6
and automatically listens on [::]:80
if it exists. For simplicity, we only listen on IPv4, but you can add IPv6 support by mounting a configuration file with a section like the following:
server {
listen 8080;
listen [::]:8080;
...
Note that the default configuration file in the Chainguard nginx Image has the relevant section at /etc/nginx/conf.d/default.conf
Environment Variable Substitution
The Docker official image has support for setting environment variables that get substituted into the config file. Currently we do not have support for this, but are looking into options.
Last updated: 2024-03-21 00:59