docker icon indicating copy to clipboard operation
docker copied to clipboard

[Question] Serving fpm-alpine image with nginx

Open lonix1 opened this issue 4 years ago • 51 comments

I am trying to get the fpm-alpine image to work with nginx.

docker-compose.yml

version: "3.7"

networks:
  mynet:

volumes:
  mariadb_data:
  phpmyadmin_data:

services:

  mariadb:
    image: mariadb:10.4.8-bionic
    environment:
      MYSQL_DATABASE: mydb
      MYSQL_ROOT_PASSWORD: password
      MYSQL_USER: admin
      MYSQL_PASSWORD: password
    volumes:
      - mariadb_data:/var/lib/mysql/
    networks:
      - mynet

  phpmyadmin:
    image: phpmyadmin/phpmyadmin:fpm-alpine
    volumes:
      - phpmyadmin_data:/var/www/html/
    networks:
      - mynet
    depends_on:
      - mariadb

  nginx:
    image: nginx:1.17.4-alpine
    volumes:
      - ./default.conf:/etc/nginx/conf.d/default.conf:ro
      - phpmyadmin_data:/var/www/html/:ro
    ports:
      - "80:80"
    networks:
      - mynet
    depends_on:
      - mariadb
      - phpmyadmin

default.conf

resolver 127.0.0.11 valid=15s;

server {

  listen 80;
  server_name www.example.com;

  root /var/www/html/;
  index index.php index.html index.htm;

  set $upstream phpmyadmin:9000;

  location ~ \/pma {
    fastcgi_pass $upstream;
    fastcgi_index index.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;
  }
}

Then: docker-compose up.

When I access http://www.example.com/pma I get

502 Bad Gateway

I also tried to get it working using a port instead of path, i.e. http://www.example.com:8080 instead of http://www.example.com/pma.

The docs show examples using traefik and haproxy, but not for nginx.

Can someone spot the error in my setup, or does someone have a working example to share?

lonix1 avatar Oct 18 '19 16:10 lonix1

@lonix1 try port 9000 on host phpmyadmin for fastcgi_pass since you are sending the script to the cgi and not to the web server

If it does not work comment back here :)

williamdes avatar Oct 18 '19 16:10 williamdes

@williamdes Thanks - yes you are right it should be 9000! I edited it above.

However, it still does not work :-(

curl http://www.example.com/pma gives:

File not found.

The docker log shows:

"GET /pma/index.php" 404

lonix1 avatar Oct 18 '19 17:10 lonix1

maybe you should change /var/www/html to /usr/src/phpmyadmin

See: https://github.com/phpmyadmin/docker/blob/master/fpm-alpine/Dockerfile#L77

I assume you have data into the volume phpmyadmin_data

https://superuser.com/a/435969/609233 I would write the nginx config block like that

  location ~ \/pma {
    rewrite ^/pma(/.*)$ $1 last;
    fastcgi_pass $upstream;
    fastcgi_index index.php;
    include snippets/fastcgi-php.conf;
    # remove line below ?
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
  }

You are maybe missing the rewrite part since the files are in the root folder and not in /pma

williamdes avatar Oct 18 '19 17:10 williamdes

When I do docker-compose up for the first time, it says

phpMyAdmin not found in /var/www/html - copying now... Complete! phpMyAdmin has been successfully copied to /var/www/html

That's why I used that path. But even if I use /usr/src/phpmyadmin it fails with same error. I checked that there are files in there, looks okay.

I tried the new location block also. Same error (file not found).

Does that actually work for you?


I will carry on fiddling to get it working. Maybe we can then add it to the docs.

lonix1 avatar Oct 18 '19 18:10 lonix1

~After hours (since my last post) I could not make a rewrite folder that worked.~

Light version

resolver 127.0.0.11 valid=15s;
server {
    listen 80;
    server_name williamdes.local default_server;
    root /var/www/html/;
    index index.php index.html index.htm;
    set $upstream phpmyadmin:9000;

    location ~ \.php$ {
        try_files $uri = 404;
        #fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass $upstream;
        fastcgi_index index.php;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param PATH_INFO $fastcgi_path_info;
    }
}
version: "3.7"

networks:
  mynet:

volumes:
  mariadb_data:
  phpmyadmin_data:

services:

  mariadb:
    image: mariadb:10.4.8-bionic
    environment:
      MYSQL_DATABASE: mydb
      MYSQL_ROOT_PASSWORD: password
      MYSQL_USER: admin
      MYSQL_PASSWORD: password
    volumes:
      - mariadb_data:/var/lib/mysql/
    networks:
      - mynet

  phpmyadmin:
    image: phpmyadmin/phpmyadmin:fpm-alpine
    environment:
      PMA_HOST: mariadb
    volumes:
      - phpmyadmin_data:/var/www/html/
    networks:
      - mynet
    depends_on:
      - mariadb

  nginx:
    image: nginx:1.17.4-alpine
    volumes:
      - ./default.conf:/etc/nginx/conf.d/default.conf:ro
      - phpmyadmin_data:/var/www/html/:ro
    ports:
      - "90:80"
    networks:
      - mynet
    depends_on:
      - mariadb
      - phpmyadmin

williamdes avatar Oct 18 '19 20:10 williamdes

Using a proxy

resolver 127.0.0.11 valid=15s;
server {
    listen 80;
    server_name williamdes.local default_server;
    root /var/www/html/;
    index index.php index.html index.htm;
    set $upstream phpmyadmin:9000;

    location ^~ /pma {
        rewrite /pma/(.*) /$1 last;
        proxy_pass http://localhost:80;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-Proto $http_x_forwarded_proto;
        proxy_cache_bypass $http_upgrade;
        proxy_redirect off;
    }

    location ~ \.php$ {
        try_files $uri = 404;
        #fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass $upstream;
        fastcgi_index index.php;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param PATH_INFO $fastcgi_path_info;
    }
}

Using CGI

Thanks to: https://stackoverflow.com/a/29213330/5155484

resolver 127.0.0.11 valid=15s;
server {
    listen 80;
    server_name williamdes.local default_server;
    root /var/www/html/;
    index index.php index.html index.htm;
    set $upstream phpmyadmin:9000;

    location ^~ /pma {
        rewrite /pma/(.*) /$1 last;
        try_files $uri = 404;
        #fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass $upstream;
        fastcgi_index index.php;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param PATH_INFO $fastcgi_path_info;
    }

    location ~ \.php$ {
        try_files $uri = 404;
        #fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass $upstream;
        fastcgi_index index.php;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param PATH_INFO $fastcgi_path_info;
    }
}

@lonix1 the CGI version is what you want

williamdes avatar Oct 18 '19 20:10 williamdes

@williamdes wow thanks! I used the "Using CGI" section, and got it working finally, but on the wrong path:

curl http://www.example.com/pma gives 404 but curl http://www.example.com/ gives the phpmyadmin login page


BTW, I assume your "Using a proxy" section is for the latest image, and "Using CGI" is for the fpm-alpine and fpm images?

lonix1 avatar Oct 19 '19 13:10 lonix1

I think you are correct on what you assume

@lonix1 can you paste your final configuration?

I made it work with the ^~ and position can be important from what Internet says

williamdes avatar Oct 19 '19 18:10 williamdes

Okay I got it to work, thanks to this!

Notes:

  • No rewriting necessary
  • I did not need to set PMA_ABSOLUTE_URI - not sure why?
resolver 127.0.0.11 valid=15s;

server {

  listen 80;
  server_name www.example.com example.com;
  set $upstream phpmyadmin:9000;

  location ^~ /phpmyadmin {
    alias /var/www/html/;
    index index.php;
    location ~ \.php$ {
      try_files $uri = 404;
      fastcgi_pass $upstream;
      include fastcgi_params;
      fastcgi_param SCRIPT_FILENAME $request_filename;
    }
  }

}

This should be in the docs. If someone knows how to do that, please add @williamdes' code for latest image and my code for fpm-alpine and fpm images.

lonix1 avatar Oct 20 '19 07:10 lonix1

@williamdes BTW thanks for taking the time to help me... Appreciated!

lonix1 avatar Oct 20 '19 07:10 lonix1

@lonix1 I think it is because all files need to know their base path?

williamdes avatar Oct 20 '19 08:10 williamdes

@williamdes Yes... so we need to correctly set SCRIPT_FILENAME.

lonix1 avatar Oct 20 '19 09:10 lonix1

@lonix1 please post the config when you have a working example ;)

williamdes avatar Oct 20 '19 10:10 williamdes

@williamdes This works for me:

docker-compose.yml

version: "3.7"

networks:
  mynet:

volumes:
  mariadb_data:
  phpmyadmin_data:

services:

  mariadb:
    image: mariadb:10.4.8-bionic
    environment:
      MYSQL_DATABASE: mydb
      MYSQL_ROOT_PASSWORD: password
      MYSQL_USER: admin
      MYSQL_PASSWORD: password
    volumes:
      - mariadb_data:/var/lib/mysql/
    networks:
      - mynet

  phpmyadmin:
    image: phpmyadmin/phpmyadmin:fpm-alpine
    environment:
      PMA_HOST: mariadb
     #PMA_ABSOLUTE_URI: http://www.example.com/phpmyadmin/
    volumes:
      - phpmyadmin_data:/var/www/html/
     #- ./config.user.inc.php:/etc/phpmyadmin/config.user.inc.php:ro
    networks:
      - mynet
    depends_on:
      - mariadb

  nginx:
    image: nginx:1.17.4-alpine
    volumes:
      - ./default.conf:/etc/nginx/conf.d/default.conf:ro
      - phpmyadmin_data:/var/www/html/:ro
    ports:
      - "80:80"
    networks:
      - mynet
    depends_on:
      - mariadb
      - phpmyadmin

default.conf

resolver 127.0.0.11 valid=15s;

server {
  listen 80;
  server_name www.example.com example.com;
  set $upstream phpmyadmin:9000;

  location ^~ /phpmyadmin {
    alias /var/www/html/;
    index index.php;
    location ~ \.php$ {
      try_files      $uri = 404;
      include        fastcgi_params;
      fastcgi_split_path_info ^\/phpmyadmin\/(.+\.php)(.*)$;
      fastcgi_param  SCRIPT_FILENAME $fastcgi_script_name;
      fastcgi_pass   $upstream;
    }
  }

}

Of course, in production, nginx would not be in the same stack (but should be in the same docker network).

lonix1 avatar Oct 20 '19 11:10 lonix1

@lonix1 Thank you !

From what I understand removing $document_root solved the URI issue.

If you want to open a pull-request let me know, if not I will do it

williamdes avatar Oct 20 '19 11:10 williamdes

I'm not sure how to do that... what I mean is that maybe the documents site can have this info...

lonix1 avatar Oct 20 '19 11:10 lonix1

@lonix1 Does nginx server need to have phpmyadmin volume attached to it? In my case I'd like to use host machine's nginx but don't want to share phpmyadmin docker's volume into host machine to actually use it as 'stateless' as possible.

Jason-2020 avatar Dec 27 '19 07:12 Jason-2020

@Jason-2020 From what I remember the alpine image doesn't come with a webserver, that's why you need to use nginx.

If you want phpmyadmin to be completely isolated, then don't use the alpine image. The normal image comes with apache, I think.

lonix1 avatar Dec 27 '19 08:12 lonix1

@lonix1 yes, there is an apache version I think you need to have the volume attached or you will get 404 errors if you do not bypass the file check on the nginx side before sending requests to the fpm server

williamdes avatar Dec 27 '19 09:12 williamdes

I'm trying to serve PHPMyAdmin on the root of a subdomain using Nginx, to avoid having two web-server running (I use Nginx for the rest of my application, so having Apache just for PMA is not really optimal...), but I cannot get it working.

I followed the conversation here, but all I get is a "404 not found", and this in the Nginx logs:

2020/02/14 21:34:49 [error] 15#15: *1 FastCGI sent in stderr: "Primary script unknown" while reading response header from upstream, client: 172.18.0.1, server: phpmyadmin.example.com, request: "GET / HTTP/1.1", upstream: "fastcgi://172.18.0.5:9000", host: "phpmyadmin.example.com"

Here's what I have for now for my Nginx config:

server {
    server_name phpmyadmin.example.com;
    root /var/www/html;
    index index.php index.html index.htm;

    location ~ \.php$ {
        try_files $uri = 404;

        fastcgi_pass phpmyadmin:9000;
        #fastcgi_split_path_info ^(.+\.php)(/.*)$;
        fastcgi_index index.php;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $fastcgi_script_name;
        fastcgi_param HTTPS off;
    }

    error_log /var/log/nginx/phpmyadmin_error.log;
    access_log /var/log/nginx/phpmyadmin_access.log;
}

Any idea?

ThibaultVlacich avatar Feb 14 '20 21:02 ThibaultVlacich

Hi @ThibaultVlacich Maybe you should follow https://github.com/phpmyadmin/docker/issues/253#issuecomment-543938409 and use fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;

Did this work ?

williamdes avatar Feb 14 '20 21:02 williamdes

It... worked...

Swear I tried it already but I guess not. Thanks @williamdes.

ThibaultVlacich avatar Feb 15 '20 14:02 ThibaultVlacich

Okay I got it to work, thanks to this!

Notes:

  • No rewriting necessary
  • I did not need to set PMA_ABSOLUTE_URI - not sure why?
resolver 127.0.0.11 valid=15s;

server {

  listen 80;
  server_name www.example.com example.com;
  set $upstream phpmyadmin:9000;

  location ^~ /phpmyadmin {
    alias /var/www/html/;
    index index.php;
    location ~ \.php$ {
      try_files $uri = 404;
      fastcgi_pass $upstream;
      include fastcgi_params;
      fastcgi_param SCRIPT_FILENAME $request_filename;
    }
  }

}

This should be in the docs. If someone knows how to do that, please add @williamdes' code for latest image and my code for fpm-alpine and fpm images.

I user this config ,www.example.com/phpmyadmin is work,but i add

    location / {
        uwsgi_pass  unix:/api/api.sock;        
        include     uwsgi_params;
    }

    location /phpmyadmin {
        alias /var/www/html/;
        index index.php;
        location ~ \.php$ {
        try_files $uri = 404;
        fastcgi_pass $upstream;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $request_filename;
        fastcgi_param PATH_INFO $fastcgi_path_info;
        }
    }

browser www.example.com will be download file , have any idea?

when fastcgi_param SCRIPT_FILENAME $request_filename; change to fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; it www.example.com/phpmyadmin does not work, i am not clear konw about fastcgi_param and variables does mean what

zengzhengrong avatar Apr 30 '20 11:04 zengzhengrong

browser www.example.com will be download file , have any idea?

You did not configure correctly the .php file handler IMO

williamdes avatar Apr 30 '20 12:04 williamdes

@williamdes I guess probably is browser cause it , I use edge to browse www.example.com ,it can show me page correctly ,but chrome do not,always download the php file

zengzhengrong avatar May 01 '20 03:05 zengzhengrong

@zengzhengrong Are you sure the URLs are exactly the same ? What about using curl or wget to have a test without a browser ?

williamdes avatar May 01 '20 18:05 williamdes

@williamdes I test curl or wget ,it both correctly route to my api.sock and postman as good as well,only chrome do not

zengzhengrong avatar May 02 '20 03:05 zengzhengrong

Very strange, could you send all the nginx config file?

williamdes avatar May 02 '20 08:05 williamdes

https://github.com/zengzhengrong/django-forum-backend/blob/master/nginx/conf.d/django.conf

resolver 127.0.0.11 valid=15s;

server {
    listen    80;
    charset     utf-8;
    client_max_body_size 75M;
    server_name     192.168.1.235;
    set $upstream phpmyadmin:9000;

    location /static {
        alias /api/static;
    }

    location /media {
        alias /api/media;
        expires 24h;
    }

    location /flower-internal/ {
        internal;
        rewrite ^/flower-internal/(.*)$ /$1 break;
        proxy_pass http://django-forum-backend:5555;
        proxy_set_header Host $host;
    }
    
    location / {
        uwsgi_pass  unix:/api/api.sock;        
        include     uwsgi_params;
    }

    location /phpmyadmin {
        alias /var/www/html/;
        index index.php;
        location ~ \.php$ {
        try_files $uri = 404;
        fastcgi_pass $upstream;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $request_filename;
        fastcgi_param PATH_INFO $fastcgi_path_info;
        }
    }

}

zengzhengrong avatar May 02 '20 15:05 zengzhengrong

@zengzhengrong Could you copy the request from F12 > Network > The request (index.php) > Copy > as curl and post it here after trying it into a terminal ?

williamdes avatar May 02 '20 15:05 williamdes