I run my Dockerfile (through docker-compose) with my own entry point. At the end I would like to run a command from CMD. Unfortunately the command is not launched I don't know why. I don't know what I do wrong.
My entrypoint:
#!/bin/bash
/usr/bin/supervisord -c /etc/supervisord.conf &
/usr/sbin/crond &
su - www-data
exec "$#"
My Dockerfile
EXPOSE 9000
ENTRYPOINT "/root/entrypoint.sh"
CMD ["php-fpm"]
When I run the docker-compose up I see that: api_1 exited with code 0. I tried running echo "$#" and it returns empty string. What can I do to make the php-fpm start? Is this the right way to solve this problem?
It turns out that if you use ENTRYPOINT without [] the instruction from CMD is not passed to entrypoint script. I changed ENTRYPOINT to ENTRYPOINT ["/root/entrypoint.sh"] and now everything is working fine :)
Related
Here is my Dockerfile:
FROM ros:kinetic-ros-core-xenial
CMD ["bash"]
If I run docker build -t ros . && docker run -it ros, and then from within the container echo $PATH, I'll get:
/opt/ros/kinetic/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
If I exec into the container (docker exec -it festive_austin bash) and run echo $PATH, I'll get:
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
Why are the environment variables different? How can I get a new bash process on the container with the same initial environment?
The ENTRYPOINT command is only invoked on docker run, not on docker exec.
I assume that this /ros_entrypoint.sh script is responsible for adding stuff to PATH. If so, then you could do something like this for docker exec:
docker exec -it <CONTAINER_ID> /ros_entrypoint.sh bash
docker exec only gets environment variables defined in Dockerfile with instruction ENV. With docker exec [...] bash you additionally get those defined somewhere for bash.
Add this line to your Dockerfile:
ENV PATH=/opt/ros/kinetic/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
or shorter:
ENV PATH=/opt/ros/kinetic/bin:$PATH
This is old question but since it's where google directed me I thought I'll share solution I ended up using.
In your entrypoint script add a section similar to this:
cat >> ~/.bashrc << EOF
export PATH="$PATH"
export OTHER="$OTHER"
EOF
Once you rebuild your image you can exec into your container (notice bash is invoked in interactive mode):
docker run -d --rm --name container-name your_image
docker exec -it container-name /bin/bash -i
If you echo $PATH now it should be the same as what you have set in .bashrc
The following install.sh script file automate the installation of my Laravel dependencies inside a container:
#!/bin/bash
LOGFILE=/tmp/install_diario_$(date +"%Y%m%d%H%M%S").log
[ -f ../.env ] || cp ../.env.docker ../.env
function error {
echo -e "\e[31m\e[1m[ERROR]"
echo -e 'See' $LOGFILE 'to more information\e[0m'
exit 1
}
function ok {
echo -e "\t\e[32m\e[1m[OK]\e[0m"
}
function installed {
echo -e "\t\e[29m\e[1m[OK]\e[0m"
}
echo '[+] Installing PHP packages'
composer install -d "/var/www/html" 2>> $LOGFILE >> $LOGFILE
if [ $? -eq 1 ]; then
echo '[!] Configuration Aborted. Exiting...'
fi
echo '[+] Generating app keys'
php ../artisan key:generate #2>> $LOGFILE >> $LOGFILE
php ../artisan passport:install #2>> $LOGFILE >> $LOGFILE
echo '[+] Populating database'
# cd .. && make resetdb
echo '[+] Backend installation sucessfull.'
echo ""
php ../artisan passport:show
echo '[+] Front-end install'
npm install 2>> $LOGFILE >> $LOGFILE
However, I don't want to run this manually, but while the container is starting. So I tried using the following commands in my Dockerfile:
WORKDIR /var/www/html/docker
ADD install.sh .
RUN chmod +x ./install.sh
CMD ./install.sh
Obs.: the script is inside a folder called docker
But when I run docker-compose up --build -d my container exits after a few seconds (when the script is done).
I tried looking for solutions but none worked for me (e.g. including /bin/bash in the end of my script).
Does anyone know if this is actually possible to be done, or should I just tell my workmates to run this script manually with docker exec -it <app_id> install.sh?
The problem here is the following line in your Dockerfile:
CMD ./install.sh
Indeed, your script overrides (ie is called in place of) the default php-fpm command.
Solution 1: add a line at the end of your install.sh script to invoke php-fpm
exec "php-fpm"
CAVEAT: php-fpm MUST NOT be launched as a service, it must run in the foreground to keep the container up and running.
Solution 2: implement a custom entrypoint that launches the install script
Remove/comment the CMD line from the Dockerfile
Implement the customized entrypoint script.
Eg:
In the Dockerfile:
# Don't override COMMAND, use the default one
#CMD ./install.sh
COPY entrypoint /usr/bin/
RUN chmod +x /usr/bin/entrypoint
ENTRYPOINT /usr/bin/entrypoint
And the entrypoint script:
# Run the install script
/path/to/install.sh
# Execute the default command, ie php-fpm
exec "$#"
*NB: Here is the minimum basic working code, feel free to customize/enrich this example - using the official docker php entrypoint for instance.
To a docker container, there is no distinction between its first start up from the consequence start unless you put some kind of file in a mounted volume.
What you probably want is a start up script that knows if this is the first start, run the install script, then remember to not run it again.
So besides your install script, you should probably have a start up script like this:
#!/bin/bash
# Assuming you mount this folder to your host system
MOUNTED_VAR=/var/run/laravel
# Only run the install on first run
if [ ! -f $MOUNTED_VAR/installed ]; then
./install.sh
fi
# Some command to start the service, for example
systemctl start php-fpm
In your docker file, you need to also include this
script to start.
WORKDIR /var/www/html/docker
ADD install.sh .
RUN chmod +x ./install.sh
ADD start.sh .
RUN chmod +x ./start.sh
CMD ./start.sh
This question already has answers here:
Why can't I use Docker CMD multiple times to run multiple services?
(5 answers)
Closed 4 years ago.
I have a dockerfile that sets up NGINX, PHP, adds a Wordpress Repository. I want at boot time, to start PHP and NGINX. However, I am failing to do so. I tried adding the two commands in the CMD array, and I also tried to put them in a shell file and starting the shell file. Nothing worked. Below is my Dockerfile
FROM ubuntu:16.04
WORKDIR /opt/
#Install nginx
RUN apt-get update
RUN apt-get install -y nginx=1.10.* php7.0 php7.0-fpm php7.0-mysql
#Add the customized NGINX configuration
RUN rm -f /etc/nginx/nginx.conf
RUN rm -f /etc/nginx/sites-enabled/*
COPY nginx/nginx.conf /etc/nginx/
COPY nginx/site.conf /etc/nginx/sites-enabled
#Copy the certificates
RUN mkdir -p /etc/pki/nginx
COPY nginx/certs/* /etc/pki/nginx/
RUN rm -f /etc/pki/nginx/placeholder
#Copy the build to its destination on the server
RUN mkdir -p /mnt/wordpress-blog/
COPY . /mnt/wordpress-blog/
#COPY wp-config.php
COPY nginx/wp-config.php /mnt/wordpress-blog/
#The command to run the container
CMD ["/bin/bash", "-c", "service php7.0-fpm start", "service nginx start"]
I tried to put the commands in the CMD in a shell file, and run the shell file in the CMD command. It still didn't work. what am i missing?
start.sh
#!/bin/bash
/usr/sbin/service php7.0-fpm start
/usr/sbin/service nginx start
tail -f /dev/null
Dockerfile
COPY ["start.sh", "/root/start.sh"]
WORKDIR /root
CMD ["./start.sh"]
With this, you can put more complex logic in start.sh.
You can replace the CMD line for some like ...
CMD ["/bin/bash", "-c", "/usr/sbin/service php7.0-fpm start && nginx -g 'daemon off;'"]
TL;DR: You don't have an entry point.
Main idea in the Docker is to have one responsibility per container. So, in order to keep running a Docker container you have to start a program in foreground upon container boot.
However, in your Dockerfile, there is no entrypoint to start a program in foreground. So, just after your container boot, your container exits.
So, in order to prevent your container from exiting, just start a program in foreground.
Nginx for instance.
Example scenario:
entrypoint.sh content:
#!/bin/bash
service php7.0-fpm start
nginx -g 'daemon off;
somewhere in Dockerfile:
COPY [ "./entrypoint.sh", "/root/entrypoint.sh" ]
at the end of the Dockerfile:
ENTRYPOINT /root/entrypoint.sh
I am a beginner in using Docker, and I am trying to run docker from php, specifically I need to run openface code. I used the command lines provided here https://cmusatyalab.github.io/openface/setup/ to make sure that docker is running on my pc correclty and it works. but now I need to call it from PHP, I wrote the same commands in batch file as follows
docker run -p 9000:9000 -p 8000:8000 -t -i bamos/openface /bin/bash
cd /root/openface
./demos/compare.py images/examples/{lennon*,clapton*}
pause
and tried to execute it in php by calling
echo shell_exec ("test.bat");
but when I run the batch file directly, only the first line is executed. as it seems the next command is not being executed inside the docker container.
how can I make all commands execute?
any help will be very much appreciated,
thank you
The problem is the first bash won't exit before you exit it and the rest of the commands are interpreted by host bash.
What you need is that your work is done and then you get inside a bash (inside the container)
docker run -p 9000:9000 -p 8000:8000 -t -i bamos/openface /bin/bash -c "cd /root/openface && ./demos/compare.py images/examples/{lennon*,clapton*} && exec bash"
First "bash -c" is to execute the commands and last command exec bash override the main bash and gives you a shell
Read a lot of topics, but couldn't understand what's going on. All is working fine before I add ENTRYPOINT to my Dockerfile. Container stops immediately without demonizing php-fpm:
FROM php:5.6-fpm
// ..Some installation instructions
# Entrypoint script
COPY ./run.sh /run.sh
RUN chmod +x /run.sh
ENTRYPOINT ["/run.sh"]
CMD ["php-fpm"]
The content of run.sh:
# Install all dependencies
php -d allow_url_fopen=on /usr/local/bin/composer install
As I understand my entrypoint will be executed with run.sh and then exited. If I will remove it then default entrypoint will be starting nginx in background. What is the best solution to run shell scripts without redefining entrypoint? Or maybe I'm talking wrong things..
ENTRYPOINT and CMD are combined to create the final COMMAND that is run when the container is started. In your case this gives:
["/run.sh", "php-fpm"]
which means that php-fpm acts as an argument to the /run.sh script. That's obviously not what you want.
You can fix this by starting php-fpm inside your script AND making sure that it runs as PID1 using exec. Running the main process as Process ID 1 assures that it will receive SIGKILL and SIGTERM interrupts (Ctrl-C for instance) and exit gracefully if possible.
# Install all dependencies
php -d allow_url_fopen=on /usr/local/bin/composer install
exec php-fpm
Your CMD should then be empty (or removed, as specifying an ENTRYPOINT also resets the CMD):
CMD []
Then in your container you can specify arguments to php-fpm via the command. Eg:
docker run -d my_php_fpm_image --help
The problem is this:
starting nginx in background
You need a process running in the foreground. If there is none, the container will exit. I think you should keep nginx running in the foreground.
To do this, use:
php-fpm -F -R
From php-fpm help:
-F, --nodaemonize force to stay in foreground, and ignore daemonize option from config file
-R, --allow-to-run-as-root Allow pool to run as root (disabled by default)
Found the way to put composer in a separate container. So i will not touch my php-fpm at all, as the best practice is one process per container.
My app container that contains all project files (composer.json, .git etc.) will provide Dockerfile:
FROM composer/composer:php5
# Set application directory
WORKDIR /var/www/html
ENTRYPOINT /usr/local/bin/composer install
CMD ["true"]
After initiating docker-compose up -d this will bring all the dependencies from composer.json into mapped directory.