10 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
10 months ago
e2d6c1c6-c741-45c3-b553-98603eaddb38
10 months ago
Hey, can you send your dockerfile?
10 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
10 months ago
can you try without switching back to the non root user?
10 months ago
Yes, trying…
10 months ago
Same problem.
10 months ago
Can i specify RAILWAYRUNUID=33 to make it the same uid as the image?
10 months ago
10 months ago
nope, the volume is mounted as root, you would need to chown the volume mount before starting your app
10 months ago
like what is done here -
10 months ago
The problem has been solved, I will share my solution.
10 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.
10 months ago
perfect, glad i could help!