https://github.com/nstapelbroek/docker-static-webserver
A static web server with find & replace support for environment variables
https://github.com/nstapelbroek/docker-static-webserver
alpine docker environment environment-variables find-and-replace nginx s6-overlay static-server webpack
Last synced: 25 days ago
JSON representation
A static web server with find & replace support for environment variables
- Host: GitHub
- URL: https://github.com/nstapelbroek/docker-static-webserver
- Owner: nstapelbroek
- License: mit
- Created: 2017-06-24T20:45:46.000Z (over 8 years ago)
- Default Branch: latest
- Last Pushed: 2024-06-07T08:05:15.000Z (over 1 year ago)
- Last Synced: 2026-01-17T11:25:15.631Z (26 days ago)
- Topics: alpine, docker, environment, environment-variables, find-and-replace, nginx, s6-overlay, static-server, webpack
- Language: HTML
- Homepage: https://hub.docker.com/r/nstapelbroek/static-webserver/
- Size: 102 KB
- Stars: 8
- Watchers: 1
- Forks: 0
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE
Awesome Lists containing this project
README
# Docker static webserver
[](https://hub.docker.com/r/nstapelbroek/static-webserver/tags/)
[](https://hub.docker.com/r/nstapelbroek/static-webserver/tags/)
[](https://hub.docker.com/r/nstapelbroek/static-webserver/tags/)
A simple nginx docker image that has the ability to insert environment variables. Created so I could re-use an image between prod and staging environments for my frontend builds.
It replaces environment variables on container startup, so you don´t have to rebuild your Docker image or use a server-side language to change some settings.
* [Usage](#usage)
* [Dockerfile example](#dockerfile-example)
* [Using environment variables](#using-environment-variables)
* [Envsubst filters](#envsubst-filters)
* [Mounting volumes](#mounting-volumes)
* [Versioning](#versioning)
* [License](#license)
* [Acknowledgments](#acknowledgments)
## Dockerfile example
This repository generates the images available on the [Docker hub](https://hub.docker.com/r/nstapelbroek/static-webserver/tags).
Using this image for your own project is as simple as creating a Dockerfile with the two lines below:
```Dockerfile
FROM nstapelbroek/static-webserver:5
COPY ./your-static-content /var/www
```
A more modern example where you build your frontend project and ship it:
```Dockerfile
FROM node:21 as build
WORKDIR /opt/project
COPY package.json package-lock.json /opt/project/
RUN npm ci
COPY . /opt/project
RUN npm run build
FROM nstapelbroek/static-webserver:5
COPY --from=build --chown=nginx:nginx /opt/project/dist /var/www
```
## Using environment variables
When this container starts, a script will replace all occurrences of ${VARIABLE_NAME} in `/var/www` with
their matching environment variable.
For example, given this HTML in a file located at `/var/www/index.html`
```HTML
My backend is located at ${BACKEND_URL}
```
And building & running this with an environment variable passed in docker run (`docker run -p 8080:80 -e BACKEND_URL=https://api.someproject.com myimage:latest`), you'll end up with:

Note: Please make sure your environment keys do not contain special characters. Only `a-z`, `A-Z`, `0-9` and `_` are recommended.
## Envsubst filters
By default, the script only changes files located in `/var/www`. You can change this by setting the `NGINX_ENVSUBST_WWW_DIR` environment variable.
Using es6 template literals can cause issues. You can fine-tune the replacement by configuring a filter with the `NGINX_ENVSUBST_FILTER` environment variable. This should allow you to set a prefix like `CONFIG_`.
Here's a table that should help you understand the behavior:
text value in file | passed environment variable | passed nginx filter | result | why
--- | --- | --- | --- | ---
`$MY_PROJECT_URL` | `MY_PROJECT_URL=123` | `PROJECT` | `123` | the passed filter matches we have an environment variable to replace
`${MY_PROJECT_URL}` | `MY_PROJECT_URL=123` | `PROJECT` | `123` | the passed filter matches and we have an environment variable to replace
\`${MY_PROJECT_URL}\` | `MY_PROJECT_URL=123` | `PROJECT` | \`123\` | the passed filter matches we have an environment variable to replace
`MY_PROJECT_URL` | `MY_PROJECT_URL=123` | `PROJECT` | `MY_PROJECT_URL` | this is not a valid form [for envsubst ](https://www.gnu.org/software/gettext/manual/html_node/envsubst-Invocation.html)
`$MY_PROJECT_URL` | `YOUR_PROJECT_URL=123` | `PROJECT` | `MY_PROJECT_URL` | the filter matches, but we have no environment variable to replace
`$MY_PROJECT_URL` | `MY_PROJECT_URL=123` | `PUBLIC_` | `MY_PROJECT_URL` | the variable does match the allowed filter
## Mounting volumes
The project is not meant as a development environment. Don´t mount your code in here as it will only change environment variables on the first container startup.
## Versioning
To prevent sudden BC-breaks you should avoid using the `latest` tag when building upon this image (or any image for that reason).
I'm using [Semver](https://semver.org/) as a base for versioning schematics. Due to the small functionality of this container I'm considering the following changes as "incompatible API changes":
- Altered behavior at clients, for example due to changes in cache-headers
- Altered behavior in the find & replace script
- Altered behavior in the file locations
You should use the latest available tag in [at in the registry](https://hub.docker.com/r/nstapelbroek/static-webserver/tags/).
## License
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details
## Acknowledgments
* [nginx dockerfiles](https://github.com/nginxinc/docker-nginx) for creating a stable base image
* [h5bp server configs](https://github.com/h5bp/server-configs-nginx) for providing the nginx config
* [html5up](html5up.net) for providing the template used in the placeholder page
* [envsubst](https://linux.die.net/man/1/envsubst) for doing the replacements