Skip to content

Conversation

@barw4
Copy link
Collaborator

@barw4 barw4 commented Oct 29, 2025

🎫 Issue IBX-10764

Related PRs:

ibexa/core#672
ibexa/recipes-dev#222

Description:

Overview

UpsunEnvVarLoader parses Upsun environment variables (PLATFORM_RELATIONSHIPS, PLATFORM_ROUTES) and exposes them as env vars for Ibexa application.

Env Vars Generation

1. Database (MySQL/PostgreSQL)

Logic: Iterates over mysql* and pgsql* schemes (uses str_starts_with for HA support like mysql-replica)

Generated variables:

  • {RELATIONSHIP_NAME}_URL - full URL with charset and serverVersion
  • {RELATIONSHIP_NAME}_USER
  • {RELATIONSHIP_NAME}_USERNAME
  • {RELATIONSHIP_NAME}_PASSWORD
  • {RELATIONSHIP_NAME}_HOST
  • {RELATIONSHIP_NAME}_PORT
  • {RELATIONSHIP_NAME}_NAME
  • {RELATIONSHIP_NAME}_DATABASE
  • {RELATIONSHIP_NAME}_DRIVER
  • {RELATIONSHIP_NAME}_SERVER

Example: Relationship databaseDATABASE_URL, DATABASE_HOST, etc.


2. DFS Database

Logic:

  1. dfs_database relationship gets the SAME treatment as any other database via buildDatabaseEnvVars (full URL with charset, serverVersion, etc.)
  2. ADDITIONALLY, if PLATFORMSH_DFS_NFS_PATH is set, buildDfsEnvVars adds DFS-specific variables

Condition for DFS-specific vars: Only when $_SERVER['PLATFORMSH_DFS_NFS_PATH'] is set

Standard database variables (from buildDatabaseEnvVars):

  • DFS_DATABASE_URL - full URL with charset and serverVersion
  • DFS_DATABASE_HOST
  • DFS_DATABASE_PORT
  • DFS_DATABASE_USER
  • DFS_DATABASE_USERNAME
  • DFS_DATABASE_PASSWORD
  • DFS_DATABASE_NAME
  • DFS_DATABASE_DATABASE
  • DFS_DATABASE_DRIVER
  • DFS_DATABASE_SERVER

DFS-specific variables (from buildDfsEnvVars, only when NFS path is set):

  • DFS_NFS_PATH
  • DFS_DATABASE_CHARSET
  • DFS_DATABASE_COLLATION
  • DFS_DATABASE_DRIVER (PDO driver format, e.g., pdo_mysql)

3. Cache (Redis/Memcached)

Priority: Redis ALWAYS before Memcached (regardless of array order)

Logic:

  1. First process all Redis endpoints
  2. Then process Memcached (only as fallback for CACHE_POOL)

Generated variables per endpoint:

  • {RELATIONSHIP_NAME}_URL (Redis only)
  • {RELATIONSHIP_NAME}_HOST
  • {RELATIONSHIP_NAME}_PORT
  • {RELATIONSHIP_NAME}_SCHEME (Redis only)

Global variables (first found):

  • CACHE_POOL - cache.redis or cache.memcached
  • CACHE_DSN

4. Session (Redis)

Priority:

  1. First looks for relationship named redissession (dedicated Redis for sessions)
  2. Fallback - first Redis found by scheme (any name: rediscache, myredis, etc.)

Generated variables:

  • SESSION_HANDLER_ID - NativeSessionHandler class
  • SESSION_SAVE_PATH - host:port

5. Search (Solr/Elasticsearch)

Solr logic: Checks $endpoint['scheme'] === 'solr'

Elasticsearch logic: Checks $endpoint['rel'] === 'elasticsearch' (NOT scheme, because ES uses http/https)

Solr generated variables:

  • SEARCH_ENGINE = solr
  • SOLR_DSN
  • SOLR_CORE
  • {RELATIONSHIP_NAME}_HOST
  • {RELATIONSHIP_NAME}_PORT
  • {RELATIONSHIP_NAME}_NAME
  • {RELATIONSHIP_NAME}_DATABASE

Elasticsearch generated variables:

  • SEARCH_ENGINE = elasticsearch
  • ELASTICSEARCH_DSN
  • {RELATIONSHIP_NAME}_URL
  • {RELATIONSHIP_NAME}_HOST
  • {RELATIONSHIP_NAME}_PORT
  • {RELATIONSHIP_NAME}_SCHEME

6. Varnish (HTTP Cache)

Logic: Looks for route with type: upstream and upstream: varnish, prefers primary: true

Generated variables:

  • HTTPCACHE_PURGE_TYPE = varnish
  • HTTPCACHE_PURGE_SERVER
  • HTTPCACHE_VARNISH_INVALIDATE_TOKEN

Summary: When we use relationship name vs scheme

Service Identification method Notes
Database Scheme (mysql*, pgsql*) str_starts_with for HA
DFS Relationship name (dfs_database) Within mysql/pgsql schemes
Redis/Memcached Scheme (redis, memcached) Redis always first
Session Name (redissession) + scheme fallback Dedicated redis preferred
Solr Scheme (solr) -
Elasticsearch rel field (elasticsearch) NOT scheme (uses http/https)
Varnish Route config type: upstream, upstream: varnish

Relationship naming conventions

Recommended names (but not required, except for special cases):

  • database - main database
  • dfs_database - DFS database (this name is required)
  • rediscache - Redis for cache
  • redissession - Redis for sessions (this name is preferred for dedicated instance)
  • elasticsearch - Elasticsearch
  • solr - Solr

Developers can use any relationship names - env vars will be generated with a prefix matching the relationship name (uppercase, -_).

For QA:

Documentation:

@barw4 barw4 self-assigned this Oct 29, 2025
@barw4 barw4 force-pushed the ibx-10764-upsun-env-loader branch from effd671 to fa2b4cb Compare October 29, 2025 20:47
@barw4 barw4 marked this pull request as ready for review December 8, 2025 09:24
@barw4 barw4 changed the title IBX-10764: Upsun env var loader IBX-10764: Extracted Upsun environmental variables Dec 8, 2025
Copy link

@konradoboza konradoboza left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we have at least logging when configuration contains errors? I assume exceptions on build/deploy will be rather annoying.

I'm also missing some unhappy path testing a bit, but this is related to the remark above.

Comment on lines +286 to +287
foreach ($groupedRelationships['redis'] as $endpoints) {
foreach ($endpoints as $endpoint) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why nested foreach if we return an array in the first iteration?

Copy link
Collaborator Author

@barw4 barw4 Dec 8, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure I follow you here, nested foreach is here to return first endpoint under a given relationship's scheme, in this case redis. Am I missing something?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks weird at first glance that you iterate in two loops just to return the first element. If we cannot do it differently ($array[0]) then fine.

/**
* @param array<string, mixed> $route
*/
private function isVarnishRoute(array $route): bool

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is Fastly handled at all here?

Copy link
Collaborator Author

@barw4 barw4 Dec 8, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Http cache is handled by exactly the same way as in the current core solution: https://github.com/ibexa/core/pull/672/files#diff-0bc93691994620e932aa9941baa089094640bca3da1275b5073f74d5e9b71d16L952

@barw4
Copy link
Collaborator Author

barw4 commented Dec 8, 2025

Can we have at least logging when configuration contains errors? I assume exceptions on build/deploy will be rather annoying.

I'm also missing some unhappy path testing a bit, but this is related to the remark above.

@konradoboza I'm not quite sure I understand. What kind of logging or maybe at which point in time do you wish to see such logging to be done?

If configuration contains errors then build hook will crash which is completely expected. The loader presented in this PR doesn't inject itself into build hook, it's active during runtime.

@barw4 barw4 requested a review from konradoboza December 8, 2025 14:06
@konradoboza
Copy link

konradoboza commented Dec 8, 2025

Ok, just wanted to suggest some way to report misconfigurations. If the build hook fails with proper info, I am fine with that.

@barw4
Copy link
Collaborator Author

barw4 commented Dec 8, 2025

Ok, just wanted to suggest some way to report misconfigurations. If the build hook fails with proper info, I am fine with that.

I'm not aware of any way to report broken configuration, if the configuration is broken the build will simply fail on Upsun side and they provide us with build logs :)

@konradoboza
Copy link

@barw4 please add permissions for ibexa/cloud repository to PHP Team.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Feature New feature request Ready for QA

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants