CMD is not working properly

I have an issue with running CMD on my Dockerfile

I have this Dockerfile:

FROM php:8-fpm
RUN apt-get update && apt-get install -y \
        libfreetype6-dev \
        libjpeg62-turbo-dev \
        libmcrypt-dev \
        libicu-dev \
        libxml2-dev \
        vim \
        wget \
        unzip \
        git \
        libonig-dev \
    && docker-php-ext-install -j$(nproc) iconv intl xml soap opcache pdo pdo_mysql mysqli \
    && docker-php-ext-configure gd --with-jpeg=/usr/include/ --with-freetype=/usr/include/ \
    && docker-php-ext-install -j$(nproc) gd \
    && curl -sS | php -- --install-dir=/usr/local/bin --filename=composer
COPY . /var/www/html/
WORKDIR /var/www/html
RUN composer install \
        --no-interaction \
        --no-plugins \
        --no-scripts \
        --no-dev \
RUN composer dump-autoload
RUN chown -R www-data:www-data /var/www
RUN chmod -R 755 /var/www/html
RUN chmod -Rf 777 storage
RUN chmod -Rf 777 bootstrap
CMD bash -c "cron && php-fpm && env > .env"

In the last line I want to save environment variables to .env file for further usage
but it seem it doesn’t work
How can I achieve this goal I mean saving environment variables to .env file
Thanks in advance

You have to create the .env file during build or in an entrypoint or custom command. You just ran a bash command which starts when you start the container and it would exist immediately, but if cron or php-fpm runs in the foreground, the env command will never.

You can read about the entrypoint, cmd and shell instructions in my blogpost (planning a video, but I didn’t have time yet):

And if you want to know how you can run multiple daemons in a container, you can read my other tutorial on GitHub:

1 Like

Hi Rimelek,
thanks for you answer but I’m not sure I understand it
Could you please say what should be changed in my Dockerfile to create .env filed filled with output of env or printenv command I thinks there is also could be some permission issues but I can’t figure out what exactly

Because I don’t know exactly what your goal was, I can’t fix it for you.

It seems you want to run a cron job and PHP FPM in one container. This is not the way. The correct way is using an init porcess because in a container only one process can run and that process an run other processes. An init process on a physical machine or virtual machine is usually Systemd. Running Systemd in a Docker container is not a good idea, but supervisor can work similarly. This is not something I can show you in a single post that’s why I linked tutorials and I have just added a video to the blog post if you want to learn about the very basics of the CMD and the ENTRYPOINT instruction which could be used to create a .env file before running php-fpm in a custom CMD shell script.

After trying to start cron and php-fpm, you try to do something else, but that will never run. It can’t run because php-fpm is running in foreground (I checked and cron will run in the background so php-fpm can start).

If you try to run php-fpm in the background (don’t do it), the env command runs, creates the .env file and the bash script just stops because there is nothing in the foreground to keep the container alive so that will stop too.

If you want a quick “solution” which is still a bad idea but should work, this is it:

CMD bash -c "cron && env > .env && php-fpm"

However, I have no idea why you would save the already existing environment variables to a dotenv file. My guess is that the PHP interpreter can’t read the original environment variables but that behavior can be changed in the PHP configuration.

Note that if you just run commands the way you did, when you run docker stop containername you wil need to wait 10 seconds before the Docker will kill your container forfefully. Normally the stop signal would be sent to the main process in the container and that would handle the signal, finish every task and stop safely. If you just kill a container that could lead to data corruption, although the chance is smaller in case of a PHP container.

1 Like

Thank you very much!
I struggled with this for 3 days last week and now it works :slight_smile:
CMD bash -c “cron && env > .env && php-fpm”
It creates the .env file as needed !!

But now I think that better solution for cron would be to use another Alpine image with cron as a service and ping my web app by url on schedule from it’s container. In this case I don’t need to run two services in one container and I don’t need to store env variables to a file