this is my first time working with nginx and I'm using it to access my dockerised drupal appliction from a production subdomain.
So before everything, I'm currently using docker-compose to create my sql, app, and webservice containers, here is my docker-compose file :
version: '3'
services:
app:
image: osiolabs/drupaldevwithdocker-php:7.4
volumes:
- ./docroot:/var/www/html:cached
depends_on:
- db
restart: always
container_name: intranet
db:
image: mysql:5.5
volumes:
- ./mysql:/var/lib/mysql
restart: always
environment:
- MYSQL_ROOT_PASSWORD=linux1354web
- MYSQL_USER=root
- MYSQL_PASSWORD=linux1354web
- MYSQL_DATABASE=intranet
container_name: intranet-db
web:
build: ./web
ports:
- 88:80
depends_on:
- app
volumes:
- ./docroot:/var/www/html:cached
restart: always
container_name: webIntranet
I don't think the containers are the problem, as when I go to the drupal containers the site works, but my main problem is the link with the nginx container. Here is my nginx.conf :
# stuff for http block
client_max_body_size 1g;
# fix error: upstream sent too big header while reading response header from upstream
fastcgi_buffers 16 16k;
fastcgi_buffer_size 32k;
server {
listen 80;
listen [::]:80 default_server;
server_name _;
index index.php index.html;
error_log /var/log/nginx/error.log;
access_log /var/log/nginx/access.log;
root /var/www/html;
#RENVOYER LA PAGE DE GARDE DE APACHE2
location / {
# try to serve file directly, fallback to app.php
try_files $uri /index.php?$query_string; # For Drupal >= 7
}
location /intranet {
# try to serve file directly, fallback to app.php
try_files $uri $uri/;
}
#RENVOYER LE FICHIER ROBOTS.TXT
location = /robots.txt {
allow all;
log_not_found off;
access_log off;
}
location = /favicon.ico {
log_not_found off;
access_log off;
}
location ~ \.php(/|$) {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass app:80;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param DOCUMENT_ROOT $document_root;
}
}
And this is my DockerFile to build nginx image:
FROM nginx:alpine
COPY nginx.conf /etc/nginx/conf.d/default.conf
When I go to localhost:88/ I currently have a apache2 hub page, but the moment I'm trying for another page I always get a 502 bad gateway error and the logs are saying :
webIntranet | 2021/03/11 08:44:55 [error] 30#30: *1 upstream sent unsupported FastCGI protocol version: 72 while reading response header from upstream, client: 172.26.0.1, server: _, request: "GET /index HTTP/1.1", upstream: "fastcgi://172.26.0.3:80", host: "localhost:88"
To go more into details, my docker folder looks like that, docroot containes the drupal website.
I have tried sovling the problem by changing the ports as some solution mentionned it but it did nothing, I don't understand what could be wrong, I've tried many things with the conf but none of them works, and I still even can't have a single page of the drupal site showing up.
The drupaldevwithdocker-php project isn't using php-fpm, hence the response is unsupported as it's from apache rather than php-fpm. I'd imagine you'd need something more like this?
proxy_pass http://app:80;
See https://gist.github.com/BretFisher/468bca2900b90a4dddb7fe9a52143fc6
Related
I had two WordPress websites on a Synology NAS at home running on NGINX with PHP-FPM 7.4 with virtual hosts.
I am moving these websites on a Debian VM also at home, and run the services in rootless Docker:
MariaDB official Docker container
NGINX official Docker container
PHP-FPM official Docker container
These websites are exposed through a Traefik Docker container and my DNS and Let's Encrypt certificates are managed with the Cloudflare API.
When I try to access to www.wordpress1.com, I get "The Page Isn’t Redirecting Properly" error.
I tried to add a phpinfo.php files in my WordPress websites, and I can access these files from WAN without any problem.
I tried to add a static website, and I can access it without any problem from WAN.
I have checked the logs for the two websites, and I get a lot of these errors:
GET / HTTP/1.1" 301 5
Here are my configuration files.
NGINX compose.yaml:
version: '3'
services:
nginx:
image: nginx:latest
container_name: nginx
restart: always
security_opt:
- no-new-privileges:true
networks:
- backend
- traefik
volumes:
- /etc/localtime:/etc/localtime:ro
- /etc/timezone:/etc/timezone:ro
- ./conf/servers.conf:/etc/nginx/conf.d/default.conf
- ./log:/var/log/nginx
- nginx_data:/var/www/html
labels:
- "traefik.enable=true"
- "traefik.http.routers.nginx.entrypoints=http"
- "traefik.http.routers.nginx.rule=Host(`static.com`,`www.wordpress1.com`,`www.wordpress2.com`)"
- "traefik.http.middlewares.nginx-https-redirect.redirectscheme.scheme=https"
- "traefik.http.routers.nginx.middlewares=nginx-https-redirect"
- "traefik.http.routers.nginx-secure.entrypoints=https"
- "traefik.http.routers.nginx-secure.rule=Host(`static.com`,`www.wordpress1.com`,`www.wordpress2.com`)"
- "traefik.http.routers.nginx-secure.tls=true"
- "traefik.http.routers.nginx-secure.service=nginx"
- "traefik.http.services.nginx.loadbalancer.server.port=80"
- "traefik.docker.network=traefik"
volumes:
nginx_data:
external: true
networks:
backend:
external: true
traefik:
external: true
NGINX servers.conf:
server {
listen 80;
server_name static.com;
root /var/www/html/static;
index index.html;
error_log /var/log/nginx/static_error.log;
access_log /var/log/nginx/static_access.log;
}
server {
listen 80;
server_name www.wordpress1.com;
root /var/www/html/wordpress1;
index index.php index.html;
error_log /var/log/nginx/wordpress1_error.log;
access_log /var/log/nginx/wordpress1_access.log;
location ~ \.php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass php:9000;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
}
location / {
try_files $uri $uri/ /index.php?$args;
}
}
server {
listen 80;
server_name www.wordpress2.com;
root /var/www/html/wordpress2;
index index.php index.html;
error_log /var/log/nginx/wordpress2_error.log;
access_log /var/log/nginx/wordpress2_access.log;
location ~ \.php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass php:9000;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
}
location / {
try_files $uri $uri/ /index.php?$args;
}
}
PHP compose.yaml:
version: '3'
services:
php:
build:
context: .
dockerfile: ./Dockerfile
image: custom/php:7.4-fpm
container_name: php
restart: always
security_opt:
- no-new-privileges:true
networks:
- backend
user: 1234:1234
volumes:
- /etc/localtime:/etc/localtime:ro
- /etc/timezone:/etc/timezone:ro
- nginx_data:/var/www/html
volumes:
nginx_data:
external: true
networks:
backend:
external: true
PHP Dockerfile:
FROM php:7.4-fpm
ADD https://github.com/mlocati/docker-php-extension-installer/releases/latest/download/install-php-extensions /usr/local/bin/
RUN chmod +x /usr/local/bin/install-php-extensions && install-php-extensions mysqli exif imagick zip
In the nginx_data volume, my permissions are 1234:1234, which are my docker user UID and GID on my rootless Docker install.
My database is on a mariadb docker container and the connection works (modified in the wp-config.php).
I don't understand why I can access the static website, why the phpinfo in the WordPress websites works, and why the WordPress websites doesn't work.
I though it was a problem of permission, but I used the "user" parameter in my PHP Docker container to specify it.
Thanks for your help.
[Edit] It seems the second WordPress website is displayed. So only the first one has this redirection error problem.
I tried with PHP v7.4 and PHP v8.1, same result.
I would suggest you to delete the previous SSL if you copied it, also delete the .httacess file if you copied it from the old one, if the problem persists you should check if any php extension is not installed.
I need to configure an nginx server to connect to multiple docker networks for different projects. As of now, I am trying to connect nginx to one docker network.
The docker network has php (laravel) and mysql in two different containers.
Here is the nginx configuration:
upstream web {
server 127.0.0.1:9000;
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name tinyurl.abc.org;
root /home/azureuser/app/url-shorterner/public;
ssl_certificate /home/azureuser/app/certs/abc.org.crt;
ssl_certificate_key /home/azureuser/app/certs/abc.org.key;
error_log /var/log/nginx/error.log error;
add_header X-Frame-Options "SAMEORIGIN";
add_header X-XSS-Protection "1; mode=block";
add_header X-Content-Type-Options "nosniff";
index index.php;
charset utf-8;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
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 web;
fastcgi_index index.php;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_param SCRIPT_FILENAME /tinyurl/public$fastcgi_script_name;
fastcgi_param QUERY_STRING $query_string;
include fastcgi_params;
}
location ~ /\.(?!well-known).* {
deny all;
}
}
server {
listen 80;
listen [::]:80;
server_name tinyurl.abc.org;
return 301 https://$server_name$request_uri;
}
The docker-compose.yml file has the following:
version: '3.8'
# Services
services:
# Web (Application) Service
web:
build:
context: ./.docker/web
args:
HOST_UID: $HOST_UID
container_name: tinyurl-web
ports:/
- '9000:9000'
volumes:
- '.:/var/www/html'
depends_on:
mysql:
condition: service_healthy
# MySQL Service
mysql:
image: mysql/mysql-server:8.0
container_name: tinyurl-mysql
environment:
MYSQL_ROOT_PASSWORD: '${DB_ROOT_PASSWORD}'
MYSQL_ROOT_HOST: '${DB_HOST}'
MYSQL_DATABASE: '${DB_DATABASE}'
MYSQL_USER: '${DB_USERNAME}'
MYSQL_HOST: '${DB_HOST}'
MYSQL_PASSWORD: '${DB_PASSWORD}'
MYSQL_ALLOW_EMPTY_PASSWORD: 'no'
volumes:
- ./.docker/mysql/my.cnf:/etc/mysql/conf.d/my.cnf
- mysqldata:/var/lib/mysql
healthcheck:
test: mysqladmin ping -h 127.0.0.1 -u root --password=$$MYSQL_ROOT_PASSWORD
interval: 5s
retries: 10
# Scheduler Service
scheduler:
image: mcuadros/ofelia:latest
container_name: tinyurl-scheduler
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- ./.docker/scheduler/config.ini:/etc/ofelia/config.ini
depends_on:
- web
volumes:
mysqldata:
driver: local
The problem seems to be in the routing of the request. The index.page within the public folder of laravel shows up, but none of the other static pages are showing up. Also, the routing of the requests is not happening correctly.
Looks like the fastcgi configuration is not okay.
Can anyone help with this, and point me to what needs to be done to the nginx configuration to route to the web container having laravel.
With Regards,
Sharat
In your nginx config, replace 127.0.0.1 with the service name in your docker-compose
upstream web {
server web:9000;
}
server {
...
location ~ \.php$ {
fastcgi_pass http://web;
...
I'm trying to install Nextcloud on my server.
The nginx service is installed directly on bare metal (Ubuntu)
I starting from the docker-compose found at https://github.com/nextcloud/docker/tree/master/.examples/docker-compose/with-nginx-proxy/postgres/fpm
version: '3.8'
services:
postgres-nextcloud:
image: postgres:alpine
restart: always
ports:
- 5435:5432
volumes:
- postgres-nextcloud-data:/var/lib/postgresql/data
env_file:
- db.env
redis-nextcloud:
image: redis:alpine
restart: always
nextcloud:
image: nextcloud:fpm-alpine
restart: always
ports:
- 8083:9000
volumes:
- /var/www/cloud.domain.com:/var/www/html
environment:
- POSTGRES_HOST=postgres-nextcloud
- REDIS_HOST=redis-nextcloud
- POSTGRES_PORT=5432
env_file:
- db.env
depends_on:
- postgres-nextcloud
- redis-nextcloud
web:
build: ./web
restart: always
volumes:
- /var/www/cloud.domain.com:/var/www/html:ro
environment:
- VIRTUAL_HOST=cloud.domain.com
- LETSENCRYPT_HOST=cloud.domain.com
- LETSENCRYPT_EMAIL=dev#domain.com
depends_on:
- nextcloud
networks:
- proxy-tier
- default
cron:
image: nextcloud:fpm-alpine
restart: always
volumes:
- /var/www/cloud.domain.com:/var/www/html
entrypoint: /cron.sh
depends_on:
- postgres-nextcloud
- redis-nextcloud
But with my knowledge in web server I haven't found the way to properly configure my "local" nginx.
I've many other website, app already working using this nginx instance
All the different config are in the sites-available directory
The config for the Nextcloud project is named cloud.mydomain.com
with this nginx config I only get a File not found. Page
server {
root /var/www/cloud.domain.com;
server_name cloud.domain.com www.cloud.domain.com;
index index.html index.htm index.php;
charset utf-8;
location / {
try_files $uri $uri/ /index.php?$query_string;
gzip_static on;
}
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$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass localhost:8083;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
}
error_log /var/log/nginx/error.log;
access_log /var/log/nginx/access.log;
listen [::]:443 ssl; # managed by Certbot
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/cloud.domain.com/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/cloud.domain.com/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}
server {
if ($host = www.cloud.domain.com) {
return 301 https://$host$request_uri;
} # managed by Certbot
if ($host = cloud.domain.com) {
return 301 https://$host$request_uri;
} # managed by Certbot
server_name cloud.domain.com www.cloud.domain.com;
listen 80;
listen [::]:80;
return 404; # managed by Certbot
}
I understand that -fpm app need a proxy but I don't really understand how to link it to my existing nginx set up. With the nginx NOT running in a docker container.
Thanks for your time!
One way I know is to install another nginx in another container and put those two containers in one network in docker...
Use your baremetal nginx as reverse proxy then forward traffic to the nginx in container will do the trick.
The other way is to use the image nextcloud:latest which comes with built in Apache server. Its actually the first way with built-in web server.
I heard there some way to configure your docker image to behave like a service installed on baremetal (with own public IP) by setting the network-mode in docker-compose files but I think its easier to just include another nginx server in docker...
Either way your existing service on baremetal will not be affected.
I user nginx docker as proxy server, and there are other containers running: nuxt.js and php-fpm.
This is my fpm's conf file:
server {
server_name fpm.me.com;
root /var/www/fpm/html;
location / {
# try to serve file directly, fallback to index.php
try_files $uri /index.php$is_args$args;
}
#location ~ ^/index\.php(/|$) {
# https://stackoverflow.com/questions/68350978/nginx-serving-only-but-not-any-other-files
location ~ \.php(/|$) {
fastcgi_pass fpm:9000;
fastcgi_split_path_info ^(.+\.php)(/.*)$;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
fastcgi_param DOCUMENT_ROOT $realpath_root;
#internal;
}
location ~ \.php$ {
return 404;
}
access_log off;
error_log /dev/stderr;
}
But when I type fpm.me.com, I get this error in nginx's log file:
2021/08/03 09:31:18 [error] 31#31: *13 FastCGI sent in stderr: "Primary script unknown" while reading response header from upstream, client: MY_IP, server: fpm.me.com, request: "GET / HTTP/1.1", upstream: "fastcgi://172.20.0.8:9000", host: "fpm.me.com"
I saw other answers in StackOverFlow, ServerFault and other websites but it seems it did not help me.
This doesn't look valid:
fastcgi_pass fpm:9000
You have 2 options:
use a unix socket:
fastcgi_pass unix:/run/php/php7.4-fpm.sock;
use TCP port
fastcgi_pass 127.0.0.1:9000;
Option 1 is slightly faster and doesn't have the risk of ports exhaustion if you receive many concurrent connections.
The issue was with the volumes I mounted for nginx and fpm which were not the same.
This is my compose file:
services:
nginx:
image: nginx
volumes:
- './fpm/:/var/www/fpm/'
fpm:
image: custom
volumes:
- './fpm/:/var/www/'
While it should have been like this to work:
services:
nginx:
image: nginx
volumes:
- './fpm/:/var/www/fpm/'
fpm:
image: custom
volumes:
- './fpm/:/var/www/fpm/'
Have been trying to setup my own LEMP stack locally , nginx and php both seem to be working well alone, however on trying to integrate php in nginx is failing...!!! getting error
403 Forbidden
nginx error logs:
2018/07/22 12:06:48 [error] 9#9: *1 directory index of "/usr/share/nginx/html/" is forbidden, client: 172.19.0.4, server: localhost, request: "GET / HTTP/1.1", host: "laradock.localhost:8000"
172.19.0.4 - - [22/Jul/2018:12:06:48 +0000] "GET / HTTP/1.1" 403 571 "-" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36" "172.19.0.1"
Been using below docker image versions:
PHP_TAG=7.1-fpm-alpine
NGINX_TAG=alpine
my docker-compose.yml file
version: "2"
services:
php:
image: php:$PHP_TAG
# restart: always
container_name: "${PROJECT_NAME}_php"
environment:
PHP_SENDMAIL_PATH: /usr/sbin/sendmail -t -i -S mailhog:1025
DB_HOST: $DB_HOST
DB_USER: $DB_USER
DB_PASSWORD: $DB_PASSWORD
DB_NAME: $DB_NAME
DB_DRIVER: $DB_DRIVER
volumes:
- /var/www/ro_www/src/sample_site/:/usr/share/nginx/html
nginx:
image: nginx:$NGINX_TAG
container_name: "${PROJECT_NAME}_nginx"
depends_on:
- php
# - mysqld
environment:
NGINX_STATIC_CONTENT_OPEN_FILE_CACHE: "off"
NGINX_ERROR_LOG_LEVEL: debug
NGINX_BACKEND_HOST: php
NGINX_SERVER_ROOT: /var/www/html/
# NGINX_DRUPAL_FILE_PROXY_URL: http://example.com
volumes:
- /var/www/ro_www/src/sample_site/:/usr/share/nginx/html
- ./config/site.conf:/etc/nginx/conf.d/site.conf:ro
# - ./etc/ssl:/etc/ssl
# ports:
# - "8000:80"
# - "3000:443"
labels:
- 'traefik.backend=nginx'
- 'traefik.port=80'
- 'traefik.frontend.rule=Host:${PROJECT_BASE_URL}'
mailhog:
image: mailhog/mailhog
container_name: "${PROJECT_NAME}_mailhog"
labels:
- 'traefik.backend=mailhog'
- 'traefik.port=8025'
- 'traefik.frontend.rule=Host:mailhog.${PROJECT_BASE_URL}'
adminer:
container_name: "${PROJECT_NAME}_adminer"
image: wodby/adminer:$ADMINER_TAG
environment:
ADMINER_SALT: adminer-salt
volumes:
- /var/www/ro_www/src/sample_site/adminer/:/usr/share/nginx/html
labels:
- 'traefik.backend=adminer'
- 'traefik.port=9000'
- 'traefik.frontend.rule=Host:adminer.${PROJECT_BASE_URL}'
portainer:
image: portainer/portainer
container_name: "${PROJECT_NAME}_portainer"
command: --no-auth -H unix:///var/run/docker.sock
volumes:
- /var/run/docker.sock:/var/run/docker.sock
labels:
- 'traefik.backend=portainer'
- 'traefik.port=9000'
- 'traefik.frontend.rule=Host:portainer.${PROJECT_BASE_URL}'
traefik:
image: traefik
container_name: "${PROJECT_NAME}_traefik"
command: -c /dev/null --web --docker --logLevel=INFO
ports:
- '8000:80'
- '8080:8080' # Dashboard
volumes:
- /var/run/docker.sock:/var/run/docker.sock
The nginx site.conf file is as follows:
server {
listen 80;
server_name nginx;
#charset koi8-r;
#access_log /var/log/nginx/host.access.log main;
location / {
root /usr/share/nginx/html;
index index.html index.htm index.php;
}
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
# error_page 500 502 503 504 /50x.html;
# location = /50x.html {
# root /usr/share/nginx/html;
# }
# proxy the PHP scripts to Apache listening on 127.0.0.1:80
#
#location ~ \.php$ {
# proxy_pass http://127.0.0.1;
#}
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
location ~ \.php$ {
#root html;
#fastcgi_pass php:9000;
fastcgi_pass unix:/var/run/php-fpm.sock;
fastcgi_index index.php;
#fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
#
location ~ /\.ht {
deny all;
}
}
Thanks in advance for your help !!! ;)
Since I did not get much feedback, after much trial and error, I got my solution!!
So am posting this, in case somebody may have similar issue.
It seems the issue here was the nginx site.conf file.
server {
listen 80;
listen [::]:80;
index index.php index.html;
server_name laradock.localhost;
error_log /var/log/nginx/error.log;
access_log /var/log/nginx/access.log;
root /usr/share/nginx/html;
location / {
autoindex on; #to list file in the directory if the index file is missing
}
#### this was where i was facing the issue, the php block
location ~ \.php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass php:9000;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
}
}
Another this to note is that nginx can have multiple .conf config files, and it dosent support .htaccess file like apache (the htaccess logic needs to be re-written to a .conf file in the nginx conf.d directory here)
The complete code for my solution can be found at this git repository