Skip to content
Zeyu Zhao edited this page May 25, 2026 · 16 revisions

Installation

This guide is for a new installation of Password-Manager v11.09 or later.

For an existing installation, read Upgrade Password Manager before replacing files.

Requirements

Backend:

  • PHP 7.1 or later
  • MySQL or MariaDB
  • PDO MySQL support
  • HTTPS
  • A web server such as Apache, Nginx, or IIS.

v11.09 also supports serverless deployment (e.g. Alibaba Clould Function Compute). start.sh, nginx.conf is provided for an easier deployment.

Frontend:

  • Any trusted static web host that can serve HTML, CSS, and JavaScript over HTTPS. I recommend CloudFlare Pages or GitHub Pages
  • Please send headers according to _headers to ensure safety (especially to avoid script injection from a compromised backend).

Recommended production setup:

  • Frontend URL: https://pm.example.com/
  • Backend URL: https://api.example.com/passwordmanager/backend/

Single-origin deployments also work. For example:

  • Frontend URL: https://example.com/passwordmanager/
  • Backend URL: https://example.com/passwordmanager/backend/

The backend URL must point to the backend root directory containing both rest/ and function/.

1. Download the stable release

Download the latest stable release from the GitHub Releases page.

Do not deploy the master branch for production unless you intentionally want the development branch.

The release archive contains:

src/
  backend/
  frontend/
  initial.sql

2. Create the database

Create a database and database user for Password-Manager.

Example:

CREATE DATABASE password_manager CHARACTER SET utf8 COLLATE utf8_general_ci;
CREATE USER 'pm_user'@'localhost' IDENTIFIED BY 'use-a-strong-password-here';
GRANT ALL PRIVILEGES ON password_manager.* TO 'pm_user'@'localhost';
FLUSH PRIVILEGES;

Import the initial schema:

mysql -u pm_user -p password_manager < src/initial.sql

Do not import initial.sql when upgrading an existing v11.00+ installation.

3. Deploy the backend

Upload the whole src/backend directory to the backend server.

Example final backend path:

https://api.example.com/passwordmanager/backend/

The backend root must contain:

backend/
  function/
  rest/
  .htaccess

Edit:

src/backend/function/config.php

Set the database connection:

$DB_HOST = 'localhost';
$DB_NAME = 'password_manager';
$DB_USER = 'pm_user';
$DB_PASSWORD = 'use-a-strong-password-here';

Set the trusted frontend URL:

$FRONTEND_URL = 'https://pm.example.com/';

Keep this false in production:

$ALLOW_NO_ORIGIN_REQUESTS = false;

Set your timezone:

date_default_timezone_set('America/Los_Angeles');

Set a server-side salt before first use:

$GLOBAL_SALT_3 = 'replace-with-a-long-random-string';

Important:

  • Do not change $GLOBAL_SALT_3 after data has been created.
  • Back up config.php; it is needed for the same installation to keep working.
  • For an existing installation, copy the old server-side salt value from the old config.

Optional settings:

$FILE_ENABLED = true;
$ALLOW_SIGN_UP = true;
$CUSTOMIZE_FIELDS = true;
$PIN_EXPIRE_TIME = 7776000;
$LOG_EXPIRE_TIME = 7776000;
$SERVER_TIMEOUT = 1200;
$PBKDF2_ITERATIONS = 64000;

For a private instance, set this to false after creating your user:

$ALLOW_SIGN_UP = false;

The backend enforces this value. You do not need to delete registration files for security.

4. Protect backend internals

The backend includes Apache .htaccess files. If you use Apache and allow .htaccess, they help block direct access to internal files.

If you use Nginx, IIS, or Apache with .htaccess disabled, add equivalent rules manually.

At minimum:

  • Deny direct web access to src/backend/function/.
  • Disable directory listing.
  • Do not expose .sql, .bak, .md, or other backup/config files.
  • Allow requests to src/backend/rest/*.php.

Example Nginx idea:

location ^~ /passwordmanager/backend/function/ {
    deny all;
}

location ~ /\. {
    deny all;
}

Adjust paths for your own deployment.

5. Deploy the frontend

Upload the contents of src/frontend to your trusted static frontend host.

Example final frontend path:

https://pm.example.com/

The frontend root contains files such as:

index.html
password.html
recovery.html
signup.html
config.js
css/
js/
img/

Edit:

src/frontend/config.js

Set the backend root URL:

apiBaseUrl: "https://api.example.com/passwordmanager/backend/",

The value must point to the directory that contains rest/ and function/. It should end with /.

Set client-side crypto salts before first use:

globalSalt1: "replace-with-a-long-random-string",
globalSalt2: "replace-with-another-long-random-string",

Important:

  • Do not change globalSalt1 or globalSalt2 after data has been created.
  • For an existing installation, copy these values exactly from the old src/function/config.php.
  • These two values live in the static frontend and are not database passwords. They still must remain stable for existing encrypted data.

6. Configure HTTPS

HTTPS is required.

Recommended:

  • Redirect HTTP to HTTPS.
  • Enable HSTS only when you are sure the domain will remain HTTPS-only.

Example HSTS header:

Strict-Transport-Security: max-age=63072000; includeSubDomains; preload

Do not use self-signed or invalid certificates for normal production use.

7. Configure file upload limits, if files are enabled

Password-Manager supports small encrypted attachments. The README only claims tested support up to about 2 MB per file, while the current UI may show a 3 MB upload limit. For best reliability, keep attachments at or below 2 MB.

If $FILE_ENABLED = true, make sure the backend stack accepts the request size you want to support.

Check settings such as:

  • PHP post_max_size
  • PHP upload_max_filesize
  • web server request body limits
  • WAF or ModSecurity request body limits
  • MySQL/MariaDB max_allowed_packet

Files are sent as encoded data, so leave overhead above the raw file size.

8. First run

Open the frontend URL in your browser.

Example:

https://pm.example.com/

Click Sign up and create your first user.

After the first user is created, private installations should disable new signup in:

src/backend/function/config.php

Set:

$ALLOW_SIGN_UP = false;

Then test:

  1. Log in.
  2. Add an entry.
  3. Log out.
  4. Log in again.
  5. Generate a backup.
  6. Open the recovery page and confirm the backup can be unlocked.

9. Enable master account 2FA

After logging in, go to:

Settings -> Turn on 2FA

Scan the QR code with an authenticator app, enter the current 6-digit code, and save the shown secret in a safe place.

Troubleshooting

Browser says the API is blocked by CORS

Check:

  • src/frontend/config.js has the correct apiBaseUrl.
  • src/backend/function/config.php has the correct $FRONTEND_URL.
  • Both URLs use HTTPS.
  • You did not add a wildcard CORS header such as Access-Control-Allow-Origin: *.

Password-Manager is designed to allow only the trusted frontend origin.

API requests return 404

apiBaseUrl must point to the backend root directory, not to rest/ directly.

Correct:

apiBaseUrl: "https://api.example.com/passwordmanager/backend/",

Wrong:

apiBaseUrl: "https://api.example.com/passwordmanager/backend/rest/",

Signup is not available

Check:

$ALLOW_SIGN_UP = true;

After the first user is created, set it back to false for private deployments.

File upload fails

Check file size, PHP limits, web server limits, WAF limits, and MySQL/MariaDB packet limits. Keep files small.

Recovery page works without backend configuration

This is expected. Recovery runs in the browser. It only needs the backup file and the login password that was active when the backup was generated.

Removed / obsolete installation steps

Do not follow old v9/v10/v11.00-era instructions that mention:

  • editing src/function/config.php
  • uploading the entire old src layout as a single app
  • SendGrid or e-mail verification setup
  • check_website.html
  • file_lists.txt
  • manual MD5 client-side source-file checking
  • adding Access-Control-Allow-Origin: *

v11.08 uses split frontend/backend deployment instead.

Clone this wiki locally