If I have a few RUN commands in my Dockerfile, how can I have it not print any output from a specific command, such as ignoring the printed statements from an apt-get update?
This works for me
FROM ubuntu:16.04
RUN which nano || echo no nano
RUN bash -c "apt-get update &> /dev/null"
RUN bash -c "apt-get install nano &> /dev/null"
RUN which nano
(really got the solution from Redirecting command output in docker)
Related
I need to execute crontab inside docker container, so I created the following dockerfile:
FROM openjdk:11-oraclelinux8
RUN mkdir -p /opt/my-user/
RUN mkdir -p /opt/my-user/joblogs
RUN groupadd my-user && adduser my-user -g my-user
RUN chown -R my-user:my-user /opt/my-user/
RUN microdnf install yum
RUN yum -y update
RUN yum -y install cronie
RUN yum -y install vi
RUN yum -y install telnet
COPY talend /opt/my-user/
COPY entrypoint.sh /opt/my-user/
RUN chmod +x /opt/my-user/entrypoint.sh
RUN chmod +x /opt/my-user/ETLJob/ETLJob_run.sh
RUN chown -R my-user:my-user /opt/my-user/
RUN echo "*/2 * * * * /bin/sh /opt/my-user/ETLJob/ETLJob_run.sh >> /opt/my-user/joblogs/job.log 2>&1" >> /etc/cron.d/my-user-job
RUN chmod 0644 /etc/cron.d/my-user-job
RUN crontab -u my-user /etc/cron.d/my-user-job
RUN chmod u+s /usr/sbin/crond
USER my-user:my-user
ENTRYPOINT [ "/opt/my-user/entrypoint.sh" ]
My entrypoint.sh file is the following one:
#!/bin/bash
echo "Start cron"
crontab /etc/cron.d/diomedee-job
echo "cron started"
# Run forever
tail -f /dev/null
So far so good, the container is created successfully and when I go inside the container and I type crontab -l I see the crontab... but it is never executed
I can't figure out what I'm missing; any research I made didn't give me any clue
May you give me any tip?
Docker containers usually only host a single process. In your case, the tail process. The cron daemon isn't running.
Your comment 'cron started' seems to indicate that running crontab starts the daemon, but it doesn't.
Replace your tail -f /dev/null command with crond -f to run the cron daemon in the foreground and it should work.
I am trying to build my own docker image for apache2 and PHP. Can anyone tell my why my container exits after run when it supposes to run ["apache2ctl", "-D", "FOREGROUND"]?
FROM ubuntu:latest
RUN apt update -y && apt upgrade -y
RUN apt install software-properties-common -y
RUN add-apt-repository ppa:ondrej/php -y
RUN apt update -y && apt upgrade -y
ARG DEBIAN_FRONTEND=noninteractive
RUN DEBIAN_FRONTEND=noninteractive apt install -y nano vim iputils-ping sudo git curl php php-cli php-fpm
RUN apt install -y php-json php-mysql
RUN apt install -y php-zip php-mbstring php-curl php-xml php-pear php-bcmath
RUN apt install psmisc -y
ENV APACHE_RUN_USER www-data
ENV APACHE_RUN_GROUP www-data
ENV APACHE_LOF_DIR /var/log/apache2
# RUN useradd -ms /bin/bash devwl
EXPOSE 80/tcp
ENTRYPOINT ["/bin/sh", "-c"]
CMD ["apache2ctl", "-D", "FOREGROUND"]
Build command:
docker build -t www .
Run command:
docker run -itd -p 80:80 www
Ouput docker ps:
Just tried to build your Dockerfile. docker logs shows a problem with start command. Running container without -D option works well...
CMD ["apache2ctl", "start"]
Do you need to use <IfDefine ...> in conf files?
You need to delete the ENTRYPOINT line.
Since you have both an ENTRYPOINT and a CMD, they get combined together into a single argument list. That means you have an effective command like
ENTRYPOINT+CMD ["/bin/sh", "-c", "apache2ctl", "-D", "FOREGROUND"]
But sh -c only reads in the single next argument and executes it. The remaining arguments would be accessible inside that string as positional parameters $0, $1, ... but unless you refer to one of those then the command you're eventually running is only apachectl with no arguments.
You only need to invoke a shell at all if your command uses shell features (referencing environment variables or running multiple commands). Yours doesn't, so you don't need anything that mentions a shell; just delete the ENTRYPOINT and have the existing CMD start Apache.
In a Dockerfile, you shouldn't usually need to say sh -c at all. If you do need to invoke a shell to run some command, you can use Docker shell syntax as a plain string without the JSON-array syntax; for example
# needs a shell because of $VARIABLE and command; command syntax
CMD touch "$APACHE_LOG_DIR/started"; exec apache2ctl -DFOREGROUND
(If you do need to override this command with docker run arguments or in a Compose command:, these syntaxes will not automatically insert a shell wrapper and there you do need to specifically say sh -c 'some command' if you need a shell to process the command string; again note the single quotes to make the command string a single argument.)
I have created a Dockerfile based on the description to create a rails application in Linux. Currently, I have two problems with the current setting:
First, I get the error or warning after every RUN command starting with the environment variable $shell. The error looks like this:
mesg: ttyname failed: Inappropriate ioctl for device
Second, my container stops directly after starting it with
docker run -d --name rails rails:test
My current docker file looks like this:
FROM ubuntu:18.04
RUN mkdir /usr/src/rails
WORKDIR /usr/src/rails
RUN apt-get update && apt-get install -y curl gnupg
RUN curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add -
RUN echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list
RUN apt-get update && apt install -y yarn
RUN curl -sSL https://get.rvm.io | bash
RUN useradd -G rvm rails
ENV shell /bin/bash -l -c
#RUN . /usr/local/rvm/scripts/rvm
RUN echo ". /etc/profile.d/rvm.sh" >> ~/.bashrc
RUN $shell "rvm requirements"
RUN $shell "rvm install ruby"
RUN echo "gem: --no-rdoc --no-ri" >> ~/.gemrc
RUN $shell "gem install rails"
RUN $shell "ruby -v" && $shell "rails -v"
USER rails
EXPOSE 3000
#CMD ["rails", "server", "-b", "0.0.0.0"]
CMD ["/bin/bash"]
The solution with the $shell variable I found on another website. Without the command /bin/bash -l -c the build process will fail. The command rvm or gem will be unknown. The mentioned command will be used as a wrapper around the real command inside the quotes. I do not really understand why this is necessary. If I create a docker container and execute the commands like they are in the Dockerfile, then everything works fine. Why it is not working as I execute the command inside of the Dockerfile script?
Since I use the wrapper command, everything works well, but I get this error or warning message mentioned above. The image will be made, so this is more like a minor problem. The main problem is, that my container doesn't start. If I type the command docker run -d rails:test the container will be exited directly after. I do not really understand why. Does anyone have some explanations?
I don't know why this line return 1 when I run it a docker file:
RUN sh -c "$(wget https://raw.githubusercontent.com/robbyrussell/oh-my-zsh/master/tools/install.sh -O -)"
I have wget install and I don't know why it's return 1 (no error message)
No idea, but you don't have to use the one step install shorthand which might give you a better idea of where the command is failing.
RUN set -uex; \
wget https://raw.githubusercontent.com/robbyrussell/oh-my-zsh/master/tools/install.sh; \
sh ./install.sh; \
rm ./install.sh
I think it's due to the interactive part of the installation script.
You should generate previously .zshrc.
RUN apt-get install -y zsh
RUN git clone https://github.com/robbyrussell/oh-my-zsh \
<installation_path>/.oh-my-zsh
COPY conf/.zshrc <installation_path>/.zshrc
when you run the following command to install oh-my-zsh, the command installed oh-my-zsh successfully and exited with code 1. (you can run echo $? to check).
sh -c "$(wget https://raw.githubusercontent.com/robbyrussell/oh-my-zsh/master/tools/install.sh -O -)"
echo $? #output 1
But, the docker build shell thought it's an error when commands execute without returning code 0. To solve it, we can append a zero-returned command after the install command:
RUN sh -c "$(wget https://raw.githubusercontent.com/robbyrussell/oh-my-zsh/master/tools/install.sh -O -)"; exit 0;
I'm trying to install Miniconda in a docker image as a first step, right now this is what I have:
FROM ubuntu:14.04
RUN apt-get update && apt-get install wget
RUN wget *miniconda download URL* && bash file_downloaded.sh
When I try to build the image, it goes well until it starts popping the following message continously:
>>> Please answer 'yes' or 'no'
At that point I need to stop docker build. How can I fix it? Should I include something in the dockerfile?
You can't attach interactive tty during image build. If it is asking for 'yes' or 'no' during package installation, wget in your case, you can replace the corresponding line with RUN apt-get update -qq && apt-get install -y wget. If it is bash file_downloaded.sh, check if file_downloaded.sh accepts 'yes' or 'no' as a command line argument.
If file_downloaded.sh doesn't have that option, create a container from ubuntu:14.04 image, install wget and run your commands manually there. Then, you can make an image of the container by committing your changes like: docker commit <cotainer_id> <image_name>.
I believe you can pass -b flag to miniconda shell script to avoid manual answering
Installs Miniconda3 4.0.5
-b run install in batch mode (without manual intervention),
it is expected the license terms are agreed upon
-f no error if install prefix already exists
-h print this help message and exit
-p PREFIX install prefix, defaults to $PREFIX
something like that:
RUN wget http://......-x86_64.sh -O miniconda.sh
RUN chmod +x miniconda.sh \
&& bash ./miniconda.sh -b