Invoice Ninja Installation on Coolify on a server different from localhost

Version

v5.10.60 (image: invoiceninja/invoiceninja:5 via Coolify)

Environment

Docker (via Coolify on remote VPS)

Checklist

  • Can you replicate the issue on our v5 demo site https://demo.invoiceninja.com or [https://react.invoicing.co/demo]?
    :cross_mark: Not applicable – issue is with self-hosted environment.
  • Have you searched existing issues?
    :white_check_mark: Yes
  • Have you inspected the logs in storage/logs/laravel.log for any errors?
    :cross_mark: Cannot access logs – container restarts before Invoice Ninja is fully booted.

Describe the bug

When deploying Invoice Ninja through Coolify on a remote VPS (i.e., an agent not marked as localhost), the container fails to start and enters a crash loop. Attempting to access the service URL results in a “Bad Gateway”, “404 Not Found”, or “No available server” error.

The container logs show the following repeated error:

Error: could not read config file /etc/supervisord.conf

This file is not part of the official Invoice Ninja image, and the image does not use supervisord by default.

Despite trying overrides or Docker Compose edits to add the missing file, the issue persists — only when deployed on a remote VPS via Coolify. The exact same deployment works when targeting the main Coolify server (localhost).

This suggests the issue may be related to how Coolify orchestrates services on remote agents, possibly expecting or injecting process management logic (supervisord) not present in the base image.

Steps To Reproduce

  1. Deploy Invoice Ninja (v5.10.60) via Coolify on a remote agent.
  2. Use the default Docker image and configuration.
  3. Start the app.
  4. Watch the container enter a restart loop.
  5. Try accessing the service — receive gateway or 404 errors.

Expected Behavior

Invoice Ninja should start properly and be accessible via the configured domain, without relying on a nonexistent supervisord.conf.

Additional context

  • Coolify is fully updated (June 2025).
  • Other apps like n8n, glance, etc. run correctly on the same remote VPS.
  • The “Predictify network” option in Coolify does not solve the issue. But make it possible for Invoice Ninja to be accessible by Coolify reverse proxy. But it still crash.
  • Manual container inspection of supervisord.conf impossible due to the restart.
  • The official Invoice Ninja image works fine outside of this Coolify remote server scenario.
  • I’ve tried even with other version (5.11.82 and other…)

Screenshots

Image 5.11.82

Image : 5

Docker compose in coolify

services:
  invoice-ninja:
    image: 'invoiceninja/invoiceninja:5'
    environment:
      - SERVICE_FQDN_INVOICENINJA
      - 'APP_NAME=${APP_NAME:-"Invoice Ninja"}'
      - 'APP_ENV=${APP_ENV:-production}'
      - 'APP_URL=${SERVICE_FQDN_INVOICENINJA}'
      - 'APP_KEY=base64:${SERVICE_REALBASE64_INVOICENINJA}'
      - 'APP_DEBUG=${APP_DEBUG:-false}'
      - 'REQUIRE_HTTPS=${REQUIRE_HTTPS:-false}'
      - 'PHANTOMJS_PDF_GENERATION=${PHANTOMJS_PDF_GENERATION:-false}'
      - 'PDF_GENERATOR=${PDF_GENERATOR:-hosted_ninja}'
      - 'TRUSTED_PROXIES=${TRUSTED_PROXIES:-*}'
      - CACHE_DRIVER=redis
      - 'QUEUE_CONNECTION=${QUEUE_CONNECTION:-redis}'
      - SESSION_DRIVER=redis
      - 'REDIS_HOST=${REDIS_HOST:-redis}'
      - 'REDIS_PASSWORD=${SERVICE_PASSWORD_REDIS}'
      - 'REDIS_PORT=${REDIS_PORT:-6379}'
      - 'DB_HOST=${DB_HOST:-mariadb}'
      - 'DB_PORT=${DB_PORT:-3306}'
      - 'DB_DATABASE=${DB_DATABASE:-invoiceninja}'
      - 'DB_USERNAME=${SERVICE_USER_MARIADB}'
      - 'DB_PASSWORD=${SERVICE_PASSWORD_MARIADB}'
      - 'IN_USER_EMAIL=${IN_USER_EMAIL:[email protected]}'
      - 'IN_PASSWORD=${SERVICE_PASSWORD_INVOICENINJAUSER}'
      - 'MAIL_MAILER=${MAIL_MAILER:-log}'
      - 'MAIL_HOST=${MAIL_HOST}'
      - 'MAIL_PORT=${MAIL_PORT}'
      - 'MAIL_USERNAME=${MAIL_USERNAME}'
      - 'MAIL_PASSWORD=${MAIL_PASSWORD}'
      - 'MAIL_ENCRYPTION=${MAIL_ENCRYPTION}'
      - 'MAIL_FROM_ADDRESS=${MAIL_FROM_ADDRESS}'
      - 'MAIL_FROM_NAME=${MAIL_FROM_NAME}'
      - 'AWS_ACCESS_KEY_ID=${AWS_ACCESS_KEY_ID}'
      - 'AWS_SECRET_ACCESS_KEY=${AWS_SECRET_ACCESS_KEY}'
      - 'AWS_DEFAULT_REGION=${AWS_DEFAULT_REGION}'
      - 'AWS_BUCKET=${AWS_BUCKET}'
      - 'AWS_URL=${AWS_URL}'
      - 'AWS_ENDPOINT=${AWS_ENDPOINT}'
      - 'NORDIGEN_SECRET_ID=${NORDIGEN_SECRET_ID}'
      - 'NORDIGEN_SECRET_KEY=${NORDIGEN_SECRET_KEY}'
      - IS_DOCKER=true
      - 'SCOUT_DRIVER=${SCOUT_DRIVER}'
      - 'LICENSE_KEY=${LICENSE_KEY}'
    healthcheck:
      test:
        - CMD
        - echo
        - ok
      interval: 5s
      timeout: 20s
      retries: 10
    volumes:
      - 'invoice-ninja-public:/var/www/app/public'
      - 'invoice-ninja-storage:/var/www/app/storage'
      -
        type: bind
        source: ./supervisord.conf
        target: /etc/supervisord.conf
        content: "[supervisord]\nnodaemon=true\npidfile=/tmp/supervisord.pid\nlogfile=/dev/null ; nodaemon will cause logs to go to stdout\nlogfile_maxbytes=0\nloglevel=info\n\n[program:php-fpm]\nredirect_stderr=true\nstdout_logfile=/dev/stdout\nstdout_logfile_maxbytes=0\nstderr_logfile=/dev/stderr\nstderr_logfile_maxbytes=0\ncommand=php artisan serve --host 0.0.0.0 --port 9000\n\n[program:scheduler]\nautorestart=true\nredirect_stderr=true\nstdout_logfile=/dev/stdout\nstdout_logfile_maxbytes=0\nstderr_logfile=/dev/stderr\nstderr_logfile_maxbytes=0\ncommand=php artisan schedule:work\n\n[program:queue-worker]\nprocess_name=%(program_name)s_%(process_num)02d\nautorestart=true\nredirect_stderr=true\nstdout_logfile=/dev/stdout\nstdout_logfile_maxbytes=0\nstderr_logfile=/dev/stderr\nstderr_logfile_maxbytes=0\nnumprocs=2\ncommand=php artisan queue:work --sleep=3 --tries=1 --memory=256 --timeout=3600\n\n[eventlistener:shutdown]\ncommand=shutdown.sh\nevents=PROCESS_STATE_STOPPED, PROCESS_STATE_EXITED, PROCESS_STATE_FATAL\nstdout_logfile=/dev/stdout\nstdout_logfile_maxbytes=0\nstderr_logfile=/dev/stderr\nstderr_logfile_maxbytes=0\n"
      -
        type: bind
        source: ./php.ini
        target: /usr/local/etc/php/php.ini
        content: "session.auto_start = Off\nshort_open_tag = Off\n\nerror_reporting = E_ALL & ~E_NOTICE & ~E_WARNING & ~E_STRICT & ~E_DEPRECATED\n\n; opcache.enable=1\n; opcache.preload=/srv/www/invoiceninja/current/preload.php\n; opcache.preload_user=www-data\n\n; ; The OPcache shared memory storage size.\n; opcache.max_accelerated_files=300000\n; opcache.validate_timestamps=1\n; opcache.revalidate_freq=30\n; opcache.jit_buffer_size=256M\n; opcache.jit=1205\n; opcache.memory_consumption=1024M\n\npost_max_size = 60M\nupload_max_filesize = 50M\nmemory_limit=512M\n"
      -
        type: bind
        source: ./php-cli.ini
        target: /usr/local/etc/php/php-cli.ini
        content: "session.auto_start = Off\nshort_open_tag = Off\n\nerror_reporting = E_ALL & ~E_NOTICE & ~E_WARNING & ~E_STRICT & ~E_DEPRECATED\n\n; opcache.enable_cli=1\n; opcache.fast_shutdown=1\n; opcache.memory_consumption=256\n; opcache.interned_strings_buffer=8\n; opcache.max_accelerated_files=4000\n; opcache.revalidate_freq=60\n; # http://symfony.com/doc/current/performance.html\n; realpath_cache_size = 4096K\n; realpath_cache_ttl = 600\n\nmemory_limit = 2G\npost_max_size = 60M\nupload_max_filesize = 50M\n"
    depends_on:
      mariadb:
        condition: service_healthy
  mariadb:
    image: 'mariadb:11'
    volumes:
      - 'mariadb-data:/var/lib/mysql'
    environment:
      - 'MYSQL_ROOT_PASSWORD=${SERVICE_PASSWORD_MARIADBROOT}'
      - 'MYSQL_DATABASE=${DB_DATABASE:-invoiceninja}'
      - 'MYSQL_USER=${SERVICE_USER_MARIADB}'
      - 'MYSQL_PASSWORD=${SERVICE_PASSWORD_MARIADB}'
    healthcheck:
      test:
        - CMD
        - healthcheck.sh
        - '--connect'
        - '--innodb_initialized'
      interval: 5s
      timeout: 20s
      retries: 10
  redis:
    image: 'redis:7.4-alpine'
    command: 'redis-server --requirepass ${SERVICE_PASSWORD_REDIS}'
    environment:
      - 'REDIS_PASSWORD=${SERVICE_PASSWORD_REDIS}'
    volumes:
      - 'invoice-ninja-redis-data:/data'
    healthcheck:
      test:
        - CMD
        - redis-cli
        - '-a'
        - '${SERVICE_PASSWORD_REDIS}'
        - ping
      interval: 10s
      timeout: 5s
      retries: 5

Logs

Error: could not read config file /etc/supervisord.conf
For help, use /usr/bin/supervisord -h

(repeats endlessly)

Final Note

I’m not a developer. I’ve tried my best to investigate the issue — reading forum posts, tweaking settings on my VPS, and chatting with ChatGPT. I don’t fully understand everything, so I apologize if this report lacks precision or duplicates an existing issue I may have misunderstood.

Thank you in advance for your help.

Hi,

I’m sorry, I don’t have any experience with Coolify. You may want to try posting on the Coolify forums instead.

Hi @hillel,

Thanks for your answer!
The thing is, this issue seems very specific to Invoice Ninja. I’ve never had this kind of bug with other services deployed through Coolify. So I doubt most Coolify users would have the answer either.

No worries though, I’ll come back and share the solution here if I manage to figure it out on my side.

Thanks again for your time!

1 Like