Laravel apps not recognizing php during deploy

Laravel apps when deployed doesn’t recognize php. I’ve noticed that this happened recently because even apps that deployed with no errors are now not deploying. I am using github actions and here is a sample of logs:

#8 4.863 OK: 152 MiB in 124 packages

#8 4.905 /bin/sh: php: not found

#8 5.214 curl: (23) Failure writing output to destination

ERROR: executor failed running [/bin/sh -c apk update && apk add curl zip unzip tzdata supervisor nginx htop vim ca-certificates rsync php8 php8-cli php8-pecl-mcrypt php8-soap php8-openssl php8-gmp php8-pdo_odbc php8-json php8-dom php8-pdo php8-zip php8-pdo_mysql php8-sqlite3 php8-pdo_pgsql php8-bcmath php8-gd php8-odbc php8-pdo_sqlite php8-gettext php8-xmlreader php8-bz2 php8-iconv php8-pdo_dblib php8-curl php8-ctype php8-phar php8-xml php8-common php8-mbstring php8-tokenizer php8-xmlwriter php8-fileinfo php8-opcache php8-simplexml php8-pecl-redis php8-sockets php8-pcntl php8-posix php8-pecl-swoole php8-fpm && cp /etc/nginx/nginx.conf /etc/nginx/nginx.old.conf && rm -rf /etc/nginx/http.d/default.conf && curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer && adduser -D -u 1000 -g 'app' app && addgroup nginx app && mkdir -p /var/run/php && chown -R app:app /var/run/php && mkdir -p /var/www/html]: exit code: 127

Hi!

Is this happening to you locally as well? Or just in gha?

Can you share your Dockerfile?

Based on the error it looks to be doing something weird like installing php successfully but then not finding the php command when installing composer :thinking:

I can’t test it locally since i don’t have docker installed on my system at the moment. Dockerfile is the one fly generates for you after running flyctl launch

# syntax = docker/dockerfile:experimental
FROM alpine:edge as base

LABEL fly_launch_runtime="laravel"

RUN apk update \
    && apk add curl zip unzip tzdata supervisor nginx htop vim ca-certificates rsync \
           php8           php8-cli        php8-pecl-mcrypt \
           php8-soap      php8-openssl    php8-gmp \
           php8-pdo_odbc  php8-json       php8-dom \
           php8-pdo       php8-zip        php8-pdo_mysql \
           php8-sqlite3   php8-pdo_pgsql  php8-bcmath \
           php8-gd        php8-odbc       php8-pdo_sqlite \
           php8-gettext   php8-xmlreader  php8-bz2 \
           php8-iconv     php8-pdo_dblib  php8-curl \
           php8-ctype     php8-phar       php8-xml \
           php8-common    php8-mbstring   php8-tokenizer \
           php8-xmlwriter php8-fileinfo   php8-opcache \
           php8-simplexml php8-pecl-redis php8-sockets \
           php8-pcntl     php8-posix      php8-pecl-swoole \
           php8-fpm \
    && cp /etc/nginx/nginx.conf /etc/nginx/nginx.old.conf \
    && rm -rf /etc/nginx/http.d/default.conf \
    && curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer \
    && adduser -D -u 1000 -g 'app' app \
    && addgroup nginx app \
    && mkdir -p /var/run/php \
    && chown -R app:app /var/run/php \
    && mkdir -p /var/www/html

WORKDIR /var/www/html
# copy application code, skipping files based on .dockerignore
COPY . /var/www/html

# Install dependencies, configure server
# For the time being, we run "composer update" as best effort to get php 8.0 working
RUN composer update \
    && composer install --optimize-autoloader --no-dev \
    && mkdir -p storage/logs \
    && chown -R app:app /var/www/html \
    && /usr/bin/crontab docker/crontab \
    && mv docker/supervisor.conf /etc/supervisord.conf \
    && mv docker/nginx.conf /etc/nginx/nginx.conf \
    && mv docker/server.conf /etc/nginx/server.conf \
    && mv docker/php.ini /etc/php8/conf.d/php.ini \
    && sed -i 's/protected \$proxies/protected \$proxies = "*"/g' app/Http/Middleware/TrustProxies.php

# If we're not using Octane, configure php-fpm
RUN if ! grep -Fq "laravel/octane" /var/www/html/composer.json; then \
        rm -rf /etc/php8/php-fpm.conf; \
        rm -rf /etc/php8/php-fpm.d/www.conf; \
        mv docker/php-fpm.conf /etc/php8/php-fpm.conf; \
        mv docker/app.conf /etc/php8/php-fpm.d/app.conf; \
    elif grep -Fq "spiral/roadrunner" /var/www/html/composer.json; then \
        if [ -f ./vendor/bin/rr ]; then ./vendor/bin/rr get-binary; fi; \
        rm -f .rr.yaml; \
    fi

# clear Laravel cache that may be left over
RUN composer dump-autoload \
    && php artisan optimize:clear \
    && chmod -R ug+w /var/www/html/storage \
    && chmod -R 755 /var/www/html

# Multi-stage build: Build static assets
FROM node:14 as node_modules_go_brrr

RUN mkdir /app

RUN mkdir -p  /app
WORKDIR /app
COPY . .
RUN if [ -f "yarn.lock" ]; then \
        yarn install; \
    elif [ -f "package-lock.json" ]; then \
        npm ci --no-audit; \
    else \
        npm install; \
    fi

# Create final container, adding in static assets
FROM base

COPY --from=node_modules_go_brrr /app/public /var/www/html/public-npm
RUN rsync -ar /var/www/html/public-npm/ /var/www/html/public/ \
    && rm -rf /var/www/html/public-npm

# The same port nginx.conf is set to listen on and fly.toml references (standard is 8080)
EXPOSE 8080

ENTRYPOINT ["/var/www/html/docker/run.sh"]

thanks! i’ll check it soon on my end to see if I can replicate it.

when you deploy locally (if fly is installed) you can use the “—remote-only” flag and it will use a remote docker instance setup within fly.

Thanks let me try that

I get the same error locally, lame (errr, well - good. That means debugging won’t suck).

It looks like Alpine stopped creating a symlink for /usr/bin/php8 -> /usr/bin/php, so the “php” command alone doesn’t work.

The quick fix is to add the symlink yourself:

copy-pastable format:

RUN apk update \
    && apk add curl zip unzip tzdata supervisor nginx htop vim ca-certificates rsync \
           php8           php8-cli        php8-pecl-mcrypt \
           php8-soap      php8-openssl    php8-gmp \
           php8-pdo_odbc  php8-json       php8-dom \
           php8-pdo       php8-zip        php8-pdo_mysql \
           php8-sqlite3   php8-pdo_pgsql  php8-bcmath \
           php8-gd        php8-odbc       php8-pdo_sqlite \
           php8-gettext   php8-xmlreader  php8-bz2 \
           php8-iconv     php8-pdo_dblib  php8-curl \
           php8-ctype     php8-phar       php8-xml \
           php8-common    php8-mbstring   php8-tokenizer \
           php8-xmlwriter php8-fileinfo   php8-opcache \
           php8-simplexml php8-pecl-redis php8-sockets \
           php8-pcntl     php8-posix      php8-pecl-swoole \
           php8-fpm \
    && ln -sf /usr/bin/php8 /usr/bin/php \
    && cp /etc/nginx/nginx.conf /etc/nginx/nginx.old.conf \
    && rm -rf /etc/nginx/http.d/default.conf \
    && curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer \
    && adduser -D -u 1000 -g 'app' app \
    && addgroup nginx app \
    && mkdir -p /var/run/php \
    && chown -R app:app /var/run/php \
    && mkdir -p /var/www/html

I’ll update the fly launch command to do that correctly.

Thanks for letting us know, sorry for the trouble!

2 Likes