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 ws:// or wss://

  • How do I start cron on docker ubuntu base?
  • Django & WordPress - wp-admin redirect issue
  • Unable to use -lt when running Nginx Docker or cat logs
  • Jenkins Docker Container can't access docker.sock
  • Unable to preserve setup.py install state in docker container
  • What's the purpose of reexec.Init() in docker?
  • 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);
    

  • Avoid hard coding the mysql container ip in my apache container script
  • Php application started working slowly with docker
  • How to get Libsodium running on Alpine Java
  • Docker windows loading kernel modules
  • Communication between spring boot dockerized apps
  • Empty project with docker supper in Visual Studio
  • 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.

    The base 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 entrypoint.sh script:

    #!/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 nginx. The 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:

    environment:
      BASEURL:
    

    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.

    Docker will be the best open platform for developers and sysadmins to build, ship, and run distributed applications.