Docker is pretty new to me, so I’m not really sure what I’m doing wrong.
I’ve tried multiple approaches, which I’ll include below. I’ll give you the docker-compose and dockerfile first:
# docker-compose.yml
version: '3.7'
services:
app:
build:
context: .
dockerfile: Dockerfile
image: php:8.2-fpm
container_name: laravel_app
working_dir: /var/www
volumes:
- /volume1/web:/var/www
- laravel_app:/var/www
- laravel_vendor:/var/www/vendor
- laravel_node_modules:/var/www/node_modules
ports:
- "9000:9000" # Exposes PHP-FPM to be used by Nginx
entrypoint: /bin/sh -c "
cp .env.production .env &&
chmod -R 775 /var/www/storage /var/www/bootstrap/cache &&
chown -R www-data:www-data /var/www &&
chmod +x /var/www/clear_allcache.sh &&
/var/www/clear_allcache.sh &&
php artisan key:generate &&
php-fpm"
# entrypoint: /bin/sh -c "chmod +x /var/www/clear_allcache.sh && /var/www/clear_allcache.sh && php-fpm"
webserver:
image: nginx:alpine
container_name: laravel_nginx
working_dir: /var/www
volumes:
- laravel_app:/var/www
- laravel_vendor:/var/www/vendor
- laravel_node_modules:/var/www/node_modules
- /volume1/web/plaves/nginx.conf:/etc/nginx/conf.d/default.conf
- /volume1/web/plaves/syno_ddns_cert:/etc/nginx/certs:ro
ports:
- "5443:443" # Exposes port 443 on your NAS through port 5443
depends_on:
- app
volumes:
laravel_app:
laravel_vendor:
laravel_node_modules:
And the dockerfile:
# Stage 1: Build environment
FROM composer:2.5 AS build
# Set working directory
WORKDIR /var/www
COPY composer.json composer.json
COPY composer.lock composer.lock
COPY . .
# Install PHP dependencies
RUN composer install --no-dev --optimize-autoloader
# Stage 2: Build environment for Node.js dependencies
FROM node:22.11 AS node-build
# Set working directory
WORKDIR /var/www
# Copy package.json and package-lock.json
COPY package.json package-lock.json ./
# Install npm dependencies
RUN npm install
# Copy application files from the build stage
COPY --from=build /var/www /var/www
# Install npm dependencies and build assets
RUN npm run build
# Use the base PHP 8.2 FPM image
FROM php:8.2-fpm As php-fpm-build
# Set working directory
WORKDIR /var/www
# Install system dependencies and PHP extensions for Laravel
RUN apt-get update && apt-get install -y
git
unzip
libpng-dev
libjpeg62-turbo-dev
libfreetype6-dev
libonig-dev
libxml2-dev
zip
libcurl4-openssl-dev
# Configure and install GD extension
&& docker-php-ext-configure gd --with-freetype --with-jpeg
# Install additional PHP extensions
&& docker-php-ext-install -j$(nproc)
gd
bcmath
exif
pcntl
&& apt-get clean && rm -rf /var/lib/apt/lists/*
# Copy application files from the build stage
COPY --from=node-build /var/www /var/www
# Remove /public/hot if it exists
RUN rm -rf /var/www/public/hot
# Copy and configure environment variables
COPY .env.production /var/www/.env
# Set permissions for storage and bootstrap/cache
RUN chmod -R 775 storage bootstrap/cache
&& chown -R www-data:www-data /var/www
# Make the script executable
RUN chmod +x clear_allcache.sh
&& sed -i 's/r$//' clear_allcache.sh
The clear_allcache.sh file just rebuilds all caches:
#!/bin/bash
php artisan config:clear
php artisan config:cache
php artisan event:clear
php artisan event:cache
php artisan route:clear
php artisan route:cache
php artisan view:clear
php artisan view:cache
# Set permissions for storage and bootstrap/cache
chmod -R 775 storage bootstrap/cache
chown -R www-data:www-data storage bootstrap/cache
From what I understand, split-build stages are subcontainers that don’t share changes apart from the mounted volume. So I copy each folder (vendor, node-modules) from build stage to build stage.
I know this works, because I managed to get the site up and running. But it had it’s issues, like not being able to do post requests.
This is where I’m at now:
The issue must be my mounting logic. I tried mounting /volume1/web directly to /var/www, but that might not work because not all changes are transferred to both containers, right?
So know I’m using shared mounts to make sure all changes are visible to both containers.
I’ve tried playing with this, but it always results in a 404 – file not found or a 403 – forbidden when I run the containers and visit the site.
Any suggestion is appreciated, even if that means throwing my progress in the bin 🙂
The build succeeds, and I can sh into both containers to verify the files are all there.
From laravel_nginx:
d--------- 1 33 33 238 Dec 8 14:54 public
d--------- 1 33 33 20 Dec 8 14:54 resources
d--------- 1 33 33 90 Dec 8 14:54 routes
---------- 1 33 33 329 Nov 26 21:23 set_permissions.sh
drwxrwxr-x 1 33 33 32 Dec 8 14:54 storage
drwxr-xr-x 1 33 33 476 Dec 1 17:38 vendor
And from laravel_app:
d--------- 1 www-data www-data 238 Dec 8 14:54 public
d--------- 1 www-data www-data 20 Dec 8 14:54 resources
d--------- 1 www-data www-data 90 Dec 8 14:54 routes
---------- 1 www-data www-data 329 Nov 26 21:23 set_permissions.sh
drwxrwxr-x 1 www-data www-data 32 Dec 8 14:54 storage
drwxr-xr-x 1 www-data www-data 476 Dec 1 17:38 vendor
bootstrap/cache:
drwxrwxr-x 1 33 33 134 Dec 8 15:10 cache
drwxrwxr-x 1 www-data www-data 134 Dec 8 15:10 cache
In case you want to look into it, here’s the build output from docker:
$ sudo docker-compose down; sudo docker-compose up -d --build
[+] Running 3/3
⠿ Container laravel_nginx Removed 2.5s
⠿ Container laravel_app Removed 15.7s
⠿ Network plaves_default Removed 0.9s
[+] Building 739.7s (27/27) FINISHED
=> [internal] load build definition from Dockerfile 1.3s
=> => transferring dockerfile: 29B 0.0s
=> [internal] load .dockerignore 1.8s
=> => transferring context: 32B 0.0s
=> [internal] load metadata for docker.io/library/php:8.2-fpm 0.0s
=> [internal] load metadata for docker.io/library/composer:2.5 3.0s
=> [internal] load metadata for docker.io/library/node:22.11 4.3s
=> [internal] load build context 3.1s
=> => transferring context: 151.41kB 0.9s
=> [build 1/6] FROM docker.io/library/composer:2.5@sha256:71e5a2761bee175e0ef866ebcaab2dbd4e460ca6da4e0a84fa11ca 0.0s
=> [php-fpm-build 1/8] FROM docker.io/library/php:8.2-fpm 135.4s
=> [node-build 1/6] FROM docker.io/library/node:22.11@sha256:ec878c763e9fad09d22aae86e2edcb7a05b397dfe8411c16e 144.1s
=> => resolve docker.io/library/node:22.11@sha256:ec878c763e9fad09d22aae86e2edcb7a05b397dfe8411c16e2b90158d595e2 1.7s
=> => sha256:ec878c763e9fad09d22aae86e2edcb7a05b397dfe8411c16e2b90158d595e2ce 6.41kB / 6.41kB 0.0s
=> => sha256:748cfe6211ab7422bd4a6597e93e45355e8e6baf5d4707887843522a0c6ea860 2.49kB / 2.49kB 0.0s
=> => sha256:4424cf09130c419aafde9798c3ac35e0a906a2b173c482319e2bac9c0ca42b90 6.39kB / 6.39kB 0.0s
=> => sha256:fdf894e782a221820acf469d425b802be26aedb5e5d26ea80a650ff6a974d488 48.50MB / 48.50MB 30.4s
=> => sha256:551df7f94f9c131f2fec0e8063142411365f0a1c88b935b9fac22be91af227e0 64.39MB / 64.39MB 34.8s
=> => sha256:5bd71677db44bb63b94de61b6f1f95d5540b4ba2d6a8a6bc4d19f422b25e0c2b 23.87MB / 23.87MB 6.1s
=> => sha256:ce82e98d553dd62ca6a12bebfe83992ae9f9ae2748275e74b66a68cc094f868b 211.31MB / 211.31MB 42.8s
=> => extracting sha256:fdf894e782a221820acf469d425b802be26aedb5e5d26ea80a650ff6a974d488 6.0s
=> => sha256:cd8cd1fac358b1e715594bbe9128429f444efb4453c30d706bc11b8332a74ebf 3.32kB / 3.32kB 33.1s
=> => sha256:a626dd299f99240da9e4e632a1fca3035e0ca04c632cc624968306bd18fb771d 54.61MB / 54.61MB 44.4s
=> => sha256:480cf7800ccb638f7049ba8b450e5dafccb825d97380e5863a11d661a766399b 1.25MB / 1.25MB 36.6s
=> => sha256:6f76c9e452df20903e7da8bc4b270f474d3ef02555846fbd66d5ae21e4b2cf47 447B / 447B 37.7s
=> => extracting sha256:5bd71677db44bb63b94de61b6f1f95d5540b4ba2d6a8a6bc4d19f422b25e0c2b 2.0s
=> => extracting sha256:551df7f94f9c131f2fec0e8063142411365f0a1c88b935b9fac22be91af227e0 7.7s
=> => extracting sha256:ce82e98d553dd62ca6a12bebfe83992ae9f9ae2748275e74b66a68cc094f868b 23.3s
=> => extracting sha256:cd8cd1fac358b1e715594bbe9128429f444efb4453c30d706bc11b8332a74ebf 3.2s
=> => extracting sha256:a626dd299f99240da9e4e632a1fca3035e0ca04c632cc624968306bd18fb771d 7.5s
=> => extracting sha256:480cf7800ccb638f7049ba8b450e5dafccb825d97380e5863a11d661a766399b 3.9s
=> => extracting sha256:6f76c9e452df20903e7da8bc4b270f474d3ef02555846fbd66d5ae21e4b2cf47 0.6s
=> CACHED [build 2/6] WORKDIR /var/www 0.0s
=> CACHED [build 3/6] COPY composer.json composer.json 0.0s
=> CACHED [build 4/6] COPY composer.lock composer.lock 0.3s
=> [build 5/6] COPY . . 8.8s
=> [build 6/6] RUN composer install --no-dev --optimize-autoloader 21.9s
=> [php-fpm-build 2/8] WORKDIR /var/www 4.3s
=> [php-fpm-build 3/8] RUN apt-get update && apt-get install -y git unzip libpng-dev 84.4s
=> [node-build 2/6] WORKDIR /var/www 5.9s
=> [node-build 3/6] COPY package.json package-lock.json ./ 3.0s
=> [node-build 4/6] RUN npm install 416.7s
=> [node-build 5/6] COPY --from=build /var/www /var/www 7.4s
=> [node-build 6/6] RUN npm run build 20.2s
=> [php-fpm-build 4/8] COPY --from=node-build /var/www /var/www 11.1s
=> [php-fpm-build 5/8] RUN rm -rf /var/www/public/hot 7.4s
=> [php-fpm-build 6/8] COPY .env.production /var/www/.env 3.2s
=> [php-fpm-build 7/8] RUN chmod -R 775 storage bootstrap/cache && chown -R www-data:www-data /var/www 5.8s
=> [php-fpm-build 8/8] RUN chmod +x clear_allcache.sh && sed -i 's/r$//' clear_allcache.sh 7.8s
=> exporting to image 69.4s
=> => exporting layers 34.1s
=> => writing image sha256:6a2203ce3493eeff1633120c29fec62415f6f2882dcb4576c5fb97e4b86d09dd 0.1s
=> => naming to docker.io/library/php:8.2-fpm 0.1s
[+] Running 3/3
⠿ Network plaves_default Created 1.3s
⠿ Container laravel_app Started 8.6s
⠿ Container laravel_nginx Started 10.8s