Search code examples
phplaravelnginxdocker-composestatic-files

Can't setup static content on dockerized Nginx and Laravel


I setup my PHP Laravel app with docker-compose, I made few containers including nginx, configured it and everything works besides the content in folder public. I've tried to setup my nginx.conf in different ways but nothing helped so could you please help me with this?

That's my nginx.conf

events {}

http {
    server {
        listen 80 default_server;
        root /var/www/public;
        index index.html index.php;
    
        add_header X-Frame-Options "SAMEORIGIN";
        add_header X-Content-Type-Options "nosniff";
    
        charset utf-8;

        location / {
            try_files $uri /index.php?$query_string;
        }
    
        location ~* \.(js|css|png|jpg|jpeg|gif|ico|html|json|svg)$ {
            try_files $uri =404;
            expires max;
            add_header Pragma public;
            add_header Cache-Control "public, must-revalidate, proxy-revalidate";
        }
    
        location = /favicon.ico { access_log off; log_not_found off; }
        location = /robots.txt  { access_log off; log_not_found off; }
    
        error_page 404 /index.php;
    
        location ~ \.php$ {
            fastcgi_pass php:9000;
            fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
            include fastcgi_params;
        }
    
        location ~ /\.(?!well-known).* {
            deny all;
        }
    }
}

This is my docker-compose.yml

version: '3.8'

services:
  nginx:
    container_name: nginx
    image: nginx:alpine
    ports:
      - "80:80"
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf
    depends_on:
      - php
      
  php:
    build:
      context: .
      dockerfile: Dockerfile
    container_name: php
    image: php:8.2-fpm
    working_dir: /var/www
    volumes:
      - ./:/var/www
      - ./.env:/var/www/.env
    depends_on:
      db:
        condition: service_healthy

  db:
    platform: linux/x86_64
    container_name: db
    image: mysql:8.0
    restart: unless-stopped
    environment:
      - MYSQL_DATABASE='${DB_DATABASE}'
      - MYSQL_USER='${DB_USERNAME}'
      - MYSQL_PASSWORD='${DB_PASSWORD}'
      - MYSQL_ALLOW_EMPTY_PASSWORD=1
    volumes:
      - dbdata:/var/lib/mysql
    ports:
      - "3306:3306"
    healthcheck:
        test: ["CMD", "mysqladmin" ,"ping", "-h", "localhost"]
        timeout: 120s
        retries: 60

  node:
    platform: linux/x86_64
    build:
      context: .
      dockerfile: Dockerfile.node
    container_name: node
    image: node:20
    ports:
    - "3000:3000"
    working_dir: /var/www
    volumes:
      - ./:/var/www
      - /var/www/node_modules

volumes:
  dbdata:
    driver: local

And this one is my Dockerfile

# Set the base image for subsequent instructions
FROM php:8.2-fpm

USER root

# Install dependencies
RUN apt-get update && apt-get install -y \
    build-essential \
    libpng-dev \
    libonig-dev \
    libxml2-dev \
    zip \
    curl \
    unzip \
    git \
    libzip-dev \
    libfreetype6-dev \
    libjpeg62-turbo-dev \
    libpng-dev && \
    docker-php-ext-install mysqli pdo_mysql mbstring exif pcntl bcmath gd zip

# Clear cache
RUN apt-get clean && rm -rf /var/lib/apt/lists/*

# Install Composer
COPY --from=composer:latest /usr/bin/composer /usr/bin/composer

# Set working directory
WORKDIR /var/www

# Remove default server definition
RUN rm -rf /var/www/html

# Copy existing application directory contents
COPY . /var/www

# Copy existing application directory permissions
COPY --chown=www-data:www-data . /var/www

# Expose port 9000 and start php-fpm server
EXPOSE 9000

ENTRYPOINT ["sh", "./entrypoint-php.sh"]

CMD ["php-fpm"]

I've already searched a lot of websites seeking for solution and tried different nginx.conf options but nothing helped. Additionally: I have .env and variable APP_URL=localhost (as I host it locally). The files I try to approach have 404 result. I will appreciate any help, thank you


Solution

  • UPDATE

    I solved my problem by adding this volume to nginx service in docker-compose: - ./:/var/www

    Also changed my nginx.conf to this:

    events {}
    
    http {
        server {
            listen 80 default_server;
    
            server_name localhost;
            root /var/www/public;
    
            error_log /var/log/nginx/error.log;
            access_log /var/log/nginx/access.log;
            location = /favicon.ico { access_log off; log_not_found off; }
            location = /robots.txt  { access_log off; log_not_found off; }
    
            index index.html index.php;
    
            client_max_body_size 5M;
    
            location / {
                try_files $uri $uri /index.php$is_args$args;
            }
    
            location ~ ^/.+\.php(/|$) {
                fastcgi_split_path_info ^(.+?\.php)(/.*)$;
                if (!-f $document_root$fastcgi_script_name) {
                    return 404;
                }
                include fastcgi_params;
                fastcgi_pass php:9000;
                fastcgi_index index.php;
                fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
                fastcgi_param DOCUMENT_ROOT $realpath_root;
                fastcgi_param REALPATHTEST $realpath_root;
                internal;
            }
        }
    }