tleb
tleb

Reputation: 4616

nginx and php-fpm in Docker

I am in the process of Dockerising my webserver/php workflow.

But because I am on Windows, I need to use a virtual machine. I chose boot2docker which is a Tiny Core Linux running in Virtualbox and adapted for Docker.

I selected three containers:

In boot2docker, /www/ contains my web projects and conf/, which has the following tree:

conf
│
├───fig
│       fig.yml
│
└───nginx
        nginx.conf
        servers-global.conf
        servers.conf

Because docker-compose is not available for boot2docker, I must use fig to automate everything. Here is my fig.xml:

mysql:
 image: mysql
 environment:
  - MYSQL_ROOT_PASSWORD=root
 ports:
  - 3306:3306

php:
 image: jprjr/php-fpm
 links:
  - mysql:mysql
 volumes:
  - /www:/srv/http:ro
 ports:
  - 9000:9000

nginx:
 image: nginx
 links:
  - php:php
 volumes:
  - /www:/www:ro
 ports:
  - 80:80
 command: nginx -c /www/conf/nginx/nginx.conf

Here is my nginx.conf:

daemon off;

user  nginx;
worker_processes  1;

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

events {
    worker_connections  1024;
}

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

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile        off;

    keepalive_timeout  65;

    index    index.php index.html index.htm;

    include /www/conf/nginx/servers.conf;

    autoindex on;
}

And the servers.conf:

server {
    server_name lab.dev;
    root /www/lab/;

    include /www/conf/nginx/servers-global.conf;
}

# Some other servers (vhosts)

And the servers-global.conf:

listen 80;

location ~* \.php$ {
    fastcgi_index   index.php;
    fastcgi_pass    php:9000;
    include         /etc/nginx/fastcgi_params;
    fastcgi_param   SCRIPT_FILENAME     /srv/http$fastcgi_script_name;
}

So the problem now (sorry for all that configuration, I believe it was needed to clearly explain the problem): If I access lab.dev, no problem (which shows that the host is created in Windows) but if I try to access lab.dev/test_autoload/, I have a File not found.. I know this comes from php-fpm not being able to access the files, and the nginx logs confirm this:

nginx_1 | 2015/05/28 14:56:02 [error] 5#5: *3 FastCGI sent in stderr:
"Primary script unknown" while reading response header from upstream,
client: 192.168.59.3, server: lab.dev, request: "GET /test_autoload/ HTTP/1.1",
upstream: "fastcgi://172.17.0.120:9000", host: "lab.dev", referrer: "http://lab.dev/"

I know that there is a index.php in lab/test_autoload/ in both containers, I have checked. In nginx, it is located in /www/lab/test_autoload/index.php and /srv/http/lab/test_autoload/index.php in php.

I believe the problem comes from root and/or fastcgi_param SCRIPT_FILENAME, but I do not know how to solve it.

I have tried many things, such as modifying the roots, using a rewrite rule, adding/removing some /s, etc, but nothing has made it change.

Again, sorry for all this config, but I think it was needed to describe the environment I am in.

Upvotes: 4

Views: 4721

Answers (3)

tleb
tleb

Reputation: 4616

I finally found the answer.

The variable $fastcgi_script_name did not take into account the root (logical, as it would have included www/ otherwise. This means that a global file can not work. An example :

# "generated" vhost
server {
    server_name lab.dev;
    root /www/lab/;

    listen 80;

    location ~* \.php$ {
        fastcgi_index   index.php;
        fastcgi_pass    php:9000;
        include         /etc/nginx/fastcgi_params;
        fastcgi_param   SCRIPT_FILENAME     /srv/http$fastcgi_script_name;
        # I need to add /lab after /srv/http because it requests PHP to look at the root of the web files, not in the lab/ folder
        # fastcgi_param   SCRIPT_FILENAME     /srv/http/lab$fastcgi_script_name;
    }
}

This meant that I couldn't write the lab/ at only one place, I needed to write at two different places (root and fastcgi_param) so I decided to write myself a small PHP script that used a .json and turned it into the servers.conf file. If anyone wants to have a look at it, just ask, it will be a pleasure to share it.

Upvotes: 2

renouveaux
renouveaux

Reputation: 11

Your nginx.conf is fully empty, where is the daemon off; the user nginx line, worker_processes etc.. nginx need some configuration file before running the http.

In the http conf, same thing, is missing the mime types, the default_type, configuration of logs sendfile at on for boot2docker.

Your problem is clearly not a problem with Docker, but with the nginx configuration. Have you test your application with running docker run before using fig ? Did it worked ?

Upvotes: 0

renouveaux
renouveaux

Reputation: 11

There's a mistake here:

fastcgi_param   SCRIPT_FILENAME     /srv/http/$fastcgi_script_name;

The good line is:

fastcgi_param   SCRIPT_FILENAME     /srv/http$fastcgi_script_name;

This is not the same thing.

Upvotes: 1

Related Questions