Cronjobs that require env variables fail to execute

Hello Fly Team, (Awesome work on the product btw, love it!)

Im using the most recent template from flyctl for laravel and I noticed that my cronjobs that require connection to the database are missing the env variables.

Tried to ssh into the cron vm and clear config cache because maybe it was from it but it did not work.

What worked was to put on the entrypoint.sh the config:cache line inside the “if [ $# -gt 0 ];then”.

I don’t know if there is a better way or if the default template is missing something to have the env variables inside the cronjob that’s why I decided to leave a message.

Hi!

Can you can share your Dockerfile? I saw that issue before but thought it was resolved - but perhaps not!

Edit: i see you said the latest actually, gotcha. I’ll see if I can replicate that.

How did you notice that? Did you create an app process for cron specifically and check the logs?

Hey Chris,

I prepared a little demo so that you can replicate the issue, maybe its easier for you to test it out and iterate over it.

On the commits I broke it down into 3:

  • Laravel Installation
  • Results after the “fly launch” was ran
  • The minimum changes I did to the project to read the env from schedule

To test then the output of the command I just did “fly console ssh” (into the cron vm) and did “tail -f /var/www/html/cron.log” and the default value of “env(‘APP_KEY’, ‘Cannot read APP_KEY’)” got printed.

I hope this is of any help

2 Likes

Thanks, I’ll check it out! Hopefully our timezone difference doesn’t make this too grim :smiley:

Don’t worry, Im trying some things on my side too, but there is no business critical problem for me since I have this workaround with config:cache on entrypoint.

The goal is that we maybe can improve the flyctl default template for the next one.

Again thank you so much for the help!

OK that sounds like:

  1. The way cron -f is being run in the container cannot pick up environment variables
  2. But config:cache being run in ENTRYPOINT makes it work because environment variables ARE accessible at that point, and laravel is able to grab the values and save them to a file

If you have the setup in front of you, can you test that? You can have your scheduled command echo out an environment variables that laravel’s config wouldn’t read in and save anything, like env('FLY_REGION')

Yeah exactly, with that example of env() not even the config:cache works. It just did in my case because i was missing the database env variables that are used in laravel config. Therefore caching them did the trick for me.

Do you have an idea how we can solve this issue so that the process in cron -f can read env variables?

Okay - I looked into this a bit.

Running cron -f is intentionally ignoring env vars - that’s a function of the cron daemon (not part of the Docker / Fly VM config).

There isn’t really a great solution:

  1. I’m working on a PR to the templates that generate Fly stuff for Laravel, and it’ll include away to run scripts before running commands like cron -f so you can essentially get your change to run config:cache from ENTRYPOINT
  2. We still need a way to get cron -f to read other env vars that Laravel would not cache itself.

So, a few options on how to proceed:

  1. Have Laravel cache config values by adding extra/needed env vars as config values in config/whatever-you-want.php
  2. Append specific env vars / and their values to /etc/environment via ENTRYPOINT (cron -f will read env vars set in there). That idea came from here, altho wholesale appending env >> /etc/environment is dangerous-ish
  3. Adjust the cron setting set in Dockerfile to be something like:
# Snippet from the Dockerfile the fly command generates
echo "MAILTO=\"\"\n* * * * * webuser FOO=barvalue /usr/bin/php /var/www/html/artisan schedule:run" > /etc/cron.d/laravel \

(I like option 2 the best I think, but getting values into Laravel and doing the config:cache thing might be the nicest in terms of being consistent - depending on your needs).