Skip to content

Commit d1e7885

Browse files
committed
feat: support filtering environment variables
1 parent f38ca09 commit d1e7885

File tree

3 files changed

+38
-12
lines changed

3 files changed

+38
-12
lines changed

README.md

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
# Docker static webserver
44

55
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.
6-
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.
6+
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.
77

88
## Getting Started
99

@@ -18,7 +18,7 @@ COPY ./your-static-content /var/www
1818
A more modern example where you build your frontend project and ship it:
1919

2020
```Dockerfile
21-
FROM node:18 as build
21+
FROM node:21 as build
2222
WORKDIR /opt/project
2323

2424
COPY package.json package-lock.json /opt/project/
@@ -62,8 +62,9 @@ You should use the latest available tag in [at in the registry](https://hub.dock
6262

6363
Due to the simple approach of finding & replacing the keywords there are some limitations:
6464
- Please make sure your environment keys do not contain special characters. Only `a-z`, `A-Z`, `0-9` and `_` are recommended.
65-
- By default, the script only changes files located in `/var/www`. You can change this by setting the `NGINX_ENVSUBST_WWW_DIR` environment variable.
66-
- The project is not meant as a development environment. Don´t mount your code in here as it will only change envioronment variables on the first starutp.
65+
- By default, the script only changes files located in `/var/www`. You can change this by setting the `NGINX_ENVSUBST_WWW_DIR` environment variable.
66+
- 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_`.
67+
- 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 startup.
6768

6869
## License
6970

files/docker-entrypoint.d/40-envsubst-on-www.sh

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,21 @@ set -e
66

77
ME=$(basename "$0")
88

9+
entrypoint_log() {
10+
if [ -z "${NGINX_ENTRYPOINT_QUIET_LOGS:-}" ]; then
11+
echo "$@"
12+
fi
13+
}
14+
915
www_envsubst() {
10-
local www_dir="${NGINX_ENVSUBST_WWW_DIR:-/var/www/}"
16+
local www_dir filter defined_envs
17+
www_dir="${NGINX_ENVSUBST_WWW_DIR:-/var/www/}"
18+
filter="${NGINX_ENVSUBST_FILTER:-}"
19+
defined_envs=$(printf '${%s} ' $(awk "END { for (name in ENVIRON) { print ( name ~ /${filter}/ ) ? name : \"\" } }" < /dev/null ))
20+
21+
if [ -n "$filter" ]; then
22+
entrypoint_log "$ME: envsubst filter is set to: $filter"
23+
fi
1124

1225
[ -d "$www_dir" ] || return 0
1326
if [ ! -w "$www_dir" ]; then
@@ -16,7 +29,13 @@ www_envsubst() {
1629
fi
1730

1831
grep --recursive --no-messages --files-with-matches "\${" "$www_dir" | while read -r file; do
19-
envsubst < "$file" > "$file.new" && cp --attributes-only --preserve "$file" "$file.new" && mv "$file.new" "$file"
32+
if [ -n "$filter" ]; then
33+
entrypoint_log "$ME: Running envsubst with filter on $file"
34+
else
35+
entrypoint_log "$ME: Running envsubst on $file"
36+
fi
37+
38+
envsubst "$defined_envs" < "$file" > "$file.new" && cp --attributes-only --preserve "$file" "$file.new" && mv "$file.new" "$file"
2039
done
2140
}
2241

files/var/www/index.html

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -38,14 +38,20 @@ <h2>Example Dockerfile</h2>
3838
<h2>Using environment variables</h2>
3939
<p>When this container bootstraps, a script will find and replace all occurrences of
4040
&dollar;&lcub;VARIABLE_NAME&rcub; and replace them for their matching values passed
41-
in the environment variables of your container. This is great when trying to
42-
ship a webpack compiled static page in a Docker image on multiple environments.
41+
in the environment variables of your container. This is great for shipping
42+
some bundled static code that only needs a small config change between environments.
4343
</p>
4444
</header>
45-
<p class="content">
46-
As an example: a container is almost certain to receive a hostname when running it. The hostname of
47-
this container is <code>${HOSTNAME}</code>. Try running another instance of this container and notice
48-
how the hostname changes.
45+
<p>
46+
As an example: a container recieves a hostname when it starts. The hostname of this container is
47+
<code>${HOSTNAME}</code> the nginx version is <code>${NGINX_VERSION}</code>.
48+
Try running another instance of this container and notice how the hostname changes.
49+
</p>
50+
<p>
51+
You can also filter the variables the startup script is replacing. This can prevent errors when your
52+
javascript contains es6 template literals. To prevent variables from being replaced you should
53+
set the `NGINX_ENVSUBST_FILTER` environment variable in your container. For example:
54+
`NGINX_ENVSUBST_FILTER=CONFIG_` only replaces variables that start with `CONFIG_`.
4955
</p>
5056
</section>
5157
<section id="cta" class="main special">

0 commit comments

Comments
 (0)