diff --git a/examples/todo/symfony/src/Kernel.php b/examples/todo/symfony/src/Kernel.php index 4cf4eed..aa2adec 100644 --- a/examples/todo/symfony/src/Kernel.php +++ b/examples/todo/symfony/src/Kernel.php @@ -10,4 +10,16 @@ use Symfony\Component\HttpKernel\Kernel as BaseKernel; final class Kernel extends BaseKernel { use MicroKernelTrait; + + // The bundled-mode supervisor sets APP_CACHE_DIR / APP_LOG_DIR to writable + // paths under the user data dir; the AppImage mount is read-only. + public function getCacheDir(): string + { + return $_SERVER['APP_CACHE_DIR'] ?? parent::getCacheDir(); + } + + public function getLogDir(): string + { + return $_SERVER['APP_LOG_DIR'] ?? parent::getLogDir(); + } } diff --git a/framework/qml/src/BackendConnection.cpp b/framework/qml/src/BackendConnection.cpp index 4be825c..cf5bac1 100644 --- a/framework/qml/src/BackendConnection.cpp +++ b/framework/qml/src/BackendConnection.cpp @@ -204,11 +204,20 @@ bool BackendConnection::runMigrations() QStringLiteral("-n"), }); + // AppImage mount is read-only; redirect Symfony's writable dirs into the + // user data dir (Kernel::getCacheDir/getLogDir read these env vars). + const QString cacheDir = m_dataDir + QStringLiteral("/var/cache"); + const QString logDir = m_dataDir + QStringLiteral("/var/log"); + QDir().mkpath(cacheDir); + QDir().mkpath(logDir); + QProcessEnvironment env = QProcessEnvironment::systemEnvironment(); - env.insert(QStringLiteral("APP_ENV"), QStringLiteral("prod")); - env.insert(QStringLiteral("APP_DEBUG"), QStringLiteral("0")); - env.insert(QStringLiteral("APP_SECRET"), QStringLiteral("bundled-mode-migrations-do-not-need-this")); - env.insert(QStringLiteral("DATABASE_URL"), databaseUrl()); + env.insert(QStringLiteral("APP_ENV"), QStringLiteral("prod")); + env.insert(QStringLiteral("APP_DEBUG"), QStringLiteral("0")); + env.insert(QStringLiteral("APP_SECRET"), QStringLiteral("bundled-mode-migrations-do-not-need-this")); + env.insert(QStringLiteral("DATABASE_URL"), databaseUrl()); + env.insert(QStringLiteral("APP_CACHE_DIR"), cacheDir); + env.insert(QStringLiteral("APP_LOG_DIR"), logDir); proc.setProcessEnvironment(env); proc.setWorkingDirectory(resolveSymfonyDir()); proc.setProcessChannelMode(QProcess::MergedChannels); @@ -249,12 +258,21 @@ bool BackendConnection::spawnChild(QString* errorOut) }); m_child->setWorkingDirectory(resolveSymfonyDir()); + // AppImage mount is read-only; redirect Symfony's writable dirs into the + // user data dir (Kernel::getCacheDir/getLogDir read these env vars). + const QString cacheDir = m_dataDir + QStringLiteral("/var/cache"); + const QString logDir = m_dataDir + QStringLiteral("/var/log"); + QDir().mkpath(cacheDir); + QDir().mkpath(logDir); + QProcessEnvironment env = QProcessEnvironment::systemEnvironment(); env.insert(QStringLiteral("APP_ENV"), QStringLiteral("prod")); env.insert(QStringLiteral("APP_DEBUG"), QStringLiteral("0")); env.insert(QStringLiteral("APP_SECRET"), randomSecret(16)); env.insert(QStringLiteral("BRIDGE_TOKEN"), m_token); env.insert(QStringLiteral("DATABASE_URL"), databaseUrl()); + env.insert(QStringLiteral("APP_CACHE_DIR"), cacheDir); + env.insert(QStringLiteral("APP_LOG_DIR"), logDir); env.insert(QStringLiteral("PORT"), QString::number(m_port)); env.insert(QStringLiteral("MERCURE_URL"), m_url + QStringLiteral("/.well-known/mercure")); env.insert(QStringLiteral("MERCURE_PUBLIC_URL"), m_url + QStringLiteral("/.well-known/mercure")); diff --git a/framework/skeleton/symfony/src/Kernel.php b/framework/skeleton/symfony/src/Kernel.php index 4cf4eed..aa2adec 100644 --- a/framework/skeleton/symfony/src/Kernel.php +++ b/framework/skeleton/symfony/src/Kernel.php @@ -10,4 +10,16 @@ use Symfony\Component\HttpKernel\Kernel as BaseKernel; final class Kernel extends BaseKernel { use MicroKernelTrait; + + // The bundled-mode supervisor sets APP_CACHE_DIR / APP_LOG_DIR to writable + // paths under the user data dir; the AppImage mount is read-only. + public function getCacheDir(): string + { + return $_SERVER['APP_CACHE_DIR'] ?? parent::getCacheDir(); + } + + public function getLogDir(): string + { + return $_SERVER['APP_LOG_DIR'] ?? parent::getLogDir(); + } }