skip to Main Content

I have file template which has various variables. I would like to constitute these variables with values before I copy this file to
running container. This what I do right now:

export $(grep -v '^#' /home/user/.env | xargs) && 
    envsubst < template.yaml > new_connection.yaml && 
    docker cp new_connection.yaml docker_container:/app && 
    rm new_connection.yaml

This is working, however I’m sure there is a way I can skip file creation/copy/remove steps and do just something like: echo SOME_TEXT > new_connection.yaml straight to the container. Could you help?

2

Answers


  1. This seems like a good application for an entrypoint wrapper script. If your image has both an ENTRYPOINT and a CMD, then Docker passes the CMD as additional arguments to the ENTRYPOINT. That makes it possible to write a simple script that rewrites the configuration file, then runs the CMD:

    #!/bin/sh
    envsubst < template.yaml > /app/new_connection.yaml
    exec "$@"
    

    In the Dockerfile, COPY the script in and make it the ENTRYPOINT. (If your host system doesn’t correctly preserve executable file permissions or Unix line endings you may need to do some additional fixups in the Dockerfile as well.)

    COPY entrypoint.sh ./
    ENTRYPOINT ["/app/entrypoint.sh"]  # must be JSON-array form
    CMD same command as the original image
    

    When you run the container, you need to pass in the environment file, but there’s a built-in option for this

    docker run --env-file /home/user/.env ... my-image
    

    If you want to see this working, any command you provide after the image name replaces the Dockerfile CMD, but it will still be passed to the ENTRYPOINT as arguments. So you can, for example, see the rewritten config file in a new temporary container:

    docker run --rm --env-file /home/user/.env my-image 
      cat /app/new_connection.yaml
    
    Login or Signup to reply.
  2. Generally, I agree with David Maze and the comment section. You should probably build your image in such a way that it picks up env vars on startup and uses them accordingly.


    However, to answer your question, you can pipe the output of envsubst to the running container.

    $ echo 'myVar: ${FOO}' > env.yaml
    $ FOO=bar envsubst < env.yaml | docker run -i busybox cat
    myVar: bar
    

    If you want to write that to a file, using redirection, you need to wrap it in a sh -c because otherwise the redirection is treated as redirect the container output to some path on the host.

    FOO=bar envsubst < env.yaml | docker run -i busybox sh -c 'cat > my-file.yaml'
    

    I did it here with docker run but you can do the same with exec.

    FOO=bar envsubst < env.yaml | docker exec -i <container> cat
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search