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 - LETSENCRYPT_EMAIL=info@mysite.com - 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 theenvironment
section, I have specified theVIRTUAL_PORT
as 9000 ’causephp-fpm
runs overfastcgi
. Then I linked theproxy
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?
Advertisement
Answer
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: info@example.com 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:
- Performance issue: we have two nginx layer here and the load time is increased a lot
- If I browse some url like example.com/admin I get 404 from nginx, guess it’s a configuration issue on my own