Score:0

PHP-FPM Docker container behaves differently regarding engine (docker-compose vs Swarm)

fr flag

one PHP-FPM container (7.2), member of classical LAPP stack, correctly exposes port 9000 when launched with docker-compose but nothing when started by Docker Swarm. Should I mention that container is running (see output below) and I can launch a TTY bash on it.

So with docker-compose, web application is fully functionnal, but with Swarm, Apache issues a 503 Service Unavailable. Nothing is changed between tests with different engines. Do you have any clue about this behaviour ?

docker-compose.yml

version: '3.5'
services:
  postgres:
    env_file: ./.env
    image: "postgres:9.5.24"
    volumes:
      - database:/var/lib/postgresql/data
    networks:
      - internal

  adminer:
    image: adminer
    networks:
      - internal
      - traefik-public
    deploy:
      labels:
        - "traefik.enable=true"
        - "traefik.http.routers.adminer.rule=Host(`adminer.example.com`)"
        - "traefik.http.routers.adminer.entrypoints=websecure"
        - "traefik.http.routers.adminer.tls.certresolver=letsencryptresolver"
        - "traefik.http.services.adminer.loadbalancer.server.port=8080"
        - "traefik.port=80"

  apache:
    env_file: ./.env
    image: visio_rdv_apache:latest
    build:
      context: docker/images/apache2.4
      dockerfile: Dockerfile
      args:
        UID: ${HOST_UID}
        ROOT_URL: ${ROOT_URL}
    ports:
      - 8000:80
    environment:
      FPM_HOST: php:9000
      ROOT_URL: ${ROOT_URL}
    volumes:
      - ${LOGS_DIR}/apache/:/var/log/httpd/
      - ${RELATIVE_APP_PATH}:/var/www/html      
    links:
      - postgres
      - php

    networks:
      - internal
      - traefik-public
    deploy:
      labels:
        - "traefik.enable=true"
        - "traefik.http.routers.visio_rdv.rule=Host(`test.example.com`)"
        - "traefik.http.routers.visio_rdv.entrypoints=websecure"
        - "traefik.http.routers.visio_rdv.tls.certresolver=letsencryptresolver"
        - "traefik.http.services.visio_rdv.loadbalancer.server.port=80"
        - "traefik.port=80"

  php:
    env_file: .env
    links:
      - ftp
    image: visio_rdv_php:latest
    build:
      context: docker/images/php
      dockerfile: Dockerfile
      args:
        UID: ${HOST_UID}
        TIMEZONE: ${TIMEZONE}
        PROXY: ${http_proxy}
    volumes:
      - ftp_data:/var/www/ftp:rw
      - ${RELATIVE_APP_PATH}:/var/www/html      
    networks:
      - internal

  ftp:
    env_file: .env
    image: "fauria/vsftpd:latest"
    ports:
      - "9520:20"
      - "9521:21"
      - "21100-21110:21100-21110"
    environment:
      FTP_USER: ${FTP_USER}
      FTP_PASS: ${FTP_PASS}      
      PASV_MIN_PORT: 21100
      PASV_MAX_PORT: 21100
    volumes:
      - ftp_data:/home/vsftpd/${AUTOMATION_CLIENT_NAME}:rw
    networks:
      - internal

volumes:
  ftp_data:
  database:

networks:
  traefik-public:
    external: true
  internal:
    external: false

With Docker Swarm

Apache logs :

[Wed Aug 04 07:35:16.382246 2021] [proxy:error] [pid 11] (111)Connection refused: AH00957: FCGI: attempt to connect to 10.0.4.93:9000 (*) failed
[Wed Aug 04 07:35:16.382314 2021] [proxy_fcgi:error] [pid 11] [client 10.0.0.2:1035] AH01079: failed to make connection to backend: php, referer: http://test.example.com/

Swarm services list :

docker service ls
ID             NAME                    MODE         REPLICAS   IMAGE                          PORTS
um2txtpz8534   traefik_reverse-proxy  replicated   1/1        traefik:v2.4                   
ahf7uukapxbr   my_stack_adminer       replicated   1/1        adminer:latest                 
ue8qekmg0ff0   my_stack_apache        replicated   1/1        my_stack_apache:latest       my_stack*:8000->80/tcp
x9igaslhsx11   my_stack_ftp           replicated   1/1        fauria/vsftpd:latest          *:9520-9521->20-21/tcp, *:21100-21110->21100-21110/tcp
jpk4qzqs1tfx   my_stack_php           replicated   1/1        my_stack_php:latest           
ih67rh82vp9e   my_stack_postgres      replicated   1/1        postgres:9.5.24    

I tried to add net-tools to the PHP image, in order to manually test the connection with nc. Same result, php container instance IP is correctly resolved, but any TCP connection to port 9000 is refused.

I use a lot environment vars, and in order to palliate missing feature with Swarm, I use the docker-compose config command output to generate complete docker-compose.yml file.

With docker-compose

         Name                        Command               State                                                                       Ports                                                                    
---------------------------------------------
my_stack_adminer_1    entrypoint.sh docker-php-e ...   Up      8080/tcp                                                                                                                                     
my_stack_apache_1     /bin/sh -c apachectl -D FO ...   Up      0.0.0.0:8000->80/tcp                                                                                                                         
my_stack_ftp_1        /usr/sbin/run-vsftpd.sh          Up      0.0.0.0:9520->20/tcp, 0.0.0.0:9521->21/tcp, 0.0.0.0:21100->21100/tcp, 0.0.0.0:21101->21101/tcp, 0.0.0.0:21102->21102/tcp,                    
                                                                   0.0.0.0:21103->21103/tcp, 0.0.0.0:21104->21104/tcp, 0.0.0.0:21105->21105/tcp, 0.0.0.0:21106->21106/tcp, 0.0.0.0:21107->21107/tcp,            
                                                                   0.0.0.0:21108->21108/tcp, 0.0.0.0:21109->21109/tcp, 0.0.0.0:21110->21110/tcp                                                                 
my_stack_php_1        php-fpm -R -F                    Up      9000/tcp                                                                                                                                     
my_stack_postgres_1   docker-entrypoint.sh postgres    Up      5432/tcp 
Score:0
in flag
  1. How did you make the build?

Swarm is unlike docker-compose: "a deploy is a deploy" - and NOT a build! (you need to build the images before you deploy them - and the (probably available) compose ones' might not meet the requirements...)

With:

docker stack deploy -c your-compose-style-code.yml <name-of-your-swarm>

you are deploying an existing image into the selected swarm (it likely uses those you did build via docker-compose before...

... another subject in swarm is networking: you need to be aware of the networking scopes (cluster or swarm wide overlay - or scope of an "internal" network to connect selected services of a "namespace" the way you do it in compose...)

... and then, of course, the volumes for the stateful-parts (databases, files the users might upload) need to be managed in a different way (from NFS to glusterFS to Galera to linbit/LINSTOR ... or cockroachDB just to name some ...), since the containers of your stateless parts of the orchestra are now distributed on many different nodes..

  1. Sometimes adding "portainer" to your swarm is a good idea https://www.portainer.io/solutions/docker ...
mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.