Docker - Incomplete install

I provide relevant information about my server (component names and versions, etc.)
Ubuntu 24.04.2 LTS + Nginx + Docker + passbolt-ce-server

I describe the steps on how to reproduce the issue

Hi, I’ve installed a VM with Ubuntu Server with Nginx. Next, I’ve configured the Nginx as a reverse proxy:

server {
  listen 443 ssl;
  
  # add Strict-Transport-Security to prevent man in the middle attacks
  add_header Strict-Transport-Security "max-age=31536000" always;

  # SSL
  ssl_certificate /etc/nginx/ssl-certs/fullchain.pem;
  ssl_certificate_key /etc/nginx/ssl-certs/privkey.pem;

  ssl_protocols TLSv1.1 TLSv1.2;
  ssl_ciphers 'EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH';
  ssl_prefer_server_ciphers on;
  ssl_session_cache shared:SSL:10m;

  # required to avoid HTTP 411: see Issue #1486 
  # (https://github.com/docker/docker/issues/1486)
  chunked_transfer_encoding on;

 location /passbolt/ {
    proxy_pass https://127.0.0.1:7443/;
    proxy_set_header Host $http_host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_buffering off;
    proxy_request_buffering off;
  }

Than, installed Passbolt using Docker. Because ports 80 and 443 ware already used:

ports:
- 7080:80
- 7443:443

APP_FULL_BASE_URL: https://my_server_address.test
APP_BASE: /passbolt

Until here, everything is OK and the Login page was displayed.

Than, on Step 5. Create first admin user
when I execute the command I get this: service “passbolt” is not running

Than I opened a console on Passbolt container and executed:

/usr/share/php/passbolt# su -m -c "/usr/share/php/passbolt/bin/cake passbolt register_user \
    -u test.user@xpto.com \
    -f test \                      
    -l user \
    -r admin" -s /bin/sh www-data

The user was saved successfully and I’ve got the link to register the user.
I’ve copy/paste the link and proceeded with user registration, choosing a password.
When I click next, I got this page:


Pressing F5 or Ctrl+F5 reload the same page
If I open a Private window I have the Login page again.
When I try to login with the previous created user, I get this:

But, if I try to create the user again I get this:
Validation failed for the following user data:
- Username: The username is already in use.

Is it mandatory to have a working email?
Thank you for any help.

I provide a copy of my logs and healthcheck:
su -m -c “/usr/share/php/passbolt/bin/cake passbolt healthcheck” -s /bin/sh www-data

Open source password manager for teams

Healthcheck shell…

Environment

[INFO] Linux ca74307eaa43 6.8.0-55-generic #57-Ubuntu SMP PREEMPT_DYNAMIC Wed Feb 12 23:42:21 UTC 2025 x86_64 GNU/Linux
[PASS] PHP version 8.2.28.
[PASS] PHP version is 8.2 or above.
[PASS] 64-bit architecture system detected.
[INFO] gpg (GnuPG) 2.2.40 / libgcrypt 1.10.1
[PASS] PCRE compiled with unicode support.
[PASS] Mbstring extension is installed.
[PASS] Intl extension is installed.
[PASS] GD or Imagick extension is installed.
[PASS] The temporary directory and its content are writable and not executable.
[PASS] The logs directory and its content are writable.
[WARN] System clock and NTP service information cannot be found.
[HELP] See timedatectl | grep -i -A 1 clock. More information: https://www.passbolt.com/docs/hosting/configure/ntp/

Config files

[PASS] The application config file is present
[WARN] The passbolt config file is missing in /etc/passbolt/
[HELP] Copy /etc/passbolt/passbolt.default.php to /etc/passbolt/passbolt.php
[HELP] The passbolt config file is not required if passbolt is configured with environment variables

Core config

[PASS] Cache is working.
[PASS] Debug mode is off.
[PASS] Unique value set for security.salt
[PASS] Full base url is set to https://srv-container.cm-albufeira.pt/
[PASS] App.fullBaseUrl validation OK.
[PASS] /healthcheck/status is reachable.

SSL Certificate

[PASS] SSL peer certificate validates.
[PASS] Hostname is matching in SSL certificate.
[PASS] Not using a self-signed certificate.

SMTP settings

[PASS] The SMTP Settings plugin is enabled.
[PASS] SMTP Settings coherent. You may send a test email to validate them.
[WARN] The SMTP Settings source is: env variables.
[HELP] It is recommended to set the SMTP Settings in the database through the administration section.
[WARN] The SMTP Settings plugin endpoints are enabled.
[HELP] It is recommended to disable the plugin endpoints.
[HELP] Set the PASSBOLT_SECURITY_SMTP_SETTINGS_ENDPOINTS_DISABLED environment variable to true.
[HELP] Or set passbolt.security.smtpSettings.endpointsDisabled to true in /etc/passbolt/passbolt.php.
[PASS] No custom SSL configuration for SMTP server.

JWT Authentication

[PASS] The JWT Authentication plugin is enabled.
[FAIL] The /etc/passbolt/jwt/ directory should not be writable.
[HELP] You can try:
[HELP] sudo chown -Rf root:www-data /etc/passbolt/jwt/
[HELP] sudo chmod 750 /etc/passbolt/jwt/
[HELP] sudo chmod 640 /etc/passbolt/jwt/jwt.key
[HELP] sudo chmod 640 /etc/passbolt/jwt/jwt.pem
[PASS] A valid JWT key pair was found.

GPG Configuration

[PASS] PHP GPG Module is installed and loaded.
[PASS] The environment variable GNUPGHOME is set to /var/lib/passbolt/.gnupg.
[PASS] The directory /var/lib/passbolt/.gnupg containing the keyring is writable by the webserver user.
[FAIL] The server OpenPGP key is not set.
[HELP] Create a key, export it and add the fingerprint to /etc/passbolt/passbolt.php
[HELP] See. https://www.passbolt.com/help/tech/install#toc_gpg
[PASS] The public key file is defined in /etc/passbolt/passbolt.php and readable.
[PASS] The private key file is defined in /etc/passbolt/passbolt.php and readable.
[FAIL] The server key fingerprint doesn’t match the one defined in /etc/passbolt/passbolt.php.
[HELP] Double check the key fingerprint, example:
[HELP] sudo su -s /bin/bash -c “gpg --list-keys --fingerprint --home /var/lib/passbolt/.gnupg” www-data | grep -i -B 2 ‘SERVER_KEY_EMAIL’
[HELP] SERVER_KEY_EMAIL: The email you used when you generated the server key.
[HELP] See. https://www.passbolt.com/help/tech/install#toc_gpg
[FAIL] The server public key defined in the /etc/passbolt/passbolt.php (or environment variables) is not in the keyring
[HELP] Import the private server key in the keyring of the webserver user.
[HELP] you can try:
[HELP] sudo su -s /bin/bash -c “gpg --home /var/lib/passbolt/.gnupg --import /etc/passbolt/gpg/serverkey_private.asc” www-data
[FAIL] The server key does not have a valid email id.
[HELP] Edit or generate another key with a valid email id.
[FAIL] The private key cannot be used to decrypt a message
[FAIL] The private key cannot be used to decrypt and verify a message
[FAIL] The public key cannot be used to verify a signature.

Application configuration

[PASS] Using latest passbolt version (4.12.1).
[FAIL] Passbolt is not configured to force SSL use.
[HELP] Set passbolt.ssl.force to true in /etc/passbolt/passbolt.php.
[PASS] App.fullBaseUrl is set to HTTPS.
[PASS] Selenium API endpoints are disabled.
[PASS] Search engine robots are told not to index content.
[INFO] The Self Registration plugin is enabled.
[INFO] Registration is closed, only administrators can add users.
[PASS] The deprecated self registration public setting was not found in /etc/passbolt/passbolt.php.
[WARN] Host availability checking is disabled.
[HELP] Make sure this instance is not publicly available on the internet.
[HELP] Or set the PASSBOLT_EMAIL_VALIDATE_MX environment variable to true.
[HELP] Or set passbolt.email.validate.mx to true in /etc/passbolt/passbolt.php.
[PASS] Serving the compiled version of the javascript app.
[WARN] Some email notifications are disabled by the administrator.
[PASS] The database schema is up to date.

Database

[PASS] The application is able to connect to the database
[PASS] 34 tables found.
[PASS] Some default content is present.

[FAIL] 9 error(s) found. Hang in there!

Hello @anjoze and welcome to the forum!
First, you need to resolve the error related to your server’s OpenPGP key that appears in the status healthcheck

1 Like

Hi @Termindiego25.
I’m following the steps here: https://www.passbolt.com/docs/hosting/install/ce/docker/
I can’t find the OpenPGP instructions.
I’ve found some instructions about this, here:
https://www.passbolt.com/docs/admin/server-maintenance/passbolt-api-status/#gpg-configuration
Is it this?
Thank you

Hey @anjoze I believe he was referring to this set of instructions: https://www.passbolt.com/docs/hosting/troubleshooting/docker/

On docker you have to run a quick command before you can run the healthcheck so that you don’t get these GPG issues

1 Like

I think I’m missing something…
I’ve deleted the containers and volumes and start from scratch.

I’ve following step by step instructions from here:
https://www.passbolt.com/docs/hosting/install/ce/docker/
but this time I didn’t execute: Step 5. Create first admin user

As you suggested, from here:
https://www.passbolt.com/docs/hosting/troubleshooting/docker/?pk_vid=5b9c268e254c073e1743670716d8c720

I’ve executed:

export PASSBOLT_GPG_SERVER_KEY_FINGERPRINT="$(gpg \
  --home $GNUPGHOME\
  --list-keys \
  ${PASSBOLT_KEY_EMAIL:-passbolt@yourdomain.com} | \
  grep -Ev "^(pub|sub|uid|^$)" | tr -d ' ')"

Executing: ./bin/status-report
Still have multiple errors.
Executing: source /etc/environment
Have just one error: [FAIL] The /etc/passbolt/jwt/ directory should not be writable.

Now nothing changes…
I can create new users, the registration Link works, I choose a password, download the recovery Kit and, when I click next to finish the processes I get the grey screen!

Then, opening a new incognito window, I try to login and I get this:

Trying with Firefox or Chrome Extension I get this:

I’ve disabled some parts of nginx has suggested in some forums but the behavior is always the same.

More feedback.

I redid it all again, luckily Docker is fast :slight_smile:
According to: https://www.passbolt.com/docs/hosting/troubleshooting/docker/?pk_vid=5b9c268e254c073e1743670716d8c720
In fresh new install, I enter on container and change to user www-data:
su -s /bin/bash www-data

Then I execute:

./bin/status-report

I have 9 ERRORS
Then I execute:

export PASSBOLT_GPG_SERVER_KEY_FINGERPRINT="$(gpg \
  --home $GNUPGHOME\
  --list-keys \
  ${PASSBOLT_KEY_EMAIL:-passbolt@yourdomain.com} | \
  grep -Ev "^(pub|sub|uid|^$)" | tr -d ' ')"

or

source /etc/environment

I have 2 Errors:
[FAIL] The temporary directory and its content are not writable, or are executable.
[FAIL] The /etc/passbolt/jwt/ directory should not be writable.

This is the interesting part:
If I exit and become www-data again (su -s /bin/bash www-data) and do ./bin/status-report again, I have the same 9 ERRORS like it was a fresh install!
Maybe its this: [FAIL] The temporary directory and its content are not writable, or are executable.

I have this:
\var\lib\passbolt: drwxr-xr-x 1 www-data www-data
\var\lib\passbolt\tmp: drwxr-xr-x 1 www-data www-data

Hi anjoze,

When you:

$ source /etc/environment

The bash shell executes all the commands in the file you’re “sourcing”.

It’s the equivalent of setting those environment variables by typing:

export APP_FULL_BASE_URL="https://passbolt.local"

Except bash is using the builtin command declare and those environment variables are only available to the shell you’ve imported them in to.

root@801f670dea30:/usr/share/php/passbolt# cat /etc/environment
declare -x APP_FULL_BASE_URL="https://passbolt.local"
declare -- BASH="/usr/bin/bash"
...
declare -x DATASOURCES_DEFAULT_PASSWORD="P4ssb0lt"
...
declare -x PASSBOLT_GPG_SERVER_KEY_FINGERPRINT="EA90DB3FE9874DCDD01090348139D7620AEAE44A"
...

declare with the -x option:

  • The -x flag marks the variable for export, meaning that the variable will be available to any subprocesses spawned from the current shell such ashealthcheck or status-report.

  • declare --” just means there’s no more options and BASH doesn’t need to be exported to child processes. declare is a shell builtin command and you can learn more about those from man bash in a full *nix environment that has man pages installed (docker doesn’t)

Environment variables unlocked!

$ echo $APP_FULL_BASE_URL
https://passbolt.local

I hope that helps understand why the errors are back to 9 after you log back in to the same docker container.

note: It’s why we declare commands in files like .bashrc so when we open a bash shell it automatically sources files or sets useful variables.

cheers
gareth

Thank you for the explanation @gyaresu.
Now I understand that, before the export PASSBOLT_GPG_SERVER_KEY_FINGERPRINT…
command, if I do:
echo $PASSBOLT_GPG_SERVER_KEY_FINGERPRINT
I get nothing.
After doing the export PASSBOLT_GPG_SERVER_KEY_FINGERPRINT… command I have a Key.
Shouldn’t that be persistent?

My doubts still.
According to Official Documentation I’m not missing steps or changing the configuration from Docker compose.
The only change I’ve made is the Nginx reverse proxy, that works with other sites that I have.

I think there is an error on Documentation where is saying:

exec passbolt su -m -c "/usr/share/php/passbolt/bin/cake \
  passbolt register_user \
    -u YOUR_EMAIL \
    -f YOUR_NAME \
    -l YOUR_LASTNAME \
    -r admin" -s /bin/sh www-data

Shouldn’t be:

docker-compose ...?

Now, I’ve deleted the Containers, Volumes and Images to start from beginning with a new version.
Than:

docker exec -ti passbolt-container-name bash

su -s /bin/bash www-data

export PASSBOLT_GPG_SERVER_KEY_FINGERPRINT="$(gpg \
  --home $GNUPGHOME\
  --list-keys \
  ${PASSBOLT_KEY_EMAIL:-passbolt@yourdomain.com} | \
  grep -Ev "^(pub|sub|uid|^$)" | tr -d ' ')"

Then I send a test email and receive it but, when I create a User, the problem persists!
Running the status-report I have:

ERROR: /usr/share/php/passbolt/bin/utils.sh: line 64: mysql: command not found
warning: SplFileInfo::openFile(/var/lib/passbolt/tmp/cache/models/myapp_cake_model_default_organization_settings): Failed to open stream: Permission denied
warning: 512 :: SplFileInfo::openFile(/var/lib/passbolt/tmp/cache/models/myapp_cake_model_default_organization_settings): Failed to open stream: Permission denied on line 387 of /usr/share/php/passbolt/vendor/cakephp/cakephp/src/Cache/Engine/FileEngine.php
2025-04-10 15:17:28 warning: SplFileInfo::openFile(/var/lib/passbolt/tmp/cache/models/myapp_cake_model_default_organization_settings): Failed to open stream: Permission denied
warning: 512 :: SplFileInfo::openFile(/var/lib/passbolt/tmp/cache/models/myapp_cake_model_default_organization_settings): Failed to open stream: Permission denied on line 387 of /usr/share/php/passbolt/vendor/cakephp/cakephp/src/Cache/Engine/FileEngine.php
…2025-04-10 15:17:28 warning: SplFileInfo::openFile(/var/lib/passbolt/tmp/cache/persistent/myapp_cake_core_translations.cake.en_UK): Failed to open stream: Permission denied
warning: 512 :: SplFileInfo::openFile(/var/lib/passbolt/tmp/cache/persistent/myapp_cake_core_translations.cake.en_UK): Failed to open stream: Permission denied on line 387 of /usr/share/php/passbolt/vendor/cakephp/cakephp/src/Cache/Engine/FileEngine.php
2025-04-10 15:17:28 warning: SplFileInfo::openFile(/var/lib/passbolt/tmp/cache/persistent/myapp_cake_core_translations.cake.en_UK): Failed to open stream: Permission denied
warning: 512 :: SplFileInfo::openFile(/var/lib/passbolt/tmp/cache/persistent/myapp_cake_core_translations.cake.en_UK): Failed to open stream: Permission denied on line 387 of /usr/share/php/passbolt/vendor/cakephp/cakephp/src/Cache/Engine/FileEngine.php

[FAIL] The temporary directory and its content are not writable, or are executable.
[FAIL] Could not reach the /healthcheck/status with the url specified in App.fullBaseUrl
[FAIL] The /etc/passbolt/jwt/ directory should not be writable.

[FAIL] 3 error(s) found. Hang in there!

Data check shell
2025-04-10 15:17:29 warning: SplFileInfo::openFile(/var/lib/passbolt/tmp/cache/persistent/myapp_cake_core_translations.cake.en_UK): Failed to open stream: Permission denied
warning: 512 :: SplFileInfo::openFile(/var/lib/passbolt/tmp/cache/persistent/myapp_cake_core_translations.cake.en_UK): Failed to open stream: Permission denied on line 387 of /usr/share/php/passbolt/vendor/cakephp/cakephp/src/Cache/Engine/FileEngine.php
2025-04-10 15:17:29 warning: SplFileInfo::openFile(/var/lib/passbolt/tmp/cache/persistent/myapp_cake_core_translations.cake.en_UK): Failed to open stream: Permission denied
warning: 512 :: SplFileInfo::openFile(/var/lib/passbolt/tmp/cache/persistent/myapp_cake_core_translations.cake.en_UK): Failed to open stream: Permission denied on line 387 of /usr/share/php/passbolt/vendor/cakephp/cakephp/src/Cache/Engine/FileEngine.php
tail: cannot open ‘/var/log/passbolt/error.log’ for reading: No such file or directory

Hi anjoze,

Exports

exports are not persistent as when your shell starts it is either an ‘interactive’ (non-login) shell or a login shell.

  • Login Shells: Often source files such as ~/.bash_profile, ~/.profile, or ~/.bash_login.
  • Interactive Non-Login Shells: Often source ~/.bashrc.

When you export, either from script or directly from the commandline, that variable is only available to that bash process and child processes. If you log out of a bash terminal session then those exports end with the process.

That’s why we customize our shell initialization files to make settings, variables, and behaviours the default.

You’ll see strange behaviour sometimes when running sudo as a user because the sudo process doesn’t have access to the environment variables of your current user and sudo -E [command] is required to pass the users environment along as well.

There’s a lot of quirks to a Unix environment like this and I would recommend you search for some friendly blog posts or go straight to the source of the Bash manual: $ man bash.

Docker compose

Short story: docker-compose is the older Python application. You can enable the new and preferred docker compose with changes to your docker config.json
https://docs.docker.com/compose/install/

My homebrew example using colima runtime:

$ cat ~/.docker/config.json
{
        "auths": {},
        "currentContext": "colima",
        "cliPluginsExtraDirs": [
                "/opt/homebrew/lib/docker/cli-plugins"
        ]
}

Docker errors

There’s a lot of “Permission denied” errors all the way through the logs you posted.
I would start with a sanity check regarding permissions of running containers with docker.

I hope this helps.

cheers
gareth