How to make distinct versions (development and production) of JS code?
I develop small web application, distributed in Docker container, based on nginx image. It contains plain html and js code, without frameworks.
In JS code there is access to remote host via WebSockets. There is difference in environments: during testing on localhost, it works via http, on production server it uses https. So URL, which is passed to WebSocket, starts either with
What is reliable solution to maintain two versions of these URL in code, considering I want to keep single Docker image for both development and production, and just use different Docker Compose configuration scripts?
There is example of work with WebSockets:
// This is for testing in localhost environment var url = "ws://" + window.location.host + window.location.pathname + "bridge/"; // This is for working in production environment var url = "wss://" + window.location.host + window.location.pathname + "bridge/"; BRIDGE.socket = new WebSocket(url);
One Solution collect form web for “How to make distinct versions (development and production) of JS code?”
Here is a simpler “template substitution at runtime” idea that could work.
nginx image from Docker Hub actually has a utility from the
gettext package called
envsubst. It can substitute environment variables inside files. We can leverage this at runtime by making a quick shell script as an entrypoint to do the substitution for us.
First, let’s create the
#!/bin/sh if [ -n "$BASEURL" ]; then envsubst '$BASEURL' < /my.js.template > /my.js exec nginx -g "daemon off;" else echo "you must specify \$BASEURL as en environment variable" fi
This will look for a file at
/my.js.template. My example file looks like:
var url = "$BASEURL" + window.location.pathname + "bridge/";
We’ll need to wrap this up in a new Docker image based on the original
Dockerfile will look something like:
FROM nginx COPY entrypoint.sh /entrypoint.sh COPY my.js.template /my.js.template ENTRYPOINT ["/entrypoint.sh"]
Now, assuming that
/my.js was the file you wanted to replace the URL per environment, you can start this image like:
docker run -d -e BASEURL=wss://myhost mynewnginximage
It will replace the
$BASEURL int eh template and write it out to
/my.js and then execute
nginx as PID 1 just as the original base image does.
Of course, you’d have to adapt the shell script paths to your actual code. But in theory, you can now use the same image, and just change the
BASEURL environment variable per environment. In Docker Compose, you can specify a blank environment variable like:
This will instruct
docker-compose to use the
BASEURL that is set on your local shell and pass it through to the container. So, you wouldn do
docker-compose up like:
export BASEURL=ws://myhostfordev docker-compose up
Let me know if something doesn’t make sense and I can try to clarify. Alternatives to
envsubst for more templating could be something like https://github.com/kelseyhightower/confd instead which is a bit more powerful and can also take environment variables as input for templates.