8 months ago
I am using serversideup/php:8.3-unit
as docker image in my application. The home directory of my application is /var/www/html/
and I am mounting the volume to /var/www/html/storage/app/public
which is where the files that are uploaded to my application are stored.
I already set the environment variable RAILWAY_RUN_UID=0
but I have permission issues to write to the mounted volume.
The container is running as a non-privileged user www-data
but i still have the following error:
[2024-08-22 15:57:00] production.ERROR: file_put_contents(/var/www/html/storage/app/public/hello.txt): Failed to open stream: Permission denied {"userId":1,"exception":"[object] (ErrorException(code: 0): file_put_contents(/var/www/html/storage/app/public/storage/hello.txt): Failed to open stream: Permission denied at /var/www/html/vendor/laravel/framework/src/Illuminate/Filesystem/Filesystem.php:204)
This is the code that generates the error:
Route::get('/example', function () {
File::put('/var/www/html/storage/app/public/hello.txt', now()->toDateTimeString());
return File::get('/var/www/html/storage/app/public/hello.txt');
});
0 Replies
8 months ago
e2d6c1c6-c741-45c3-b553-98603eaddb38
8 months ago
Hey, can you send your dockerfile?
8 months ago
FROM serversideup/php:8.3-unit
USER root
# Install server dependencies
RUN apt-get update \
&& apt-get install -y ca-certificates gnupg \
&& mkdir -p /etc/apt/keyrings \
&& curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg \
&& echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_20.x nodistro main" | tee /etc/apt/sources.list.d/nodesource.list \
&& apt-get update \
&& apt-get install -y --no-install-recommends nodejs \
&& install-php-extensions intl \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* /usr/share/doc/*
# Install project dependencies
COPY package*.json composer.* ./
RUN composer install --no-dev --no-autoloader --no-scripts --no-interaction && npm ci
COPY . .
RUN composer dump --no-interaction && \
npm run build && \
rm -rf node_modules && \
# find /var/www/html -type d -not -path "./vendor/*" -not -path "./.git/*" -exec chmod 755 "{}" \; && \
# find /var/www/html -type f -not -path "./vendor/*" -not -path "./.git/*" -exec chmod 644 "{}" \; && \
chmod -R 777 /var/www/html/storage /var/www/html/bootstrap/cache && \
php /var/www/html/artisan filament:optimize
USER www-data
8 months ago
can you try without switching back to the non root user?
8 months ago
Yes, trying…
8 months ago
Same problem.
8 months ago
Can i specify RAILWAYRUNUID=33 to make it the same uid as the image?
8 months ago
8 months ago
nope, the volume is mounted as root, you would need to chown the volume mount before starting your app
8 months ago
like what is done here -
8 months ago
The problem has been solved, I will share my solution.
8 months ago
Because I'm using a docker image that by default runs as a non-privileged user www-data:www-data
or 33:33
, it's necessary to change the owner of the mounted volume after starting the container.
To achieve this, I added a script in /etc/entrypoint.d/99-starting-hook.sh
with the following content:
#!/bin/sh
# chown the mount to allow the www-data user read and write access.
chown -R 33:33 /var/www/html/storage/app/public && echo "✅ added permissions to mounted volume"
# optimize filament for production (optional).
php /var/www/html/artisan filament:optimize
This is my final Dockerfile:
FROM serversideup/php:8.3-unit
USER root
# Install server dependencies
RUN apt-get update \
&& apt-get install -y ca-certificates gnupg \
&& mkdir -p /etc/apt/keyrings \
&& curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg \
&& echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_20.x nodistro main" | tee /etc/apt/sources.list.d/nodesource.list \
&& apt-get update \
&& apt-get install -y --no-install-recommends nodejs \
&& install-php-extensions intl \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* /usr/share/doc/*
COPY --chmod=755 ./99-starting-hook.sh /etc/entrypoint.d/99-starting-hook.sh
USER www-data
COPY --chown=www-data:www-data . .
RUN composer install --no-dev --no-interaction && \
npm ci && \
npm run build && \
rm -rf node_modules/ && \
chmod -R 777 /var/www/html/storage /var/www/html/bootstrap/cache /var/www/html/public
There is no need to add the RAILWAY_RUN_UID=0
environment variable because the volume is already owned by the www-data
user.
If you are using serversideup/php:8.3-unit
you must add the following environment variable:
AUTORUN_ENABLED=true
This will run php artisan storage:link
after starting the container.
8 months ago
perfect, glad i could help!