Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sending list of filenames in current directory as a single string to a Docker container's STDIN

I have a Docker container and need to pass a single string (an array of strings would work too, but as far as I know this is not possible) containing the names of the file present in the current directory.

My first strategy to get the filenames inside the container was running the command docker build -t doc-validate . && docker run doc-validate (printf "%s " $(ls -p | grep -v /)) , to send the output of (printf "%s " $(ls -p | grep -v /)) directly into the container's STDIN, however, I get zsh: bad pattern: (printf %s Dockerfile returned as an error; seems to me that the container or the shell is trying to get 'Dockerfile' executed somewhere and I don't know why this happens, as running this same printf command directly in the terminal works as expected (printing only file names in the current directory).

My second approach was trying to send these filenames as an environment variable to the container. Running PROJECT_FILES=(printf "%s " $(ls -p | grep -v /)) in the terminal works as expected, $PROJECT_FILES outputs these filenames. However, if I try to pass it directly into the container like this: docker build -t doc-validate . && docker run --env PROJECT_FILES=(printf "%s " $(ls -p | grep -v /)) doc-validate I get the same zsh: bad pattern: PROJECT_FILES=(printf %s Dockerfile as an error.

Seems to me that it the commands are failing before even entering the container due to 'zsh:' being in the error output, however, I don't see why running them standalone in the terminal works and why passing them as parameters to the container is being such a headache.

How can I get the output of running (printf "%s " $(ls -p | grep -v /)) in my local machine as a value accessible inside the container?

Dockerfile:

FROM node:16
WORKDIR /moduleRoot
COPY package.json /moduleRoot
RUN npm install
COPY . /moduleRoot/
# Authorize execution of entrypoint bash script
RUN chmod +x /moduleRoot/docker-container-entrypoint.sh
# these values below will be set later, just register them explicitly here
ENV PROJECT_FILES=""
CMD [ "/moduleRoot/docker-container-entrypoint.sh" ]

Bash entrypoint (docker-container-entrypoint.sh file in CMD):

#!/bin/bash
echo "Args are: $@"
echo "PROJECT_FILES=$PROJECT_FILES"
like image 984
Otávio Monteagudo Avatar asked Jun 18 '21 18:06

Otávio Monteagudo


People also ask

What is Workdir in docker image?

WORKDIR instruction is used to set the working directory for all the subsequent Dockerfile instructions. Some frequently used instructions in a Dockerfile are RUN, ADD, CMD, ENTRYPOINT, and COPY. If the WORKDIR is not manually created, it gets created automatically during the processing of the instructions.

How do you give a docker container a static name?

You can assign memorable names to your docker containers when you run them, using the --name flag as follows. The -d flag tells docker to run a container in detached mode, in the background and print the new container ID.


2 Answers

First thing is that you are using the node:16 and according to the entrypoint of the project it will call node to execute anything you pass as an argument.

On your Dockerfile you are calling a CMD and not changing the ENTRYPOINT, so when you execute the container it will try to execute the bash script using node and you must be getting an error like this:

/moduleRoot/docker-container-entrypoint.sh:2
echo "Args are: $@"
     ^^^^^^^^^^^^^^

SyntaxError: Unexpected string
    at Object.compileFunction (node:vm:353:18)
    at wrapSafe (node:internal/modules/cjs/loader:1039:15)
    at Module._compile (node:internal/modules/cjs/loader:1073:27)
    at Object.Module._extensions..js (node:internal/modules/cjs/loader:1138:10)
    at Module.load (node:internal/modules/cjs/loader:989:32)
    at Function.Module._load (node:internal/modules/cjs/loader:829:14)
    at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:76:12)
    at node:internal/main/run_main_module:17:47

If your bash script is there only to help you troubleshoot, then you can use the online heredoc to pass the arguments you need:

» docker run -t --rm doc-validate <<< echo $(ls -a1)

Args are: docker-container-entrypoint.sh Dockerfile package.json
PROJECT_FILES=

On the other hand, if you need the bash script then you'll have to change the CMD with ENTRYPOINT. Another thing worth noting is that Linux's ls doesn't have the -p flag.

like image 165
fboaventura Avatar answered Oct 19 '22 08:10

fboaventura


Maybe this question/answers should work for you if you are using a CI pipeline with Jenkins: How to mount docker volume with jenkins docker container?

like image 29
mmarquezvacas Avatar answered Oct 19 '22 07:10

mmarquezvacas