Hello! First time poster. Thank you for such an awesome piece of software!
I get an error (Gunicorn) when launching an OCI container that has an entrypoint (CMD) with parentheses in one of the arguments. It looks like the escaped (x2?) entrypoint is being passed through. Gunicorn does expect the parentheses in the argument (docs).
$ incus start profilarr --console
To detach from the console, press: <ctrl>+a q
[2025-06-03 12:59:54 +0000] [21] [INFO] Starting gunicorn 21.2.0
[2025-06-03 12:59:54 +0000] [21] [INFO] Listening at: http://0.0.0.0:6868 (21)
[2025-06-03 12:59:54 +0000] [21] [INFO] Using worker: sync
[2025-06-03 12:59:54 +0000] [22] [INFO] Booting worker with pid: 22
Failed to parse 'create_app\\(\\)' as an attribute name or function call.
[2025-06-03 12:59:54 +0000] [22] [INFO] Worker exiting (pid: 22)
[2025-06-03 12:59:54 +0000] [21] [ERROR] Worker (pid:22) exited with code 4
[2025-06-03 12:59:54 +0000] [21] [ERROR] Shutting down: Master
[2025-06-03 12:59:54 +0000] [21] [ERROR] Reason: App failed to load.
This is the CMD from the application’s Dockerfile.
Next, verify what you already go. Indeed, it matches.
$ incus start profilarr --console
To detach from the console, press: <ctrl>+a q
[2025-06-03 13:52:02 +0000] [21] [INFO] Starting gunicorn 21.2.0
[2025-06-03 13:52:02 +0000] [21] [INFO] Listening at: http://0.0.0.0:6868 (21)
[2025-06-03 13:52:02 +0000] [21] [INFO] Using worker: sync
[2025-06-03 13:52:02 +0000] [22] [INFO] Booting worker with pid: 22
Failed to parse 'create_app\\(\\)' as an attribute name or function call.
[2025-06-03 13:52:02 +0000] [22] [INFO] Worker exiting (pid: 22)
[2025-06-03 13:52:02 +0000] [21] [ERROR] Worker (pid:22) exited with code 4
[2025-06-03 13:52:02 +0000] [21] [ERROR] Shutting down: Master
[2025-06-03 13:52:02 +0000] [21] [ERROR] Reason: App failed to load.
$
But if we fix it, does it still fails to run? Let’s see.
$ incus config set profilarr oci.entrypoint 'gunicorn --bind 0.0.0.0:6868 app.main:create_app()'
$ incus config get profilarr oci.entrypoint
gunicorn --bind 0.0.0.0:6868 app.main:create_app()
$ incus start profilarr --console
To detach from the console, press: <ctrl>+a q
[2025-06-03 13:52:36 +0000] [21] [INFO] Starting gunicorn 21.2.0
[2025-06-03 13:52:36 +0000] [21] [INFO] Listening at: http://0.0.0.0:6868 (21)
[2025-06-03 13:52:36 +0000] [21] [INFO] Using worker: sync
[2025-06-03 13:52:36 +0000] [22] [INFO] Booting worker with pid: 22
Failed to parse 'create_app\\(\\)' as an attribute name or function call.
[2025-06-03 13:52:36 +0000] [22] [INFO] Worker exiting (pid: 22)
[2025-06-03 13:52:36 +0000] [21] [ERROR] Worker (pid:22) exited with code 4
[2025-06-03 13:52:36 +0000] [21] [ERROR] Shutting down: Master
[2025-06-03 13:52:36 +0000] [21] [ERROR] Reason: App failed to load.
$
This is weird. As if the initial escaped value has been cached. Is it that the case? Let’s see.
$ incus delete profilarr
$ incus create docker:santiagosayshey/profilarr:latest profilarr
Creating profilarr
$ incus config get profilarr oci.entrypoint
gunicorn --bind 0.0.0.0:6868 app.main:create_app\(\)
$ incus config set profilarr oci.entrypoint 'gunicorn --bind 0.0.0.0:6868 app.main:create_app()'
$ incus config get profilarr oci.entrypoint
gunicorn --bind 0.0.0.0:6868 app.main:create_app()
$ incus start profilarr --console
To detach from the console, press: <ctrl>+a q
[2025-06-03 13:57:26 +0000] [21] [INFO] Starting gunicorn 21.2.0
[2025-06-03 13:57:26 +0000] [21] [INFO] Listening at: http://0.0.0.0:6868 (21)
[2025-06-03 13:57:26 +0000] [21] [INFO] Using worker: sync
[2025-06-03 13:57:26 +0000] [22] [INFO] Booting worker with pid: 22
Failed to parse 'create_app\\(\\)' as an attribute name or function call.
[2025-06-03 13:57:26 +0000] [22] [INFO] Worker exiting (pid: 22)
[2025-06-03 13:57:26 +0000] [21] [ERROR] Worker (pid:22) exited with code 4
[2025-06-03 13:57:26 +0000] [21] [ERROR] Shutting down: Master
[2025-06-03 13:57:26 +0000] [21] [ERROR] Reason: App failed to load.
$
This means that even if you remove the escaping from oci.entrypoint, something else is likely adding it back before sending it to gunicorn. Or, there’s some other error but the printing function for the error always does the escaping in the error message.