nginx return file not found with nginx-proxy and doesn't load static files
Asked Answered
E

1

8

I'm using nginx-proxy-automation to run my php application which is written using CodeIgniter 4 and the app structure is the following:

php-application
   docker
       php-fpm
            config
                php.ini
           Dockerfile
   src
       node_modules
       app
       public
       tests
       vendor
       writable
       .env
       composer.json
       package.json
       spark
   docker-comopse.yml

the index.php file is available inside the public folder. The docker-compose.yml of php-application contains the following stuff:

nginx
    nginx-proxy
       docker-compose.yml
    php-application
       docker-compose.yml

Inside the php-application/docker-compose.yml I have this:

version: '3.7'

services:
  php-fpm:
    container_name: boilerplate_app
    restart: always
    build:
      context: .
      dockerfile: ./docker/php-fpm/Dockerfile
    volumes:
      - ./src:/var/www/html
    environment:
      # NGINX-PROXY ENVIRONMENT VARIABLES: UPDATE ME
      - VIRTUAL_HOST=mysite.com
      - VIRTUAL_ROOT=/var/www/html/public
      - VIRTUAL_PORT=9000
      - VIRTUAL_PROTO=fastcgi
      - LETSENCRYPT_HOST=mysite.com
      - [email protected]
      - NETWORK=proxy
      # /END NGINX-PROXY ENVIRONMENT VARIABLES
    ports:
      - '9000:80'
    expose:
      - 9000
    networks:
      - proxy

  database:
    container_name: boilerplate_db
    restart: always
    build:
      context: ./docker/database
    environment:
      - MYSQL_DATABASE=boilerplate
      - MYSQL_USER=user
      - MYSQL_PASSWORD=secret
      - MYSQL_ROOT_PASSWORD=secret
    volumes:
      - ./docker/database/data.sql:/docker-entrypoint-initdb.d/data.sql

  phpmyadmin:
    container_name: boilerplate_phpmyadmin
    image: phpmyadmin/phpmyadmin
    restart: always
    ports:
      - 8088:80
    environment:
      - PMA_HOST=database
      - MYSQL_USER=user
      - MYSQL_PASSWORD=secret
      - MYSQL_ROOT_PASSWORD=secret
    depends_on:
      - database

networks:
  proxy:
    external:
      name: proxy

essentially I have three services:

  • php-fpm: which mount the application files in the /var/www/html folder, and in the environment section, I have specified the VIRTUAL_PORT as 9000 'cause php-fpm runs over fastcgi. Then I linked the proxy network which is the network of your image.
  • database: runs within the app network
  • phpmyadmin: runs within the app network

The Dockerfile content of php-fpm contains the following stuff:

FROM php:8.0.2-fpm-alpine
WORKDIR /var/www/html

RUN docker-php-ext-install pdo_mysql
RUN docker-php-ext-install mysqli
RUN apk add icu-dev

# Install intl
RUN docker-php-ext-configure intl && docker-php-ext-install intl

# Install curl
RUN apk add --update libzip-dev curl-dev &&\
    docker-php-ext-install curl && \
    apk del gcc g++ &&\
    rm -rf /var/cache/apk/*

COPY docker/php-fpm/config/php.ini /usr/local/etc/php/

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

# Install nodejs
RUN apk add --update nodejs nodejs-npm
RUN npm install gulp-cli -g
RUN npm install

COPY src src/

CMD ["php-fpm"]

EXPOSE 9000

when I start the container using docker-compose up --build -d I get this message when I visit mysite.com (I have hidden the real domain for privacy):

File not found.

Inspecting the nginx log using sudo docker logs -f nginx I get:

[error] 30#30: *39 FastCGI sent in stderr: "Primary script unknown" while reading response header from upstream, client: 2.38.140.109, server: mysite.com, request: "GET / HTTP/2.0", upstream: "fastcgi://172.28.0.7:9000", host: "mysite.com"
mysite.com 2.38.140.109 - - [29/Mar/2021:17:52:31 +0000] "GET / HTTP/2.0" 404 16 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.90 Safari/537.36 Edg/89.0.774.63"

For fix this problem, I have update the nginx.tmpl with this one.

The problem now is that when I load my site all the static files such js / image / css return 404.

What can I do for fix this?

Edwardoedwards answered 29/3, 2021 at 17:54 Comment(7)
php-application/docker-compose.yml environment section is VIRTUAL_ROOT=/var/www/html, but you said it is /var/www/html/public. Are you sure of your php-application/docker-compose.yml? What if you let nginx execute an index.html from /var/www/html/ to see if it's working properly?Stater
exec the container, then tail /var/log/nginx/error.log to see the error. Before, run ls -l /var/log/nginx/error.log. If it's pointed to stderr, remove this file and run nginx -s reload and run your site again, then run tail -f ... to see errorsStater
Check /etc/resolve.conf. It seems there's resolve problem. Check both on your host and container.Stater
Check this link: community.letsencrypt.org/t/… and let me know if it resolves your issueStater
Also you can create /etc/resolve.conf in your host with this single line nameserver 8.8.8.8, then restart your host's network and try your task again.Stater
So, have you done the suggests in your link?Stater
As it said, first run docker exec -ti nginx-proxy cat /etc/nginx/fastcgi.conf to see if you have this file. If does not exist, run docker exec -ti nginx-proxy echo "fastcgi_index index.php;" >> /etc/nginx/fastcgi.conf. Then run docker exec -it nginx-proxy nginx -s reload Or as said in the last post, create a file called /etc/nginx/fastcgi_params and reload nginx again to see if it works.Stater
E
1

In order to serve the static files from a container using the nginx proxy, the nginx proxy must have access to files statically... it would not 'proxy' but 'read' and serve the files... which means you must mount the app files into the proxy...

I would recommend you put up a new, light and clean nginx behind the nginx proxy along with your php-fpm service so you can have full management of your routes/locations,

First of all I have created a docker-compose.yml in my app that contains the following:

version: '3.9'

services:

php-fpm:
    container_name: boilerplate_app
    restart: always
    build:
    context: .
    dockerfile: ./docker/php-fpm/Dockerfile
    volumes:
    - ./src:/var/www/html

nginx:
    image: nginx:stable-alpine
    container_name: boilerplate_nginx
    restart: always
    volumes:
    - ./src:/var/www/html
    - ./docker/nginx/nginx.conf:/etc/nginx/nginx.conf
    - ./docker/nginx/sites/:/etc/nginx/sites-available
    - ./docker/nginx/conf.d/:/etc/nginx/conf.d
    depends_on:
    - php-fpm
    environment:
    VIRTUAL_HOST: example.com
    LETSENCRYPT_HOST: example.com
    LETSENCRYPT_EMAIL: [email protected]
    
database:
    container_name: boilerplate_db
    restart: always
    build:
    context: ./docker/database
    environment:
    - MYSQL_DATABASE=boilerplate
    - MYSQL_USER=user
    - MYSQL_PASSWORD=secret
    - MYSQL_ROOT_PASSWORD=secret
    volumes:
    - ./docker/database/data.sql:/docker-entrypoint-initdb.d/data.sql

phpmyadmin:
    container_name: boilerplate_phpmyadmin
    image: phpmyadmin/phpmyadmin
    restart: always
    ports:
    - 8088:80
    environment:
    - PMA_HOST=database
    - MYSQL_USER=user
    - MYSQL_PASSWORD=secret
    - MYSQL_ROOT_PASSWORD=secret
    depends_on:
    - database
    
networks:
default:
    external:
    name: proxy

then, inside my app directory I have created the nginx configurations structure:

app
   docker
       nginx
           conf.d
              default.conf
           sites
              default.conf
        nginx.conf

where I have conf.d:

upstream php-upstream {
    server php-fpm:9000;
}

then I have sites:

server {
    root   /var/www/html/public;
    index index.php;

    location ~ [^/]\.php(/|$) {
    fastcgi_split_path_info ^(.+?\.php)(/.*)$;

    include fastcgi_params;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    fastcgi_param PATH_INFO       $fastcgi_path_info;
    fastcgi_param PATH_TRANSLATED $document_root$fastcgi_path_info;

    fastcgi_pass   php-upstream;
    fastcgi_index  index.php;
    }
}

and nginx.conf:

user  nginx;
worker_processes  4;

error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;

events {
    worker_connections  1024;
}

http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    access_log  /var/log/nginx/access.log;
    # Switch logging to console out to view via Docker
    #access_log /dev/stdout;
    #error_log /dev/stderr;

    sendfile        on;
    keepalive_timeout  65;
    
    include /etc/nginx/conf.d/*.conf;
    include /etc/nginx/sites-available/*.conf;
}

the site load now but there are some issues:

  1. Performance issue: we have two nginx layer here and the load time is increased a lot
  2. If I browse some url like example.com/admin I get 404 from nginx, guess it's a configuration issue on my own
Edwardoedwards answered 6/4, 2021 at 14:24 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.