I am trying to dockerize a PHP laravel app. I am using a PHP and a composer image to achieve this. However, when I run composer install, I get all my packages installed but then run into this error:
/app/vendor does not exist and could not be created.
I want composer to create the /vendor directory! Could this be a permission issue?
Here is my Dockerfile:
FROM php:7.4.3-cli
# Install system dependencies
RUN apt-get update && apt-get install -y \
git \
curl \
libpng-dev \
libonig-dev \
libxml2-dev \
zip \
unzip
# Clear cache
RUN apt-get clean && rm -rf /var/lib/apt/lists/*
# Install PHP extensions
RUN docker-php-ext-install pdo_mysql mbstring exif pcntl bcmath gd
COPY --from=composer:2.4.4 /usr/bin/composer /usr/local/bin/composer
# Set working directory
WORKDIR /app
COPY . .
# Add a new user "john" with user id 8877
RUN useradd -u 8877 john
# Change to non-root privilege
USER john
RUN composer install
I created a user with an arbitrary ID since it's a bad practice to run composer install as root security-wise.
CodePudding user response:
It looks like the issue is that the composer install command is running as the john user, but the vendor directory is owned by the root user. When the john user tries to write to the vendor directory, it doesn't have permission to do so because it is owned by a different user.
One possible solution is to create the vendor directory before running the composer install command, and to give the john user permission to write to it. You can do this by adding the following lines to your Dockerfile before running composer install:
# Create the vendor directory
RUN mkdir -p /app/vendor
# Give the john user permission to write to the vendor directory
RUN chown john:john /app/vendor
With these lines added to your Dockerfile, the vendor directory will be created and owned by the john user, so the composer install command should be able to write to it.
Another possible solution is to run the composer install command as the root user, but this is not recommended for security reasons. Instead, you can use the --no-plugins and --no-scripts flags when running composer install to prevent it from running any potentially insecure scripts or plugins. This way, you can still run the command as the john user without compromising security.
# Run composer install as the john user, without running any scripts or plugins
RUN composer install --no-plugins --no-scripts
CodePudding user response:
I was able to solve the problem by making some changes to my Dockerfile:
FROM php:7.4.3-cli
# Install system dependencies
RUN apt-get update && apt-get install -y \
git \
curl \
libpng-dev \
libonig-dev \
libxml2-dev \
zip \
unzip
# Clear cache
RUN apt-get clean && rm -rf /var/lib/apt/lists/*
# Install PHP extensions
RUN docker-php-ext-install pdo_mysql mbstring exif pcntl bcmath gd
COPY --from=composer:2.4.4 /usr/bin/composer /usr/local/bin/composer
# Add a new user "john" with user id 8877
RUN useradd -u 8877 john
# Set working directory
WORKDIR /app
COPY . .
RUN chmod -R 775 /app
RUN chown -R john:john /app
# Change to non-root privilege
USER john
RUN composer install --no-scripts --no-plugins