From 1774418e225ea2857ec26a89f98d91fd84194df3 Mon Sep 17 00:00:00 2001 From: raphael Date: Thu, 19 Feb 2026 17:13:18 +0300 Subject: [PATCH] -- adds Idempotency guard for if composer download fails during build. --- Dockerfile | 14 ++-- playsms/docker-setup.sh | 147 +++++++++++++++++++++++++--------------- 2 files changed, 101 insertions(+), 60 deletions(-) mode change 100755 => 100644 playsms/docker-setup.sh diff --git a/Dockerfile b/Dockerfile index 292ec8b..30c208e 100644 --- a/Dockerfile +++ b/Dockerfile @@ -32,11 +32,17 @@ RUN sed -i /etc/php83/php-fpm.d/www.conf -e 's/^listen = 127.0.0.1:9000/listen = sed -i /etc/php83/php-fpm.d/www.conf -e 's/^;listen.group = nobody/listen.group = playsms/' && \ sed -i /etc/php83/php.ini -e 's/^display_errors = Off/display_errors = On/' && \ sed -i /etc/php83/php.ini -e "s#^;date.timezone =#date.timezone = ${TZ}#" - + RUN rm -rf /home/playsms && mkdir -p /home/playsms && chown playsms:playsms -R /home/playsms && chmod 0755 /home/playsms && \ rm -rf /var/www && mkdir -p /var/www && chown playsms:playsms -R /var/www && chmod 0755 /var/www && \ echo 'export PATH=$PATH:/home/playsms/bin' > /home/playsms/.profile +# Install Composer at build time so it is always available without a network +# call at container startup. This avoids runtime download failures and the +# cascading restart loop they cause. +RUN curl -sS https://getcomposer.org/installer | php83 -- --install-dir=/usr/local/bin --filename=composer && \ + chmod +x /usr/local/bin/composer + COPY /playsms/supervisor.conf /etc/supervisor.conf COPY /playsms/run.sh /run.sh COPY /playsms/runner_php-fpm.sh /runner_php-fpm.sh @@ -45,9 +51,9 @@ COPY /playsms/docker-setup.sh /_docker-setup.sh COPY /playsms/healthcheck.sh /usr/bin/healthcheck.sh RUN chown playsms:playsms -R /_docker-setup.sh /etc/php83 && \ - chmod 0755 /run.sh /runner_php-fpm.sh /runner_playsmsd.sh /usr/bin/healthcheck.sh && \ - chmod 0644 /_docker-setup.sh && \ - chmod 0777 -R /var/log + chmod 0755 /run.sh /runner_php-fpm.sh /runner_playsmsd.sh /usr/bin/healthcheck.sh && \ + chmod 0644 /_docker-setup.sh && \ + chmod 0777 -R /var/log #USER playsms diff --git a/playsms/docker-setup.sh b/playsms/docker-setup.sh old mode 100755 new mode 100644 index 92d2e6a..697eb23 --- a/playsms/docker-setup.sh +++ b/playsms/docker-setup.sh @@ -5,6 +5,7 @@ MYSQL_PWD=$PLAYSMS_DB_PASS MYSQL_DBNAME=$PLAYSMS_DB_NAME MYSQL_HOST=$PLAYSMS_DB_HOST MYSQL_TCP_PORT=$PLAYSMS_DB_PORT + PATHSRC="/home/playsms/src" PATHWEB="/home/playsms/web" PATHLIB="/home/playsms/lib" @@ -34,101 +35,135 @@ echo "playSMS conf path = $PATHCONF" echo echo "==================================================================" echo -INSTALLED=0 && -mkdir -p $PATHCONF $PATHBIN $PATHLIB $PATHLOG $PATHWEB && -git clone --branch $PLAYSMS_VERSION --depth=1 https://github.com/playsms/playsms.git $PATHSRC && -cd $PATHSRC && -./getcomposer.sh && -cp -rR -f web/* $PATHWEB/ && -cp -f web/config-dist.php $PATHWEB/config.php && -ln -s $PATHSRC/daemon/linux/bin/playsmsd.php $PATHBIN/playsmsd && -touch $PATHCONF/playsmsd.conf && -touch $PATHLOG/audit.log $PATHLOG/playsms.log && -ln -s $PATHWEB /var/www/html && -ln -s /etc/php83 /home/playsms/php83 && -chmod -R 0777 $PATHLOG $PATHWEB/storage && -chown -R playsms:playsms $PATHCONF $PATHBIN $PATHLIB $PATHLOG $PATHWEB && -INSTALLED=1 + +# ------------------------------------------------------------------ +# Idempotency guard: +# If a previous run cloned the repo but failed before finishing +# (e.g. composer download error), the src dir exists but is broken. +# Detect a successful prior install via a sentinel file written only +# on success. On a failed partial install, clean up and retry. +# ------------------------------------------------------------------ +SENTINEL="$PATHCONF/.installed" + +if [ -f "$SENTINEL" ]; then + echo "playSMS already installed (sentinel found). Skipping installation." + exit 0 +fi + +# Clean up any incomplete previous attempt +if [ -d "$PATHSRC" ]; then + echo "Removing incomplete previous source directory..." + rm -rf "$PATHSRC" +fi + +INSTALLED=0 && \ + mkdir -p $PATHCONF $PATHBIN $PATHLIB $PATHLOG $PATHWEB && \ + git clone --branch $PLAYSMS_VERSION --depth=1 https://github.com/playsms/playsms.git $PATHSRC && \ + cd $PATHSRC && \ + composer install --no-interaction --no-dev --optimize-autoloader && \ + cp -rR -f web/* $PATHWEB/ && \ + cp -f web/config-dist.php $PATHWEB/config.php && \ + ln -sf $PATHSRC/daemon/linux/bin/playsmsd.php $PATHBIN/playsmsd && \ + touch $PATHCONF/playsmsd.conf && \ + touch $PATHLOG/audit.log $PATHLOG/playsms.log && \ + ln -sf $PATHWEB /var/www/html && \ + ln -sf /etc/php83 /home/playsms/php83 && \ + chmod -R 0777 $PATHLOG $PATHWEB/storage && \ + chown -R playsms:playsms $PATHCONF $PATHBIN $PATHLIB $PATHLOG $PATHWEB && \ + INSTALLED=1 + if [ ! "$INSTALLED" = "1" ]; then - echo "playSMS installation has failed. Exitting..." - exit 128 + echo "playSMS installation has failed. Exitting..." + exit 128 fi + echo echo "==================================================================" echo + sed -i "s/#MYSQL_HOST#/$MYSQL_HOST/g" $PATHWEB/config.php sed -i "s/#MYSQL_TCP_PORT#/$MYSQL_TCP_PORT/g" $PATHWEB/config.php sed -i "s/#MYSQL_DBNAME#/$MYSQL_DBNAME/g" $PATHWEB/config.php sed -i "s/#MYSQL_USER#/$MYSQL_USER/g" $PATHWEB/config.php sed -i "s/#MYSQL_PWD#/$MYSQL_PWD/g" $PATHWEB/config.php sed -i "s|#PATHLOG#|$PATHLOG|g" $PATHWEB/config.php -echo "PLAYSMS_PATH=\"$PATHWEB\"" > $PATHCONF/playsmsd.conf -echo "PLAYSMS_LIB=\"$PATHLIB\"" >> $PATHCONF/playsmsd.conf -echo "PLAYSMS_BIN=\"$PATHBIN\"" >> $PATHCONF/playsmsd.conf -echo "PLAYSMS_LOG=\"$PATHLOG\"" >> $PATHCONF/playsmsd.conf -echo "DAEMON_SLEEP=\"1\"" >> $PATHCONF/playsmsd.conf + +echo "PLAYSMS_PATH=\"$PATHWEB\"" > $PATHCONF/playsmsd.conf +echo "PLAYSMS_LIB=\"$PATHLIB\"" >> $PATHCONF/playsmsd.conf +echo "PLAYSMS_BIN=\"$PATHBIN\"" >> $PATHCONF/playsmsd.conf +echo "PLAYSMS_LOG=\"$PATHLOG\"" >> $PATHCONF/playsmsd.conf +echo "DAEMON_SLEEP=\"1\"" >> $PATHCONF/playsmsd.conf echo "ERROR_REPORTING=\"E_ALL ^ (E_NOTICE | E_WARNING)\"" >> $PATHCONF/playsmsd.conf + echo "playSMS daemon config file: $PATHCONF/playsmsd.conf" echo cat $PATHCONF/playsmsd.conf echo echo "==================================================================" echo + FRESH_INSTALL=0 SQL_FILE="$PATHSRC/db/playsms.sql" + if echo "SELECT uid FROM playsms_tblUser WHERE status=2;" | mysql -u${MYSQL_USER} -p${MYSQL_PWD} -h${MYSQL_HOST} -P${MYSQL_TCP_PORT} ${MYSQL_DBNAME} &>/dev/null; then - echo "Database already exists." - echo "Importing data skipped and installation process will continue." + echo "Database already exists." + echo "Importing data skipped and installation process will continue." else - echo "CREATE DATABASE ${MYSQL_DBNAME};" | mysql -u${MYSQL_USER} -p${MYSQL_PWD} -h${MYSQL_HOST} -P${MYSQL_TCP_PORT} &>/dev/null - echo "Importing data to database..." - if mysql -u${MYSQL_USER} -p${MYSQL_PWD} -h${MYSQL_HOST} -P${MYSQL_TCP_PORT} ${MYSQL_DBNAME} < ${SQL_FILE} &>/dev/null; then - echo "Database has been installed successfully." - FRESH_INSTALL=1 - else - echo "ERROR: Failed to import data from ${SQL_FILE} to database ${MYSQL_DBNAME}." - echo - echo "Installation process will continue but you may have a broken system." - echo - echo "Make sure database related configuration are all good before trying again." - fi + echo "CREATE DATABASE ${MYSQL_DBNAME};" | mysql -u${MYSQL_USER} -p${MYSQL_PWD} -h${MYSQL_HOST} -P${MYSQL_TCP_PORT} &>/dev/null + echo "Importing data to database..." + if mysql -u${MYSQL_USER} -p${MYSQL_PWD} -h${MYSQL_HOST} -P${MYSQL_TCP_PORT} ${MYSQL_DBNAME} < ${SQL_FILE} &>/dev/null; then + echo "Database has been installed successfully." + FRESH_INSTALL=1 + else + echo "ERROR: Failed to import data from ${SQL_FILE} to database ${MYSQL_DBNAME}." + echo + echo "Installation process will continue but you may have a broken system." + echo + echo "Make sure database related configuration are all good before trying again." + fi fi + echo echo "==================================================================" echo + if [ "$FRESH_INSTALL" == "1" ]; then - WEB_ADMIN_PASSWORD_HASHED="$(php -r "echo password_hash(\"$WEB_ADMIN_PASSWORD\", PASSWORD_BCRYPT, [\"cost\"=>12]);")" - if echo "UPDATE playsms_tblUser SET password='$WEB_ADMIN_PASSWORD_HASHED' WHERE username='admin';" | \ - mysql -u${MYSQL_USER} -p${MYSQL_PWD} -h${MYSQL_HOST} -P${MYSQL_TCP_PORT} ${MYSQL_DBNAME} &>/dev/null; - then - echo "Web admin password has been successfully updated." - echo - echo "WARNING:" - echo " - Web admin username is admin" - echo " - Web admin password is $WEB_ADMIN_PASSWORD" - echo " - This is just the default admin password" - echo " - Login and change it to your own strong password" - sleep 5 - else - echo "WARNING: Failed to update web admin password." - fi - echo - echo "==================================================================" - echo + WEB_ADMIN_PASSWORD_HASHED="$(php -r "echo password_hash(\"$WEB_ADMIN_PASSWORD\", PASSWORD_BCRYPT, [\"cost\"=>12]);")" + if echo "UPDATE playsms_tblUser SET password='$WEB_ADMIN_PASSWORD_HASHED' WHERE username='admin';" | \ + mysql -u${MYSQL_USER} -p${MYSQL_PWD} -h${MYSQL_HOST} -P${MYSQL_TCP_PORT} ${MYSQL_DBNAME} &>/dev/null; + then + echo "Web admin password has been successfully updated." + echo + echo "WARNING:" + echo " - Web admin username is admin" + echo " - Web admin password is $WEB_ADMIN_PASSWORD" + echo " - This is just the default admin password" + echo " - Login and change it to your own strong password" + sleep 5 + else + echo "WARNING: Failed to update web admin password." + fi + echo + echo "==================================================================" + echo fi + echo "playSMS has been installed on your system" echo echo "Your playSMS daemon script operational guide:" -echo +echo echo "- To start it : playsmsd start" echo "- To stop it : playsmsd stop" echo "- To check it : playsmsd check" echo echo "==================================================================" -echo +echo echo "INSTALLATION FINISHED." echo echo "==================================================================" echo +# Write sentinel file to mark successful installation +touch "$SENTINEL" + exit 0