-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Description
Summary
When deploying Krayin CRM using a custom Docker image (based on php:8.2-apache), the installation wizard completes all steps successfully, including database migration and admin user creation. However, upon completion, the application fails to recognize that it is installed and immediately redirects all traffic back to the /install page, creating an infinite loop.
This loop persists even after exhausting all possible file permission fixes, including using chmod -R 777 on the storage directory and even mounting the storage directory as an in-memory tmpfs volume to rule out any host-level filesystem issues.
This suggests a potential bug in the installer's finalization step where it fails to create the storage/installed flag file under specific containerized conditions.
Steps to Reproduce
Set up a project with the Dockerfile, docker-compose.yml, start.sh, and apache.conf files provided below.
Download the latest Krayin CRM source code and extract it into a ./krayin-src subdirectory.
Build the Docker image: docker build -t krayin-custom:latest .
Deploy the stack using docker stack deploy -c docker-compose.yml krayincrm.
Navigate to the installation URL (e.g., https://your-domain.com/install).
Complete all steps of the installation wizard. The logs will show all API POST requests completing with a 200 OK status.
The final screen will show "Installation Completed."
Click the "Admin Panel" button.
Expected Behavior
The user should be redirected to the /admin/login page and be able to log in. Subsequent visits to the site should not redirect to the installer.
Actual Behavior
After clicking "Admin Panel," the user is redirected back to the /install page. Any attempt to access the site results in this redirect.
Environment Details
Deployment: Docker Swarm
Proxy: Traefik v2 (handling SSL termination)
Base Image: php:8.2-apache
Database: percona/percona-server:latest
Krayin Version: Latest stable (downloaded Oct 3, 2025)
Reproducible Setup Files
Dockerfile
Dockerfile
1. Usar una imagen base oficial de PHP con Apache
FROM php:8.2-apache
2. Instalar dependencias del sistema
RUN apt-get update && apt-get install -y
git
unzip
zip
libzip-dev
libpng-dev
libicu-dev
&& rm -rf /var/lib/apt/lists/*
3. Instalar las extensiones de PHP que Krayin necesita
RUN docker-php-ext-install pdo_mysql bcmath gd zip intl calendar
4. Instalar Composer
COPY --from=composer:latest /usr/bin/composer /usr/bin/composer
5. Copiar el código base de Krayin a la imagen
COPY ./krayin-src/ /var/www/html/
6. Copiar la configuración de Apache y activar mod_rewrite
COPY apache.conf /etc/apache2/sites-available/000-default.conf
RUN a2enmod rewrite
7. Establecer el directorio de trabajo
WORKDIR /var/w ww/html
8. Instalar las dependencias de Krayin y la extensión de Google
RUN composer install --no-dev --optimize-autoloader --no-interaction
RUN composer require krayin/krayin-google-integration --no-interaction
9. Publicar los recursos y limpiar cachés
RUN php artisan vendor:publish --provider="Krayin\Google\Providers\GoogleServiceProvider" --force
RUN php artisan optimize:clear
10. Hacer el cambio para TrustProxies permanente
RUN sed -i "s/protected $proxies;/protected $proxies = '*';/" app/Http/Middleware/TrustProxies.php
11. Copiar nuestro script de inicio y hacerlo ejecutable
COPY start.sh /usr/local/bin/start.sh
RUN chmod +x /usr/local/bin/start.sh
12. Establecer el script de inicio como el comando por defecto del contenedor
CMD ["/usr/local/bin/start.sh"]
start.sh
Bash
#!/bin/sh
set -e
Use the most aggressive permission setting on the storage and cache folders.
chmod -R 777 /var/www/html/storage
chmod -R 777 /var/www/html/bootstrap/cache
Fix ownership of all files.
chown -R www-data:www-data /var/www/html
Execute the main container command (start Apache).
exec apache2-foreground
docker-compose.yml (Final diagnostic version)
YAML
version: "3.7"
services:
krayincrm_app:
image: krayin-custom:latest # Use the image you just built
volumes:
- krayincrm_data:/var/www/html/
tmpfs: # Using tmpfs to rule out host volume permission issues
- /var/www/html/storage
networks:
- XXXXXX
environment:
- APP_URL=https://your-domain.com
- APP_ENV=development
- APP_DEBUG=true
# And all other necessary DB/Redis variables
# ...
# ... deploy labels for Traefik
apache.conf
Apache
<VirtualHost *:80>
DocumentRoot /var/www/html/public
<Directory /var/www/html/public>
AllowOverride All
Require all granted
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
Debugging Summary & Conclusion
The Apache access logs confirm that all POST requests to the installer API (/install/api/...) complete with a 200 OK status. The final step of the installer redirects to /admin/login, which is then immediately redirected back to /install by the CanInstall middleware.
This indicates that the check file_exists(storage_path('installed')) is failing.
We have definitively ruled out standard permissions issues by:
Running chown -R www-data:www-data on every container start.
Running chmod -R 777 on the storage and bootstrap/cache directories on every container start.
Crucially, using a tmpfs mount for the /var/www/html/storage directory.
The failure to write the installed file to an in-memory tmpfs volume with 777 permissions suggests the problem is not with the environment's permissions but with the application's finalization logic itself. It appears the installer is completing but silently failing to execute the final touch(storage_path('installed')) command.