'Api-platform docker deployment behind nginx-proxy

I'm trying to deploy a quick demo of api-platform. In advance, my apologize if I missed something in a discssion or a documentation, I'm not used to work on deployment and maybe not looking at the right places.

I use a server where I already have some docker containers running, for that I use nginxproxy/nginx-proxy docker container as reverse proxy. I looked at the api-platofrm documentation on how to deploy with docker-compose : https://api-platform.com/docs/deployment/docker-compose/#deploying but since I'm working on this subject I evolve between "502 bad gateway" or "The page is not redirected correctly" errors.

Actually I've got this docker-compose.yml :

version: "3.4"

services:
  php:
    build:
      context: ./api
      target: api_platform_php
    depends_on:
      - database
    restart: unless-stopped
    volumes:
      - php_socket:/var/run/php
    healthcheck:
      interval: 10s
      timeout: 3s
      retries: 3
      start_period: 30s
    networks:
      - 'cloud'

  caddy:
    build:
      context: api/
      target: api_platform_caddy
    depends_on:
      - php
    environment:
      PWA_UPSTREAM: pwa:3000
      SERVER_NAME: ${SERVER_NAME:-localhost, caddy:80}
      MERCURE_PUBLISHER_JWT_KEY: ${MERCURE_PUBLISHER_JWT_KEY:-!ChangeMe!}
      MERCURE_SUBSCRIBER_JWT_KEY: ${MERCURE_SUBSCRIBER_JWT_KEY:-!ChangeMe!}
    restart: unless-stopped
    volumes:
      - php_socket:/var/run/php
      - caddy_data:/data
      - caddy_config:/config
    ports:
      # HTTP
      - target: 80
        published: 7000
        protocol: tcp
      # HTTPS
      - target: 443
        published: 7001
        protocol: tcp
      # HTTP/3
      - target: 443
        published: 7001
        protocol: udp
    networks:
      - 'cloud'

  database:
    image: postgres:13-alpine
    environment:
      - POSTGRES_DB=api
      - POSTGRES_PASSWORD=!ChangeMe!
      - POSTGRES_USER=api-platform
    volumes:
      - db_data:/var/lib/postgresql/data:rw
      # you may use a bind-mounted host directory instead, so that it is harder to accidentally remove the volume and lose all your data!
      # - ./api/docker/db/data:/var/lib/postgresql/data:rw
    networks:
      - 'cloud'

volumes:
  php_socket:
  db_data:
  caddy_data:
  caddy_config:


networks:
  cloud:
    external: true

and this docker-compose.preprod.yml file :

version: "3.4"

# Preproduction environment override
services:
  php:
    environment:
      APP_ENV: prod
      APP_SECRET: ${APP_SECRET}

  caddy:
    environment:
      MERCURE_PUBLISHER_JWT_KEY: ${MERCURE_PUBLISHER_JWT_KEY:-!ChangeMe!}
      MERCURE_SUBSCRIBER_JWT_KEY: ${MERCURE_SUBSCRIBER_JWT_KEY:-!ChangeMe!}
      VIRTUAL_HOST: api-preprod.melofeel.com
      VIRTUAL_PORT: 80
      LETSENCRYPT_HOST: api-preprod.melofeel.com

I'm deploying it with gitlab-ci and launching it with this command : SERVER_NAME=******.*****.com APP_SECRET=testdeploy POSTGRES_PASSWORD=testdeploy CADDY_MERCURE_JWT_SECRET=testdeploy docker-compose -f api_preprod/docker-compose.yml -f api_preprod/docker-compose.preprod.yml up -d

I've tried to run it with and without Caddy, without I always get "502 bad gateway".

The 3 containers are running, but when I look on Caddy logs I've got this messages :

{"level":"error","ts":1648201680.3190682,"logger":"tls.issuance.acme.acme_client","msg":"challenge failed","identifier":"*****.*****.com","challenge_type":"http-01","problem":{"type":"urn:ietf:params:acme:error:unauthorized","title":"","detail":"Invalid response from http://*****.*****.com/.well-known/acme-challenge/O9zJRdytI8vlf7yZLRcV9pzUlmI73ysCqQJTHg8XWTw [188.165.218.39]: 404","instance":"","subproblems":[]}}

I've tried to deactivate the automatic https from caddy, nginx-proxy is already responsible for doing it, but it's seems to not work. My Caddyfile :

{
    # Debug
    {$DEBUG}
    # HTTP/3 support
    servers {
        protocol {
            experimental_http3
        },
        auto_https disable_redirects
    }
}

{$SERVER_NAME}

log

# Matches requests for HTML documents, for static files and for Next.js files,
# except for known API paths and paths with extensions handled by API Platform
@pwa expression `(
        {header.Accept}.matches("\\btext/html\\b")
        && !{path}.matches("(?i)(?:^/docs|^/graphql|^/bundles/|^/_profiler|^/_wdt|\\.(?:json|html$|csv$|ya?ml$|xml$))")
    )
    || {path} == "/favicon.ico"
    || {path} == "/manifest.json"
    || {path} == "/robots.txt"
    || {path}.startsWith("/_next")
    || {path}.startsWith("/sitemap")`

route {
    root * /srv/api/public
    mercure {
        # Transport to use (default to Bolt)
        transport_url {$MERCURE_TRANSPORT_URL:bolt:///data/mercure.db}
        # Publisher JWT key
        publisher_jwt {env.MERCURE_PUBLISHER_JWT_KEY} {env.MERCURE_PUBLISHER_JWT_ALG}
        # Subscriber JWT key
        subscriber_jwt {env.MERCURE_SUBSCRIBER_JWT_KEY} {env.MERCURE_SUBSCRIBER_JWT_ALG}
        # Allow anonymous subscribers (double-check that it's what you want)
        anonymous
        # Enable the subscription API (double-check that it's what you want)
        subscriptions
        # Extra directives
        {$MERCURE_EXTRA_DIRECTIVES}
    }
    vulcain
    push

    # Add links to the API docs and to the Mercure Hub if not set explicitly (e.g. the PWA)
    header ?Link `</docs.jsonld>; rel="http://www.w3.org/ns/hydra/core#apiDocumentation", </.well-known/mercure>; rel="mercure"`

    # Comment the following line if you don't want Next.js to catch requests for HTML documents.
    # In this case, they will be handled by the PHP app.
    reverse_proxy @pwa http://{$PWA_UPSTREAM}

    php_fastcgi unix//var/run/php/php-fpm.sock
    encode zstd gzip
    file_server
}

Thanks in advance for any help and explanation that allow me to understand what the problem is.



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source