dunglas / mercure

🪽 An open, easy, fast, reliable and battery-efficient solution for real-time communications
https://mercure.rocks
GNU Affero General Public License v3.0
3.98k stars 297 forks source link

Failing to get Mercure Hub up and running in Platform.sh #940

Closed dayton-outar closed 3 months ago

dayton-outar commented 3 months ago

I have the following applications.yaml configured in a Symfony app,

api:
  type: php:8.1
  runtime:
      extensions:
          - apcu
          - mbstring
          - sodium
          - ctype
          - iconv
          - pdo_pgsql

  # Relationships enable an app container's access to a service.
  relationships:
      database: "database:postgresql"
      mercure: "mercure:http"

  build:
      flavor: none

  disk: 512

  web:
      locations:
          '/':
              root: "public"
              expires: 1h
              passthru: "/index.php"
              headers:
                  Access-Control-Allow-Origin: "*"
  mounts:
      '/var': { source: local, source_path: var }

  hooks:
      build: |
          set -x -e
          curl -fs https://get.symfony.com/cloud/configurator | bash

          NODE_VERSION=18 symfony-build

      deploy: |
          set -x -e

          symfony-deploy

mercure:
  type: golang:1.22
  build:
      flavor: 'none'
  disk: 1024
  variables:
    env:
      MERCUREVERSION: v0.16.2
      MERCURE_TRANSPORT_URL: 'bolt://database/mercure.db'
      MERCURE_PUBLISHER_JWT_KEY: '!ChangeThisMercureHubJWTSecretKey!'
      # MERCURE_PUBLISHER_JWT_ALG: 'HS256'
      MERCURE_SUBSCRIBER_JWT_KEY: '!ChangeThisMercureHubJWTSecretKey!'
      # MERCURE_SUBSCRIBER_JWT_ALG: 'HS256'
      MERCURE_EXTRA_DIRECTIVES: |
        # Allow all CORS origins
        cors_origins *
        # Allow all publishers
        publish_origins *
        # Enable the subscription endpoint (default is enabled)
        subscriptions
        # Enable the publishing endpoint (default is enabled)
        publish
        # Enable UI
        ui
  web:
    commands:
      start: ./mercure run

    locations:
      /:
        passthru: true
        scripts: false
        request_buffering:
          enabled: false
        headers:
          Access-Control-Allow-Origin: '*'

  mounts:
    'database': { source: local, source_path: 'database' }
    '/.local': { source: local, source_path: '.local' }
    '/.config': { source: local, source_path: '.config' }

  hooks:
    build: ./mercure.sh

The mercure binary downloads but when it is run, I get the following error,

Error: loading initial config: loading new config: loading http app module: provision http: server srv0: setting up route handlers: route 0: loading handler modules: position 0: loading module 'subroute': provision http.handlers.subroute: setting up subroutes: route 4: loading handler modules: position 1: loading module 'mercure': provision http.handlers.mercure: "bolt://database/mercure.db?subscriptions=1": invalid transport: open /mercure.db: read-only file system

I've created a mount that should be writable. I'm not sure what I have not configured right

dayton-outar commented 3 months ago

I've got around the read-only issue concerning the bolt database by doing a number of things. Here they are:

  1. Turned off auto_https. Caddy is not the gateway to the internet, it sits within an environment that platform.sh has to navigate to via nginx
  2. I used MERCURE_TRANSPORT_URL: 'bolt:///var/run/mercure.db' instead of the the default transport_url, the var/run path seems to be writable

Here's the resulting applications.yaml,

api:
  type: php:8.1
  runtime:
      extensions:
          - apcu
          - mbstring
          - sodium
          - ctype
          - iconv
          - pdo_pgsql

  # Relationships enable an app container's access to a service.
  relationships:
      database: "database:postgresql"
      mercure: "mercure:http"

  build:
      flavor: none

  disk: 512

  web:
      locations:
          '/':
              root: "public"
              expires: 1h
              passthru: "/index.php"
              headers:
                  Access-Control-Allow-Origin: "*"

  mounts:
      '/var': { source: local, source_path: var }

  hooks:
      build: |
          set -x -e
          curl -fs https://get.symfony.com/cloud/configurator | bash

          NODE_VERSION=18 symfony-build

      deploy: |
          set -x -e

          symfony-deploy

mercure:
  type: golang:1.22

  build:
      flavor: 'none'

  disk: 1024

  variables:
    env:
      PORT: '3000'
      SERVER_NAME: 'localhost:3000'
      MERCURE_TRANSPORT_URL: 'bolt:///var/run/mercure.db'
      MERCURE_PUBLISHER_JWT_KEY: '!ChangeThisMercureHubJWTSecretKey!'
      MERCURE_SUBSCRIBER_JWT_KEY: '!ChangeThisMercureHubJWTSecretKey!'
      GLOBAL_OPTIONS: |
        auto_https off
        admin off
      MERCURE_EXTRA_DIRECTIVES: |
        # Allow all CORS origins
        cors_origins *
        # Allow all publishers
        publish_origins *
        # Enable the subscription endpoint (default is enabled)
        subscriptions
        # Enable the publishing endpoint (default is enabled)
        publish
        # Enable UI
        ui
      CADDY_SERVER_EXTRA_DIRECTIVES: |
        # Optional: Reverse proxy to a backend application (e.g., API or app)
        # reverse_proxy /api/* http://backend:8080 # But caddy is not the gateway, so we don't need this

        # Enable logging
        # log {
        #     output file /var/log/caddy/access.log {
        #         roll_size 5MiB
        #         roll_keep 10
        #         roll_keep_for 720h
        #     }
        # }

  web:
    commands:
      start: ./mercure run

    locations:
      /:
        proxy: 'http://localhost:3000'
        passthru: true
        scripts: false
        request_buffering:
          enabled: false
        headers:
          Access-Control-Allow-Origin: '*'

  mounts:
    'database': { source: local, source_path: 'database' }
    '/.local': { source: local, source_path: '.local' }
    '/.config': { source: local, source_path: '.config' }

  hooks:
    build: ./mercure.sh

The problem that I now have is a HTTP 502 error. Specifically, my project is configured such that mercure (or caddy) is not listening at the same place that nginx is set as stated in troubleshooting development (http responses 502 bad gateway).

Interestingly, ChatGPT suggest that I set the locations section in _applications.yaml` as follows,

locations:
            "/.well-known/mercure":
                proxy: "http://127.0.0.1:8081"  # Proxy to Mercure running on port 8081
                allow: true

However, when consulting [Upstream] reference on platform.sh docs, I see no provisions to perform such a configuration. In other words, this is not compilable and legal.

So, how do I get platform.sh to navigate to the port that mercure is running on. This is no longer a mercure issue but a platform.sh problem.

[Closing issue on mercure Github repo]