0

I have the following working systemctl systemd startup script that automatically starts on reboot perfectly (other dbdeployer dependency starting too).

Its a .sh script where I created a few different 'states', basically for the services called.

(One startup script uses docker-compose project, while the other is for a dbdeployer mysql instance)

Systemd service unit for docker-compose containers:

[Unit]
Description=Magento 2.3.5 Docker-Compose Containers
After=dbdeployer-mysql-5-731-in-1.service
Requires=docker.service dbdeployer-mysql-5-731-in-1.service

[Service]
EnvironmentFile=/var/www/_systemd.startups_/glolighting/magento/2_35/docker-compose.mag2.35.env.file
#Environment=FILE_SCRIPT=/var/www/docker/_systemd.startups_/magento/2_35/dc-glo-mag235.sh
#PassEnvironment=$DCFOLDER
Type=simple
TimeoutStartSec=0
Restart=always
RestartSec=4s
RemainAfterExit=yes
#WorkingDirectory=${DC_PROJECT_FOLDER}
ExecStartPre=mkdir -p ${LOGFOLDER}
ExecStartPre=echo ${DC_PROJECT_FOLDER}
ExecStartPre=echo Starting Docker-compose service for ${DESCRIPTION}...
ExecStartPre=bash ${SERVICE_FILE_SCRIPT} ${DC_PROJECT_FOLDER} 1
ExecStart=bash ${SERVICE_FILE_SCRIPT} ${DC_PROJECT_FOLDER} 2
ExecStartPost=bash ${SERVICE_FILE_SCRIPT} ${DC_PROJECT_FOLDER} 1
ExecStop=bash ${SERVICE_FILE_SCRIPT} ${DC_PROJECT_FOLDER} 3
ExecStopPost=bash ${SERVICE_FILE_SCRIPT} ${DC_PROJECT_FOLDER} 1

[Install]
WantedBy=multi-user.target

The script being called by systemd:

____truncated for relevance___
# Continue on success
if [ $arguments_correct -eq 1 ]; then
   cd $PATH_DOCKER_COMPOSE_PROJECT_FILE

   if [ $OPTION -eq 1 ]; then
         echo "$LINE"
         echo ""
         $(which docker-compose) ps
         echo ""
         echo "$LINE"
   elif [ $OPTION -eq 2 ]; then
         $(which docker-compose) start
   elif [ $OPTION -eq 3 ]; then
         $(which docker-compose) stop
   fi
   exit 0
fi

I was hoping ExecStartPost=bash ${SERVICE_FILE_SCRIPT} ${DC_PROJECT_FOLDER} 1 will supply me with the correct output, (in other words $(which docker-compose) ps, but there is a delay - docker containers can take from ~3-10 seconds. So, since this status does not update (requery) everytime you call the status command, I only see the output when the original ExecStartPost occurred.

To summarize: once I do systemctl status docker-compose-mag235.service, I will get output to say that some docker-containers are still exit/starting state.

Question

Is there any way to use systemctl status docker-compose-mage235.service (or equivalent systemctl command) that will be able to give me an updated status. _In other words: The status of $(which docker-compose) ps at the moment I ran this new systemctl command.

(Before creating these startup systemd services, I always assumed that the state is 're-queried' for every call, but then I realized it's just taking the last output from logfiles (most likely syslog)).

NOTE:

Calling /location/of/project/file/of/docker-compose.yml is possible, but I would rather just want to house different systemd services that I can query based on Docker Compose project, in other words I have multiple folders for different DC projects. And then I would need to create aliases, but before I do that I would know if systemd can help me.

6
  • There is no point in running docker-compose as $(which docker-compose). Either it's in the PATH, so it can be run as just docker-compose, or it's not in the PATH and which won't find it. – cas May 5 at 12:44
  • 1
    Also, quote your variables whenever you use them. In your code snippet above, all of the following should be double-quoted, not just "$LINE": $arguments_correct, $PATH_DOCKER_COMPOSE_PROJECT_FILE, and $OPTION – cas May 5 at 12:47
  • Finally, instead of having several ExecStartPre lines AND an ExecStart script, just have one script that does everything in the ExecStartPre and ExecStart lines. Probably ExecStartStop too. Same for ExecStop* entries too, they should be in their own script (a different script to ExecStart - or the same script called with different arguments). – cas May 5 at 13:05
  • Thank you for the advice regarding quotes, I realized that I do not always do that in my scripts. Its something I just need to get used to regarding scripts - examples most of the time show unquoted. $(which docker-compose) : makes sense, it is in the PATH. I was testing out ExecStart* behaviour, and it was just my misunderstanding (and my question maybe also showing that) that initially I thought status can be requeried via one of the Pre/Post* commands. The end plan is to combine everything into one script once everything worked. – CvRChameleon May 5 at 13:27
  • The ExecPre and ExecPost commands can't do what you want. They're run once, before (Pre) or after (Post) a service is started or stopped. BTW, in case it's not obvious, i made a typo with ExecStartStop in my comment above. That should be ExecStartPost. – cas May 5 at 13:33
2

No, it's not possible unless you can somehow make docker-compose send extra info to systemd's journal.

systemctl status shows the status of the service, and the most recent journal entries for the service.

You can view more log entries by running journalctl -b0 -p 0..7 -u docker-compose. That will give you all docker-compose journal log entries since the last reboot.

6
  • A pity, I will see if I can 'delay' the script completion, such that ExecStartPost can execute a bit later in time (or just combine everything into ExecStart as you suggest. – CvRChameleon May 5 at 14:22
  • 1
    There's no reason why your ExecStartPost script can't keep repeatedly checking if everything's started OK (with a second or 2 or more sleep between each check) before it finishes. Whether you can output more status info to the journal log - I don't know....maybe print to STDERR – cas May 5 at 14:25
  • That's what I will try. Thanks for your assistance and advice! – CvRChameleon May 5 at 14:27
  • @CvRChameleon if you have an answer that works for you, you should post it as an answer, not as an edit to my answer. and if you like your answer better than mine, then go right ahead and change your accepted answer (i won't be offended :-) – cas May 6 at 8:46
  • 1
    I think you should post that as an answer. You put in the work to figure it out. I just posted "nope, can't do it". An answer is whatever works, even if it's "you can't do it how you want, but here's how you can". – cas May 6 at 9:01
1

Thanks to @cas for pointing out that it is not possible to get an 'updated status' from systemd directly. He pointed me and advised:

There's no reason why your ExecStartPost script can't keep repeatedly checking if everything's started OK (with a second or 2 or more sleep between each check) before it finishes. Whether you can output more status info to the journal log - I don't know....maybe print to STDERR

This then made me realize that I could potentially just delay the script, as opposed to my original objective: getting status directly from systemd 'somestatuscommand-that-queries'.

In my case my script could be adapted slightly by giving an extra input argument only when ExecStartPost and ExecStopPost executes.

Extra input arguments only for these commands:

ExecStartPost=bash ${SERVICE_FILE_SCRIPT} ${DC_PROJECT_FOLDER} 1 **4**
ExecStopPost=bash ${SERVICE_FILE_SCRIPT} ${DC_PROJECT_FOLDER} 1 **4**
____truncated for relevance___
# Continue on success
if [ $arguments_correct -eq 1 ]; then
   cd $PATH_DOCKER_COMPOSE_PROJECT_FILE

   if [ $OPTION -eq 1 ]; then
      if [ $sleep_correct -eq 1]; then
         # Sleep here when requested (and sleep input verified above)
         sleep $SLEEP
      fi
      #Now docker-compose ps has been given enough time to query after containers were started/stopped.
         echo "$LINE"
         echo ""
         $(which docker-compose) ps
         echo ""
         echo "$LINE"
   elif [ $OPTION -eq 2 ]; then
         $(which docker-compose) start
   elif [ $OPTION -eq 3 ]; then
         $(which docker-compose) stop
   fi
   exit 0
fi

Not sure why systemd was not given this type of capability - I assume some important design decisions that I won't understand right now, but this means extra work for each and every 'script type systemd unit'.

2
  • +1. but you still need to quote your variables. and stop using that pointless $(which docker-compose). – cas May 6 at 14:33
  • 1
    I have done that in my final script early this morning, just didn't apply it on my answer yet. Thanks for +1, and really helpful advice! – CvRChameleon May 6 at 14:51

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.