I know this isn't an actual docker way. But, I need to convert a custom distro into a container. So, far I was able to run the container and bash into the container and execute a script. As long as I left the console container terminates. Here is the process for the container creation from a Raspbx.img file. After mounting the image:
mkdir rootfs raspbxfdisk -l -u=sectors /home/pi/raspbx-10-10-2020.img
mount -o loop,offset=272630784 /home/pi/raspbx-10-10-2020.img /rootfs
Then,
cp -a /rootfs/. /raspbx/
nano /raspbx/run/startup.sh
chmod +x /run/*
tar -C raspbx -c . | docker import - raspbx
After this I was able to run the container using:
docker run --name=raspbx -it --privileged --restart unless-stopped raspbx bash
cd /run
./startup.sh
At this point, script runs fine and I can access the webui. But, the container stops if I exit the shell.So, I tried
So, I tried
docker run --name=raspbx --net=macvlan_network --ip=192.168.188.27 -itd --privileged --restart no --entrypoint=/bin/bash raspbx
This time the script executes, but as soon as the container finishes executing the script it stops working. Same result with Dockerfile:
FROM raspbx
ENTRYPOINT ["sh", "/run/startup.sh"]
EXPOSE 80 3306 5060 5061 5160 5161 4569 10000-20000/udp
And
FROM raspbx
ENTRYPOINT ["bash", "/run/startup.sh"]
EXPOSE 80 3306 5060 5061 5160 5161 4569 10000-20000/udp
The script is:
#!/bin/bash -x
#https://docs.docker.com/engine/admin/multi-service_container/
/etc/init.d/mysql start
status=$?
if [ $status -ne 0 ]; then
echo "Failed to start mysql: $status"
exit $status
fi
fwconsole start
if [ $status -ne 0 ]; then
echo "Failed to start fwconsole: $status"
exit $status
fi
#restore backup if exists
if [ -f /backup/new.tgz ]; then
echo "Restoring backup from /backup/new.tgz"
php /var/www/html/admin/modules/backup/bin/restore.php --items=all --restore=/backup/new.tgz
echo "Done"
fi
#restart freepbx to load everything fine after restoring backup
fwconsole stop
if [ $status -ne 0 ]; then
echo "Failed to stop fwconsole: $status"
exit $status
fi
fwconsole start
if [ $status -ne 0 ]; then
echo "Failed to start fwconsole: $status"
exit $status
fi
/etc/init.d/apache2 start
status=$?
if [ $status -ne 0 ]; then
echo "Failed to start apache2: $status"
exit $status
fi
/run/backup.sh &
status=$?
if [ $status -ne 0 ]; then
echo "Failed to start backup.sh: $status"
exit $status
fi
/run/delete-old-recordings.sh &
status=$?
if [ $status -ne 0 ]; then
echo "Failed to start delete-old-recordings: $status"
exit $status
fi
while /bin/true; do
ps aux |grep mysqld |grep -q -v grep
MYSQL_STATUS=$?
ps aux |grep asterisk |grep -q -v grep
ASTERISK_STATUS=$?
ps aux |grep '/run/backup.sh' |grep -q -v grep
BACKUPSCRIPT_STATUS=$?
echo "Checking running processes..."
if [ $MYSQL_STATUS -ne 0 -o $ASTERISK_STATUS -ne 0 -o $BACKUPSCRIPT_STATUS -ne 0 ]; then
echo "One of the processes has already exited."
exit -1
fi
echo "OK"
sleep 60
done
The only way I was able to keep it alive more then 24hrs is:
docker run --name=raspbx --net=macvlan_network --ip=192.168.188.27 -itd --privileged --restart no --entrypoint=/bin/bash raspbx -c 'sleep inf'
So, how do I keep the container keep alive, any help will be highly appreciated.
Docker containers are stopped whenever the main process exits. You run a number of services in the background, so you don't really have a main process.
The 'docker way' of doing what you're doing is to have each service in its own container. Ie Mysql in one container and Apache in another etc.
If you want to keep it the way you have it set up now, you can 'promote' one of the services to be the main process and run it in the foregound. If you take Apache, you can run it with the FOREGROUND switch. That's what the official Apache Docker image does using this script: https://github.com/docker-library/httpd/blob/4d89a55e9e5742bebd10fddf83ffb07f2df4d7a0/2.4/httpd-foreground
Another solution is to have a dummy process running as you've discovered with the sleep
command. Another command I've seen used is tail -f /dev/null
.
In order to keep a container running for debugging purposes, I add the following ENTRYPOINT
command at the end of the Dockerfile:
ENTRYPOINT ["tail", "-f", "/dev/null"]
This allows me to connect locally to the Docker Container in development and run manually any script I'm developing (eg run.sh
, run.py
). I find this very useful and a more interactive way of developing / testing my scripts in a Docker Container.
Source: https://devopscube.com/keep-docker-container-running/
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.