8.2.15 Deployment and Configuration of Passbolt

Passbolt CE is a reliable solution for team password management with end-to-end GPG encryption. Containerized deployment lets you roll out Passbolt quickly with minimal host‐system dependencies.
Server Preparation
Requirements
Variables to replace (EN)
YOUR_DOMAIN— the domain where Passbolt will be accessible; used inAPP_FULL_BASE_URL, the nginx config, and when issuing the SSL certificate.DB_USERNAME— MariaDB user that connects to the Passbolt database (DATASOURCES_DEFAULT_USERNAME,MYSQL_USER).PASSWORD— password for<DB_USERNAME>(DATASOURCES_DEFAULT_PASSWORD,MYSQL_PASSWORD).DB_NAME— Passbolt database name (DATASOURCES_DEFAULT_DATABASE,MYSQL_DATABASE).DB_ROOT_PASSWORD— root (administrator) password for MariaDB (MYSQL_ROOT_PASSWORD).EMAIL— e-mail address of the first administrator created withregister_user.SMTP_HOST— SMTP server address (EMAIL_TRANSPORT_DEFAULT_HOST, optional).SMTP_PASSWORD— SMTP password or token (EMAIL_TRANSPORT_DEFAULT_PASSWORD, optional).
Firewall Setup
For security, allow only the necessary ports: SSH (remote access), HTTP and HTTPS (Passbolt web interface).
UFW:
sudo ufw allow 22/tcp
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable

iptables:
sudo iptables -A INPUT -p tcp --dport 22 -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 80 -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 443 -j ACCEPT
sudo iptables -A INPUT -i lo -j ACCEPT
Deploying Passbolt
Create and enter the working directory:
mkdir ~/passbolt && cd ~/passbolt
Create docker-compose.yml:
version: '3.8'
services:
passbolt:
image: passbolt/passbolt:latest-ce
container_name: passbolt
environment:
APP_FULL_BASE_URL: YOUR_DOMAIN
DATASOURCES_DEFAULT_HOST: db
DATASOURCES_DEFAULT_USERNAME: USERNAME
DATASOURCES_DEFAULT_PASSWORD: PASSWORD
DATASOURCES_DEFAULT_DATABASE: DB_NAME
ports:
- "80:80"
- "443:443"
volumes:
- gpg_volume:/etc/passbolt/gpg
- jwt_volume:/etc/passbolt/jwt
- ./nginx:/etc/nginx/certs:ro
depends_on:
- db
db:
image: mariadb:10.6
container_name: passbolt-db
environment:
MYSQL_ROOT_PASSWORD: DB_ROOT_PASSWORD>
MYSQL_DATABASE: DB_NAME
MYSQL_USER: DB_USERNAME
MYSQL_PASSWORD: PASSWORD
volumes:
- db_data:/var/lib/mysql
volumes:
gpg_volume:
jwt_volume:
db_data:
Note: replace db, passbolt, StrongPassw0rd!, passboltdb with your own values.
Bring up the containers:
docker-compose up -d

Initial Configuration
Get the container name:
docker ps

Run the install script:
docker exec -it passbolt su -m -c "/usr/share/php/passbolt/bin/cake passbolt install" -s /bin/sh www-data
Follow the prompts:
- Web server: nginx (built-in)
- SSL certificate: self-signed or via reverse proxy
- Database: passboltdb / user: passbolt / password: StrongPassw0rd!
Important: if you run an external nginx or Caddy, remove ports 80/443 from Compose and set up the reverse proxy yourself.
Registering the First Administrator
After installation, you must create the first admin user via CLI:
docker exec -it passbolt su -m -c "/usr/share/php/passbolt/bin/cake passbolt register_user -u EMAIL -f Admin -l User -r admin" -s /bin/sh www-data
Note: replace admin@example.com with your admin email.
SMTP Configuration
Add SMTP settings under environment for the passbolt service in docker-compose.yml:
EMAIL_TRANSPORT_DEFAULT_CLASSNAME: Smtp
EMAIL_TRANSPORT_DEFAULT_HOST: smtp.mailgun.org
EMAIL_TRANSPORT_DEFAULT_PORT: 587
EMAIL_TRANSPORT_DEFAULT_USERNAME: postmaster@mg.example.com
EMAIL_TRANSPORT_DEFAULT_PASSWORD: your_smtp_password
EMAIL_TRANSPORT_DEFAULT_TLS: true
Note: be sure to replace smtp.mailgun.org, 587, postmaster@mg.example.com, your_smtp_password per our SMTP guide.
A correctly configured mail service is required to send invitations to new users.
Reverse Proxy (nginx)
If you use an external nginx, create this config:
server {
listen 443 ssl;
server_name YOUR_DOMAIN;
ssl_certificate /etc/letsencrypt/live/YOUR_DOMAIN/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/YOUR_DOMAIN/privkey.pem;
location / {
proxy_pass http://127.0.0.1:80;
proxy_set_header Host $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;
}
}
Obtain an SSL certificate:
sudo certbot certonly --standalone -d YOUR_DOMAIN
Disable ports in docker-compose.yml when using the external proxy:
ports:
# - "80:80"
# - "443:443"
Automatic Updates (Watchtower)
Add Watchtower to docker-compose.yml:
watchtower:
image: containrrr/watchtower
container_name: watchtower
restart: always
volumes:
- /var/run/docker.sock:/var/run/docker.sock
This will auto-restart containers when new images are available.
Diagnostics and Logging
Check container status and logs:
docker ps -a
docker logs passbolt
docker logs -f passbolt
View nginx errors:
docker exec -it passbolt tail -f /var/log/nginx/error.log
Verification
In your browser, visit:
https://YOUR_DOMAIN

Run the health check:
docker exec -it passbolt su -m -c "/usr/share/php/passbolt/bin/cake passbolt healthcheck" -s /bin/sh www-data

Backup
Create a backup directory:
mkdir -p ~/passbolt/backup
Export the database:
docker exec passbolt-db sh -c 'exec mysqldump -u root -p"ROOT_PASSWORD" DB_NAME' > ~/passbolt/backup/passbolt_db.sql
Backup certificates and config:
sudo cp -r ~/passbolt/nginx ~/passbolt/backup/nginx_certs
docker cp passbolt:/etc/passbolt ~/passbolt/backup/passbolt_conf
Automate this with a cron job or systemd timer.
Common Issues & Solutions
| Issue | Cause | Solution |
|---|---|---|
| https://<YOUR_DOMAIN> won’t open | Port or nginx misconfiguration | Ensure ports 80/443 are forwarded, or configure an external SSL proxy |
| Emails aren’t sent | Missing or incorrect SMTP settings | Add the EMAIL_TRANSPORT_* variables in Compose |
| Database error during install | Database not ready when Passbolt starts | Add depends_on: db and restart containers |
| Container keeps restarting | Config or GPG key errors | Check docker logs passbolt and volume permissions |
| Healthcheck shows WARNING | Missing SMTP or wrong BASE URL | Verify APP_FULL_BASE_URL and SMTP settings in docker-compose.yml |
Official Documentation


