1

I've been struggling to find a good working Docker container to start working on Magento 2 under Windows 10.

I created my own based on this tutorial:https://tech.osteel.me/posts/docker-for-local-web-development-part-1-a-basic-lemp-stack#nginx

This is not for using it on production environment or anything, just for playing around with Magento 2.

I'm having an issue with Nginx throwing 404 for /src/pub/static files. Maybe something is wrong with my Nginx config?

Magento 2 version 2.3.5-p1

Access logs show this:

[error] 6#6: *11 open() "/var/www/php/pub/static/version1592198150/frontend/Magento/luma/en_CA/Magento_Theme/favicon.ico" failed (2: No such file or directory), client: 172.20.0.1, server: magento.test

Here is my folder structure:

/
/.docker
/.docker/mysql
/.docker/mysql/my.cnf
/.docker/nginx/conf.d/php.conf
/.docker/nginx/conf.d/phpmyadmin.conf
/.docker/php/Dockerfile
/src      
/.env
/docker-compose.yml
/php.env

Here are my files:

docker-compose.yml

version: "3.7"

# Services
services:
  # Nginx Service
  nginx:
    image: nginx:1.17
    container_name: nginx
    #restart: always
    ports:
      - 80:80
    volumes:
      - ./src:/var/www/php:ro
      - ./.docker/nginx/conf.d:/etc/nginx/conf.d:ro
      - phpmyadmindata:/usr/src/phpmyadmin
    depends_on:
      - php
      - phpmyadmin
    networks:
      - app-network

  # PHP Service
  php:
    build: ./.docker/php
    container_name: php
    #restart: always
    working_dir: /var/www/php
    environment:
      - COMPOSER_MEMORY_LIMIT=-1
    volumes:
      - ./src:/var/www/php
    links:
      - mysql
      - redis
    depends_on:
      - mysql
    networks:
      - app-network

  # MySQL Service
  mysql:
    image: mariadb:10
    container_name: mysql
    #restart: always
    environment:
      MYSQL_ROOT_PASSWORD: root
      MYSQL_DATABASE: magento
    volumes:
      - ./.docker/mysql/my.cnf:/etc/mysql/conf.d/my.cnf:ro
      - mysqldata:/var/lib/mysql
    ports:
      - "3306:3306"
    networks:
      - app-network

  # PhpMyAdmin Service
  phpmyadmin:
    image: phpmyadmin/phpmyadmin:5-fpm
    container_name: phpmyadmin
    #restart: always
    environment:
      PMA_HOST: mysql
    volumes:
      - phpmyadmindata:/usr/src/phpmyadmin
    links:
      - mysql:db
    depends_on:
      - mysql
    networks:
      - app-network

  redis:
    image: redis:latest
    #restart: always
    container_name: redis
    restart: always
    volumes:
      - redis-data:/data
    networks:
      - app-network

# Volumes
volumes:
  mysqldata:

  phpmyadmindata:

  redis-data:
    external: false

#Docker Networks
networks:
  app-network:
    driver: bridge

php.conf

error_log  /var/log/nginx/error.log debug;

upstream fastcgi_backend {  
     server 127.0.0.1:9000;
}

server {
    listen      80;
    listen      [::]:80;
    server_name magento.test;

    set $MAGE_ROOT /var/www/php;

    root $MAGE_ROOT;
    index index.php index.html index.htm;

    autoindex off;
    charset UTF-8;
    error_page 404 403 = /errors/404.php;
    #add_header "X-UA-Compatible" "IE=Edge";
    add_header 'X-Content-Type-Options' 'nosniff';    

    # Deny access to sensitive files
    location /.user.ini {
        deny all;
    }



    # PHP entry point for setup application
    location ~* ^/setup($|/) {
        root /var/www/php;
        location ~ ^/setup/index.php {
            fastcgi_pass   php:9000;

            fastcgi_param  PHP_FLAG  "session.auto_start=off \n suhosin.session.cryptua=off";
            fastcgi_param  PHP_VALUE "memory_limit=4000M \n max_execution_time=600";
            fastcgi_read_timeout 600s;
            fastcgi_connect_timeout 600s;

            fastcgi_index  index.php;
            fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
            include        fastcgi_params;
        }

        location ~ ^/setup/(?!pub/). {
            deny all;
        }

        location ~ ^/setup/pub/ {
            add_header X-Frame-Options "SAMEORIGIN";
        }
    }

    # PHP entry point for update application
    location ~* ^/update($|/) {
        root /var/www/php;

        location ~ ^/update/index.php {
            fastcgi_split_path_info ^(/update/index.php)(/.+)$;
            fastcgi_pass   php:9000;
            fastcgi_index  index.php;
            fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
            fastcgi_param  PATH_INFO        $fastcgi_path_info;
            include        fastcgi_params;
        }

        # Deny everything but index.php
        location ~ ^/update/(?!pub/). {
            deny all;
        }

        location ~ ^/update/pub/ {
            add_header X-Frame-Options "SAMEORIGIN";
        }
    }

    location / {
        try_files $uri $uri/ /index.php$is_args$args;
    }

    location /pub/ {
        location ~ ^/pub/media/(downloadable|customer|import|custom_options|theme_customization/.*\.xml) {
            deny all;
        }
        alias /var/www/php/pub/;
        add_header X-Frame-Options "SAMEORIGIN";
    }

    location /static/ {
        # Uncomment the following line in production mode
        # expires max;

        # Remove signature of the static files that is used to overcome the browser cache
        location ~ ^/static/version {
            rewrite ^/static/(version\d*/)?(.*)$ /static/$2 last;
        }

        location ~* \.(ico|jpg|jpeg|png|gif|svg|js|css|swf|eot|ttf|otf|woff|woff2|html|json)$ {
            add_header Cache-Control "public";
            add_header X-Frame-Options "SAMEORIGIN";
            expires +1y;

            if (!-f $request_filename) {
                rewrite ^/static/(version\d*/)?(.*)$ /static.php?resource=$2 last;
            }
        }
        location ~* \.(zip|gz|gzip|bz2|csv|xml)$ {
            add_header Cache-Control "no-store";
            add_header X-Frame-Options "SAMEORIGIN";
            expires    off;

            if (!-f $request_filename) {
            rewrite ^/static/(version\d*/)?(.*)$ /static.php?resource=$2 last;
            }
        }
        if (!-f $request_filename) {
            rewrite ^/static/(version\d*/)?(.*)$ /static.php?resource=$2 last;
        }
        add_header X-Frame-Options "SAMEORIGIN";
    }

    location /media/ {
        try_files $uri $uri/ /get.php$is_args$args;

        location ~ ^/media/theme_customization/.*\.xml {
            deny all;
        }

        location ~* \.(ico|jpg|jpeg|png|gif|svg|js|css|swf|eot|ttf|otf|woff|woff2)$ {
            add_header Cache-Control "public";
            add_header X-Frame-Options "SAMEORIGIN";
            expires +1y;
            try_files $uri $uri/ /get.php$is_args$args;
        }
        location ~* \.(zip|gz|gzip|bz2|csv|xml)$ {
            add_header Cache-Control "no-store";
            add_header X-Frame-Options "SAMEORIGIN";
            expires    off;
            try_files $uri $uri/ /get.php$is_args$args;
        }
        add_header X-Frame-Options "SAMEORIGIN";
    }

    location /media/customer/ {
        deny all;
    }

    location /media/downloadable/ {
        deny all;
    }

    location /media/import/ {
        deny all;
    }

    location /media/custom_options/ {
        deny all;
    }

    location /errors/ {
        location ~* \.xml$ {
            deny all;
        }
    }

    # PHP entry point for main application
    location ~ ^/(index|get|static|errors/report|errors/404|errors/503|health_check)\.php$ {
        try_files $uri =404;
        fastcgi_pass   php:9000;
        fastcgi_buffers 1024 4k;

        fastcgi_param  PHP_FLAG  "session.auto_start=off \n suhosin.session.cryptua=off";
        fastcgi_param  PHP_VALUE "memory_limit=4000M \n max_execution_time=18000";
        fastcgi_read_timeout 600s;
        fastcgi_connect_timeout 600s;

        fastcgi_index  index.php;
        fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
        include        fastcgi_params;
    }

    gzip on;
    gzip_disable "msie6";

    gzip_comp_level 6;
    gzip_min_length 1100;
    gzip_buffers 16 8k;
    gzip_proxied any;
    gzip_types
        text/plain
        text/css
        text/js
        text/xml
        text/javascript
        application/javascript
        application/x-javascript
        application/json
        application/xml
        application/xml+rss
        image/svg+xml;
    gzip_vary on;

    # Banned locations (only reached if the earlier PHP entry point regexes don't match)
    location ~* (\.php$|\.phtml$|\.htaccess$|\.git) {
        deny all;
    }
}

php.env

PHP_MEMORY_LIMIT=4000M
PHP_ENABLE_XDEBUG=false
UPDATE_UID_GID=true
DEBUG=false
ENABLE_SENDMAIL=true
UPLOAD_MAX_FILESIZE=64M
PHP_DISPLAY_ERRORS=1
PHP_MAX_EXECUTION_TIME=300
PHP_POST_MAX_SIZE=500M
PHP_UPLOAD_MAX_FILESIZE=1024M

Dockerfile

FROM php:7.2-fpm

# Install dependencies
RUN apt-get update \
    && apt-get install -y \
    libfreetype6-dev \ 
    libicu-dev \ 
    libjpeg62-turbo-dev \ 
    libmcrypt-dev \
    git \
    libpng-dev \ 
    libxslt1-dev \ 
    #sendmail-bin \ 
    #    sendmail \ 
    sudo

# Configure the gd library
RUN docker-php-ext-configure \
    gd --with-freetype-dir=/usr/include/ --with-jpeg-dir=/usr/include/

# Install required PHP extensions

RUN docker-php-ext-install \
    dom \ 
    gd \ 
    intl \ 
    mbstring \ 
    pdo_mysql \ 
    xsl \ 
    zip \ 
    soap \ 
    bcmath \ 
    pcntl \ 
    sockets

# Install Xdebug (but don't enable)
RUN pecl install -o -f xdebug

ENV PHP_MEMORY_LIMIT 6G
ENV PHP_ENABLE_XDEBUG false
ENV COMPOSER_MEMORY_LIMIT=-1
#ENV MAGENTO_ROOT /var/www/magento

ENV DEBUG false
ENV UPDATE_UID_GID false

# Install Composer
#RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer

phpmyadmin.conf

server {
    listen      80;
    listen      [::]:80;
    server_name phpmyadmin.test;
    root        /usr/src/phpmyadmin;
    index       index.php;

    location ~* \.php$ {
        fastcgi_pass   phpmyadmin:9000;
        include        fastcgi_params;
        fastcgi_param  SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param  SCRIPT_NAME     $fastcgi_script_name;
    }
}

When you launch the containers and access http://magento.test setup guide shows up with no issues, goes through all the steps and installs Magento 2.

Once you land on the page, it shows 404 for all the assets in /pub/static.

Magento 2 Nginx 404

I have refreshed cache, I have deleted and regenerated static assets, nothing helped.

I assume this is some kind of misconfig of Nginx or file permission issue?

1

It can be any reason first check following points and try below things.

  1. In app/etc/di.xml, find the virtualType name=”developerMaterialization” section and its item called name=”view_preprocessed”. Modify or delete it depending on your needs. To change the content of the item replace Symlink with Copy in Magento\Framework\App\View\Asset\MaterializationStrategy\Symlink.
  2. To get rid of any existing symlinks, you need to delete the files. Go to pub/static and cleanse it but be careful: the .htaccess file is situated there as well – don’t delete it!
  3. Check if .htaccess exist or not in pub/static folder ?
  4. Stores>Configuration>Advanced>Developer>Sign Static Files(Yes->No) Or Access the database and execute the command: insert core_config_data (config_id, scope, scope_id, path, value) values (null, 'default', 0, 'dev/static/sign', 0);

Apply above things and if not works let us know we will find other options.

| improve this answer | |
  • this is an NGINX setup - it doesnt read .htaccess files. I'll look into your other suggestions. Thanks – Kalvin Klien Jun 15 at 6:46
  • have you been successful running Magento 2 on Windows? Is this always a big headache with file regeneration and so on? Should I just switch to Linux as base OS? – Kalvin Klien Jul 21 at 20:31
  • 1
    yes magento 2 prefereable os is always linux as base OS ..you can use ubuntu – ParulThakkar Jul 22 at 8:48
0

Ok I think I figured it out:

I saw this on Github Magento 2 bug / issue forum:

I am using example nginx configuration, and have tried switching to both developer and production modes. Request reaches static.php correctly which then returns a 404 header to nginx. The referenced files exist on disk and I have verified file permissions. I used the following workaround to disable static file signing, which has corrected the 404 for me:

INSERT INTO `core_config_data` (`scope`, `scope_id`, `path`, `value`) VALUES ('default', 0, 'dev/static/sign', '0');

You will need to clear cache after this, and also check for any entries with the same config path if you have previously modified this setting. This isn't a very good workaround as it would break cache-busting when using Varnish or any CDNs etc, but at least assets do not 404.

URL: https://github.com/magento/magento2/issues/7869

Nginx finally serving files now

This is a temporary fix until I can figure out how to run with version working.

| improve this answer | |
  • 1
    yes that's what I added in my answer – ParulThakkar Jun 16 at 5:58

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.