I have nginx and php-fpm running in separate docker containers. Php-fpm processs the same php script in as fast time as php-fpm running on bare-metal (not using docker). However, the TTFB when using nginx+php-fpm docker is always over 1.3 seconds, whereas running nginx+php-fpm on bare metal (no docker) TTFB is always < 30 ms.
Why is nginx (presumably) so slow on docker? More importantly, I'm sure this is a configuration issue that can be resolved, what in my docker-compose yml needs to be changed to improve the performance of nginx TTFB? No one would use docker for nginx+php-fpm if this is the expected behavior so I know this is user error.
Edit: I've created a repo you can see all files and try for yourself. The numbers on TTFB will be slightly different than the app I'm referring to, but issue still exists, See CI Docker Test Repo.
This is my docker-compose.yml:
version: "3"
services:
nginx:
image: nginx
build:
dockerfile: Dockerfile
context: ./server/nginx
ports:
- 80:80
- 443:443
volumes:
- ./app:/var/www/html
- ./uploads:/var/www/uploads
networks:
- www
php:
user: "${userid}:${groupid}"
image: php:7.3-fpm
build:
dockerfile: Dockerfile
context: ./server/php-fpm
env_file:
- server/php-fpm/env/my.env
environment:
XDEBUG_CONFIG: remote_host=${ipaddr}
CI_ENV: development
volumes:
- ./app:/var/www/html
- ./uploads:/var/www/uploads
networks:
- www
networks:
www:
Issue solved (I'll leave up in case anyone else runs into this)
I've been starting docker using this command:
userid=$(id -u) groupid=$(id -g) ipaddr=$(ip route get 8.8.8.8 | awk '{print $NF; exit}') docker-compose up --build
In docker-compose.yml in the php container you see XDEBUG_CONFIG: remote_host=${ipaddr}
The problem was, ip route get 8.8.8.8 | awk '{print $NF; exit}'
does not return the ip on all systems. So xdebug was getting the incorrect ip address, which in turn was causing a syscall that was causing the latency. Once I sent in the correct ip address to xdebug, all was well.
I adjusted my up
command to simply pass in the ip rather than trying to pass in a dynamic lookup, since it is different on every system. Now latency is gone.
userid=$(id -u) groupid=$(id -g) ipaddr=$(myipaddress) docker-compose up --build
TTFB running nginx+php-fpm in docker 1.23 seconds:
TTFB bare metal not in docker:
php script timer running php-fpm on docker container:
php script timer running php-fpm on bare metal (not in docker)