This question already has answers here:
Bash brace expansion not working on Dockerfile RUN command
(2 answers)
Closed 3 months ago.
In my docker file I have this command to create directories :
RUN mkdir -p logs/{shell,security,errors}
However, it ends up creating these on my container :
{shell,security,errors}
How can I create directories without also including the curly braces?
You should try with shell for loop
RUN for i in shell security errors; do mkdir "/logs/$i"; done
This should work.
Related
On Windows
I successfully run Prometheus from a docker image like this.
docker run -p 9090:9090 \
-v D:/WORK/MyProject/grafana:/etc/prometheus \
prom/prometheus
The D:/WORK/MyProject/grafana contains prometheus.yml file with all configs I need.
Now I need to enable # operator usage so I added promql-at-modifier tried to run
docker run -p 9090:9090 \
-v D:/WORK/MyProject/grafana:/etc/prometheus \
prom/prometheus --enable-feature=promql-at-modifier
I got the following:
level=info ts=2021-07-30T14:56:29.139Z caller=main.go:143 msg="Experimental promql-at-modifier enabled"
level=error ts=2021-07-30T14:56:29.139Z caller=main.go:356 msg="Error loading config (--config.file=prometheus.yml)" err="open prometheus.yml: no such file or directory"
Tried to google. There are suggestions to mount file
docker run -p 9090:9090 \
-v /path/to/prometheus.yml:/etc/prometheus/prometheus.yml \
prom/prometheus
(from https://www.promlts.com/resources/wheres-my-prometheus-yml)
But no luck.
Tried to specify config file option but again no luck.
Could you help?
I am a fan of docker, but it does have a few points of friction, and you found one of them.
https://github.com/prometheus/prometheus/blob/main/Dockerfile#L25 is where the upstream prometheus defines ENTRYPOINT and CMD:
ENTRYPOINT [ "/bin/prometheus" ]
CMD [ "--config.file=/etc/prometheus/prometheus.yml", \
"--storage.tsdb.path=/prometheus", \
"--web.console.libraries=/usr/share/prometheus/console_libraries", \
"--web.console.templates=/usr/share/prometheus/consoles" ]
The problem is, any arguments provided to the docker run command will replace the default CMD. So in order to append arguments to the default CMD, you sadly need to copy the upstream CMD and then add your argument to the list.
Sadly, docker does not (currently!) support any way to "append" something to an upstream's CMD. How to append an argument to a container command? gives one idea for using an environment variable to do it.
In the general case where I want to provide default arguments and allow the invocation to provide additional arguments, I usually follow this pattern:
Make the entrypoint launch a shell script
exec the real entrypoint at the end of the shell script. exec replaces the shell with the real entrypoint, so that exec is important so signals are passed to the entrypoint and not the wrapper shell script.
At the end of the arguments to exec within the script, add "$#", which expands to the arguments of the shell script, quoted appropriately (yes, shell is quite esoteric! you'd think it would quote all the arguments together, but instead it quotes each of the arguments because that token is magical)
In this way, the "default" commands are within the shell script and thus don't need to be included with CMD. The downside to this method is that the shell script provided arguments are more difficult to remove if you wanted to.
Here's an example:
https://github.com/farrellit/stackoverflow/tree/main/68593213
The dockerfile includes a default CMD:
FROM alpine
COPY entrypoint.sh /entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"]
CMD ["7"]
the entrypoint.sh includes a set of "automatic" arguments to which is appended CMD, either default or overridden.
#!/bin/sh
exec echo 1 2 3 "$#"
The Makefile demonstrates to two invocations:
docker run --rm stackoverflow-68593213
docker run --rm stackoverflow-68593213 4 5 6
docker run --rm stackoverflow-68593213
1 2 3 7
docker run --rm stackoverflow-68593213 4 5 6
1 2 3 4 5 6
Here, 1 2 3 are the default "base" paramters I always want to pass to the ENTRYPOINT, 7 is the default "additional" parameters, and 4 5 6 provided to override the default parameters.
Can you try adding:
--config.file=/etc/prometheus/prometheus.yml
i.e.
docker run --publish=9090:9090 \
--volume=D:/WORK/MyProject/grafana:/etc/prometheus \
prom/prometheus \
--config.file=/etc/prometheus/prometheus.yml \
--enable-feature=promql-at-modifier
Explanation: Once you add flags (e.g. --enable-feature), other flags take default values. The default value for --config.file is prometheus.yml which is not what you want (you want /etc/prometheus/prometheus.yml) and so you must explicitly reference it.
Just a few brief details that lie behind DazWilkin's answer:
If you docker inspect the prom/prometheus image, you'll find the
following:
"Entrypoint": [
"/bin/prometheus"
],
"Cmd": [
"--config.file=/etc/prometheus/prometheus.yml",
"--storage.tsdb.path=/prometheus",
"--web.console.libraries=/usr/share/prometheus/console_libraries",
"--web.console.templates=/usr/share/prometheus/consoles"
],
When you run:
docker run ... prom/prometheus --enable-feature=promql-at-modifier
You are replacing the existing Cmd setting, so the command actually
executed is /bin/prometheus --enable-feature=promql-at-modifier. To
provide the same behavior as you get by default, you would actually
want to run:
docker run ... prom/prometheus \
--enable-feature=promql-at-modifier \
--config.file=/etc/prometheus/prometheus.yml \
--storage.tsdb.path=/prometheus \
--web.console.libraries=/usr/share/prometheus/console_libraries \
--web.console.templates=/usr/share/prometheus/consoles
0
I am trying to run this command and getting an error:
docker exec 19eca917c3e2 cat "Hi there" > /usr/share/ngnix/html/system.txt
/usr/share/ngnix/html/system.txt: No such file or directory
A very simple command to create a file and write in it, I tried echo and that one too didn't work.
The cat command only works on files, so cat "Hi there" is incorrect.
Try echo "Hi there" to output this to standard out.
You are then piping the output to /usr/share/ngnix/html/system.txt. Make sure the directory /usr/share/ngnix/html/ exists. If not create it using
mkdir -p /usr/share/ngnix/html
I presume you are trying to create the file in the container.
You have several problems going on, one of which #Yatharth Ranjan has addressed - you want echo not cat for that use.
The other is, your call is being parsed by the local shell, which is breaking it up into docker ... "hello world" and a > ... system.txt on your host system.
To get the pipe into file to be executed in the container, you need to explicity invoke bash in the container, and then pass it the command:
docker exec 12345 /bin/sh -c "echo \"hello world\" > /usr/somefile.txt"
So, here you would call /bin/sh in the container, pass it -c to tell it a shell command follows, and then the command to parse and execute is your echo "hello world" > the_file.txt.
Of course, a far easier way to copy files into a container is to have them on your host system and then copy them in using docker cp: (where 0123abc is your container name or id)
docker cp ./some-file.txt 01234abc:/path/to/file/in/container.txt
This question already has answers here:
Allowed characters in Linux environment variable names
(8 answers)
Closed 2 years ago.
Docker version: 20.10.2, build 2291f61
In a Dockerfile, is it possible to use an ENV directive for which the key contains embedded periods? For example:
ENV story.paragraph.port 2029
And if it is possible to declare ENV variables with keys that have periods, then is it later possible to reference them, using familiar shell-interpolation, in the same Dockerfile?
EXPOSE $story.paragraph.port
The latter EXPOSE directive breaks for me.
My use-case: I have a python script that loads its configuration from an INI file. Eg, I might have configuration properties like these:
story.paragraph.word=helloworld
story.paragraph.length=256
The python logic recognizes configuration settings both from the INI file (by default) or, alternatively, in overrides specified in the environment. The idea is that a container instance could specify its own environment variables for story.paragraph.word or story.paragraph.length, and that those values would override the default configuration.
Periods in env is not a valid identifier from unix prespective.
Setting env with periods inside a docker container is possible at runtime, but you can't directly access that env; you will need some workaround.
$ docker run --name test -itd -e story.paragraph.word=helloworld alpine sh
da4214ac2377cf1b3ce3af515f30e96dfadabf0140f541c06ee4a176a2bef746
$ docker exec -it test sh
/ # env | grep story
story.paragraph.word=helloworld <=== env is set
/ # echo $story.paragraph.word
.paragraph.word <=== can't access the env
/ # echo ${story.paragraph.word}
sh: syntax error: bad substitution
/ # env | grep 'story.paragraph.word' | cut -f 2 -d '=' <=== need such workaround
helloworld
/ # $
This question already has answers here:
docker: "build" requires 1 argument. See 'docker build --help'
(17 answers)
Closed 2 years ago.
The community reviewed whether to reopen this question last year and left it closed:
Original close reason(s) were not resolved
I just want to build a dockerfile from a different directory, I tried the following command
docker build -f C:/Users/XXXX/XXXX/XXXX/XXXX/XXXX/Dockerfile
and
docker build -f C://Users/XXXX/XXXX/XXXX/XXXX/XXXX/Dockerfile
Both of them yield the same error
"docker build" requires exactly 1 argument.
Am I missing something ?
You should provide the context, current directory for instance: ..
docker build -f C://Users/XXXX/XXXX/XXXX/XXXX/XXXX/Dockerfile -t something .
It is interpreting the C://Users/XXXX/XXXX/XXXX/XXXX/XXXX/Dockerfile in that line as the value for the -f switch (or option)
If you remove that -f it should rather interpret it as the path to the Dockerfile
when i type docker build at the terminal, i see
Usage: docker build [OPTIONS] PATH | URL | -
im not sure what the -f switch does, but when i build images, I am pretty sure I do this
docker image build -t tagname /path/to/Dockerfile
This question already has answers here:
Why would a correct shell script give a wrapped/truncated/corrupted error message? [duplicate]
(1 answer)
Syntax error : end of file unexpected (expecting "fi")
(4 answers)
Closed 2 years ago.
I am running the startup.sh script from Dockerfile and I get the error below when I run the docker container:
docker run -p 5308:5308 activity-logger
: not found line 2:
: not found line 5:
startup.sh: line 13: syntax error: unexpected end of file (expecting "then")
If I try to run sh startup.sh from my command line it seems to work well.
Any ideas?
startup.sh
#!/bin/sh
export env_file=`echo microservice-configuration/$LS_ENVIRONMENT.environment.properties`
export startup_command="npm run start:dist"
if [ -f $env_file ]; then
echo "Using environment specific configuration file $env_file"
env $(cat $env_file | xargs) $startup_command
else
echo "There is no environment specific configuration file $env_file"
$startup_command
fi
Dockerfile
FROM node:6.9.4-alpine
# Create app directory
RUN mkdir -p /opt/app
WORKDIR /opt/app
COPY . /opt/app
RUN npm install -g yarn
RUN yarn
RUN yarn build
# This is not working very well - the dependencies cannot be installed afterwards
# RUN yarn --production
ENV NODE_ENV production
EXPOSE 5308
CMD ["/bin/sh", "startup.sh"]
: not found line 2:
That's pointing to something screwy with the white space in this file. The most likely cause is editing the script on windows and getting the wrong line feeds. Stop using whatever editor you were using and fix the script with a better editor or a utility like dos2unix.