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.

  • 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 05 '21 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 05 '21 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 05 '21 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 05 '21 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 05 '21 at 13:33
  • Yes I noticed that the commands were different from my original. I assumed you meant ExecStartPost. – CvRChameleon May 05 '21 at 14:21

2 Answers2

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.

cas
  • 78,579
  • 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 05 '21 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 05 '21 at 14:25
  • That's what I will try. Thanks for your assistance and advice! – CvRChameleon May 05 '21 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 06 '21 at 08:46
  • No, your answer answered my question: It is not directly possible using only systemd itself, but a 'hacky way' using the script that gets called via ExecStartPost, and ExecStopPost. I thought just giving more information as to your answer (which is correctly answering my question) would be useful. Your answer will remain accepted! TLDR: other people looking for a what to do: let your script loop until some expected result is found in your loop or sleep before calling the actual status code (for me I needed to delay docker-compose ps) – CvRChameleon May 06 '21 at 08:54
  • 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 06 '21 at 09: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'.