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:
/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.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?
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: