Nginx that uses environment variables to build a configuration file using envsubst
. I was tired of copying
and pasting this image template everywhere.
In addition, I could not agree with solutions like:
- https://hub.docker.com/r/martin/nginx/
- https://github.com/shiphp/nginx-env
- https://thepracticalsysadmin.com/templated-nginx-configuration-with-bash-and-docker/
Then decided to use what is recommended at official nginx with some help from JavaCS3 on Github
The goal is to never have to create build an image for Nginx only for changing the configuration file. However, if you need to server static files you will have to deal with volumes, or you build your image to add files or add extra templates.
There's a lot to do, but I will start lean and iterate on a per request basis.
FROM nginx
To change the configuration we use Environment Variable
docker run --rm --name some-nginx -p 8080:80 -e NGINX_HOST=192.168.99.100.xip.io milhomem/nginx
Then you can hit http://192.168.99.100.xip.io:8080
in your browser.
Another example:
docker run --rm --name some-nginx -p 8080:80 -v /local/src:/var/www -e STATIC_FILES_ROOT=/var/www/public milhomem/nginx
And if you need to understand how the applied configuration looks like you can, in another console, run:
docker exec some-nginx cat /etc/nginx/conf.d/default.conf
Currently, these are the available variables, but they will depend on the tag you use:
- CLIENT_MAX_BODY_SIZE
- NGINX_PORT
- NGINX_HOST
- STATIC_FILES_ROOT
- FASTCGI_FILES_ROOT
- FASTCGI_HOST
- FASTCGI_PORT
- FASTCGI_CONNECT_TIMEOUT
- FASTCGI_SEND_TIMEOUT
- FASTCGI_READ_TIMEOUT
- PHP_VALUE
If you have extra needs you can either file an issue or see how to create a complex configuration below
Every template file in the config folder /etc/nginx/conf.d/*.template
will be generated replacing all environment
variables and included in the Nginx configuration.
You can then create a complex configuration:
.conf.template
will be added under thehttp
directive, allowing you to add multipleservers
if needed..rules.template
will be added under the mainserver
template..fastcgi_params.template
will be included together with thefastcgi
proxy configurations.
As an example, I can create my own Dockerfile to include extra rules and add my static files to be bundled together:
FROM milhomem/nginx
ADD config/templates/*.rules.template /etc/nginx/conf.d/
ADD src .
Note: Your templates can still use variables to be replaced by envvars, making your image as flexible as this one.
Out-of-the-box, Nginx doesn't support environment variables inside most configuration blocks,
but envsubst
may be used as a workaround if you need to generate your Nginx configuration dynamically
before Nginx starts.
Here is a few examples using docker-compose.yml:
version: '3'
services:
nginx:
image: milhomem/nginx:php
ports:
- "8080:80"
environment:
FASTCGI_HOST: "hello_world_app"
FASTCGI_FILES_ROOT: "/app"
hello_world_app:
image: php:7.3-fpm
command: |
sh -c "
mkdir /app;
echo '<?php phpinfo(); ?>' > /app/index.php;
php-fpm
"
version: '3'
services:
web:
image: milhomem/nginx:php
ports:
- "8080:8081"
environment:
NGINX_HOST: "localhost"
NGINX_PORT: "8081"
FASTCGI_FILES_ROOT: "/var/www"
FASTCGI_HOST: "fcgi"
PHP_VALUE: "date.timezone=GMT\nmax_execution_time=30"
CLIENT_MAX_BODY_SIZE: "10m"
FASTCGI_CONNECT_TIMEOUT: "5"
FASTCGI_SEND_TIMEOUT: "5"
FASTCGI_READ_TIMEOUT: "5"
fcgi:
image: php:7.3-fpm
volumes:
- "source_code:/var/www"
volumes:
source_code:
driver: local
The nginx
images come in many flavors, each designed for a specific use case.
This image is based on the popular Alpine Linux project,
available in the alpine
official image.
Alpine Linux is much smaller than most distribution base images (~5MB), and thus leads to much slimmer images
in general.
It is the first use case for this Nginx image with a PHP FastCGI backend. It will proxy the requests
to the backend that is linked via FASTCGI_HOST
This image is based on the popular Alpine Linux project.
This image is just a server for static content, for cases where you just want to host your assets files.
In this scenario you must copy files to the image (build your own) or mount a volume in the container.
If you need more flavors that you know are very common, please file a new issue or create an PR.
Get in touch @milmeninos if you want to be part of the project, if you have suggestions please file an issue or create an PR.
We need to be mindful that people run docker in to multiple platforms and we will support all that our base image supports.
To build the image run the following command:
docker buildx build \
--push \
--platform linux/amd64,linux/arm/v6,linux/arm/v7,linux/arm64/v8,linux/ppc64le,linux/s390x,linux/386 \
--tag milhomem/nginx:latest \
--tag milhomem/nginx:1.21-alpine \
alpine/base
docker buildx build \
--push \
--platform linux/amd64,linux/arm/v6,linux/arm/v7,linux/arm64/v8,linux/ppc64le,linux/s390x,linux/386 \
--tag milhomem/nginx:php \
--tag milhomem/nginx:1.21-alpine-php \
--tag milhomem/nginx:1.21-alpine-php-1.0 \
alpine/php