Reputation: 43
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
?
Upvotes: 0
Views: 1948
Reputation: 374
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
CMD
line from the DockerfileEg:
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.
Upvotes: 1
Reputation: 7853
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
Upvotes: 0