Help

Installation

PoC Installation - Latest

Updated 3 Nov 2026 14 min read

Version : v2026.10

Version: v2026.10 (build 202610280904) In a hurry? PoC Installation — Quick Start — v2026.10 is the same install in three steps.

v2026.10 replaces the old monofor.sh shell script with a single static binary, monofor. One installation code carries the tenant settings, the enabled products, their versions and the registry credentials — nothing else has to be configured by hand.

This guide covers a PoC (single-server) installation of Monosign, Monopam and Monosync on Docker Swarm.


1. Before you start

Monofor products run as containers pulled from Monofor's official registry (cr.monofor.com). Access to that registry comes with the installation code. Without a code the installation cannot be performed. Contact your Monofor Sales Engineer or authorized partner, or [email protected].

These installation steps are performed under the supervision of Monofor Sales Engineers or authorized partner sales engineers.

What gets installed

Product

What it is

Version in this build

Monosign

Identity and access management — the sign-in authority for all three

v2026.10-hf01

Monopam

Privileged account and access management

v2026.10-rc

Monosync

Directory / user synchronization

v2026.09

Internal database

PostgreSQL container, PoC only

v2025.10

Which products are enabled and at which versions is decided by the installation code, not by a flag. The installer prints them before it starts.


2. Requirements

2.1 Operating systems

Operating system

Supported

Debian 12.x, 13.x

Yes

Ubuntu 22.04 LTS

Yes

Red Hat Enterprise Linux 8.x, 9.x

Yes

CentOS Stream 8.x, 9.x

Yes

Oracle Linux 8.x, 9.x

Yes

Rocky Linux 8.x, 9.x

Yes

Windows

Not supported — Windows does not run Linux containers

Both x86_64 and arm64 are supported; the installer picks the right binary.

2.2 Hardware

The installer enforces these before it touches the server. They differ by deployment type:

Deployment

CPU

Memory

Free disk for Docker’s data (/var/lib/docker)

PoC (this guide)

8 cores

16 GB

100 GB

Production

—

16 GB

100 GB

Single Data Center — manager

2 cores

4 GB

30 GB

Single Data Center — worker

4 cores

12 GB

50 GB

Where the free disk must be. The installer downloads the product images and keeps the containers, their volumes and the PoC database under Docker’s data folder, /var/lib/docker. The free disk in the table is needed on the disk that holds this folder. On a server with one root filesystem that is /. On a server where /var is a separate partition it is /var — a 10 GB /var is not enough, and the installation fails while downloading the images. The images alone take about 15 GB; the data grows from there. The installer measures this disk before it changes anything and names it in its output. To keep Docker’s data on another disk, set data-root in /etc/docker/daemon.json before installing.

Recommended for a PoC that will be demoed under load: 16 cores / 32 GB / 200 GB. CPU speed: 2.1 GHz or better.

An installation code can carry its own thresholds (x-monofor-poc / x-monofor-sdc); when it does, those win over the table above.

2.3 Software

  • Docker Engine — docker-ce, docker-ce-cli, containerd.io, docker-buildx-plugin, docker-compose-plugin. The installer installs them from download.docker.com when they are missing; pass --install-docker to skip the prompt.

  • curl or wget

  • A PoC needs no external database. The installer deploys an internal PostgreSQL container and creates the monopam and monosync databases on it.

2.4 Firewall

Do not disable the host firewall. Unlike previous versions, v2026.10 opens its own ports in ufw / firewalld during installation. Use --skip-firewall to keep it from touching the firewall — the installer then prints the ports you must open yourself.

Ports the server listens on after installation

Port

Service

Note

TCP/80

Load balancer

HTTP, redirects to HTTPS

TCP/443

Load balancer

All product web traffic

TCP/3389, TCP/6636

Monosign LDAP gateway

Only needed if the LDAP gateway is used

TCP/5432

Internal PostgreSQL

PoC only. Published on all interfaces — restrict it at the network layer

Outbound (internet) access required

Source

Destination

Port

Why

Monofor server

services.monofor.com

TCP/443

Installer, installation files, license

Monofor server

cr.monofor.com

TCP/443

Container images

Monofor server

download.docker.com

TCP/443

Docker Engine packages

Monofor server

OS repositories

TCP/80, TCP/443

OS packages and updates

Internal access

Source

Destination

Port

Why

Monofor server

DNS servers

UDP/53

Name resolution

Monofor server

NTP servers

UDP/123

Time synchronization

Monofor server

Active Directory

TCP/389, TCP/636

Directory integration

Monofor server

SMTP server

TCP/25 or TCP/587

Email notification

Any RADIUS client

Monofor server

UDP/1812, UDP/1813

RADIUS integration

Any

Monofor server

TCP/443

User SSO and management access

Monofor server

Monopam Gateway server

TCP/443

Monopam to gateway

Monopam Gateway server

Target machines

TCP/22, TCP/3389

Privileged session access

For a multi-server installation, Docker Swarm's own ports are also needed between the nodes: TCP/2377 (cluster management), TCP+UDP/7946 (node discovery), UDP/4789 (overlay network).

2.5 DNS records

Every product name must resolve to the server before the installation starts. The services reach each other through these names, not through localhost.

Application

Name

Scope

Record

Account (sign-in)

id.example.com

Internal and external

A → server IP

Management

iam.example.com

Internal

A → server IP

API

iam-api.example.com

Internal

A → server IP

Monopam

pam.example.com

Internal

A → server IP

Monopam CDN

pam-cdn.example.com

Internal

A → server IP

Monopam CDN console

pam-cdn-con.example.com

Internal

A → server IP

Monosync

sync.example.com

Internal

A → server IP

Monopam Gateway

pamgw.example.com

Internal

A → gateway server IP

Notes:

  • id, iam and iam-api are required for every installation. The pam* and sync records are required only when those products are in scope — but when they are enabled by the code, the installer checks them.

  • id.example.com must also be published externally if Monosign Authenticator push notifications are to be used.

  • The license is bound to iam.example.com.

  • A /etc/hosts entry on the server is not a substitute. Docker's embedded DNS does not read the host's /etc/hosts, so the containers would still fail to resolve each other. If you have no DNS records, use --local-dns (see 5.4) — the installer then writes the entries both on the host and inside every service.

  • In a split-DNS lab, make sure the resolver the server uses is the one holding the zone. A server pointed at a different resolver will recurse to the public internet and get NXDOMAIN.

2.6 Time

Set the server's timezone and configure NTP before installing. Swarm nodes with drifting clocks fail to join.

2.7 Certificates

Monosign serves several hostnames under one domain, so it needs a wildcard certificate (*.example.com).

The installer generates a self-signed wildcard certificate automatically — enough for a PoC; browsers will warn. Replace it with your own at any time (see 7.2).


3. Pre-installation check

monofor check verifies the server without changing anything. With --code it also validates the code and the DNS of its domain — the check never uses the code up:

curl -fsSL https://services.monofor.com/install/latest/install.sh | sudo bash
sudo monofor check --code YOURCODE

(The first line installs only the binary, because no code follows it.)

The check reports, for the code, whether it is still free, already used by this server, or used by another installation — in the last case it cannot be installed here.


4. Installation — the one command

On the server, as root:

curl -fsSL https://services.monofor.com/install/latest/install.sh | sudo bash -s YOURCODE

The script downloads the installer for the server's architecture, verifies it against the published SHA256SUMS, installs it at /usr/local/bin/monofor, and runs monofor install --code YOURCODE. Running it again continues an installation that stopped.

You will be asked for your domain if the installation does not have one yet; pass --domain example.com to answer it up front.

Expect 15–30 minutes, almost all of it image download (16 images).

4.1 Pinning the version

latest follows the newest release. To pin this exact build, use the versioned path:

curl -fsSL https://services.monofor.com/install/v2026.10/install.sh | sudo bash -s YOURCODE

Release candidates are published at install/rc/.

4.2 Installing the binary manually

If you would rather not pipe a script into a shell:

cd /tmp
curl -fsSLO https://services.monofor.com/install/v2026.10/monofor-linux-amd64
curl -fsSLO https://services.monofor.com/install/v2026.10/SHA256SUMS
sha256sum --ignore-missing -c SHA256SUMS
sudo install -m 0755 monofor-linux-amd64 /usr/local/bin/monofor
sudo monofor install --code YOURCODE

Use monofor-linux-arm64 on an arm64 server. Builds for macOS and Windows are published too — they are for running check from a workstation, not for hosting the products.

4.3 Installation options

Flag

What it does

--code ABC123

The installation code. Everything else comes with it.

--domain example.com

The customer's domain, instead of being asked for it

--install-docker

Install missing Docker Engine without asking

--local-dns

Write the product names as host entries instead of requiring DNS records

--local-dns-ip <ip>

Point those host entries at another address (implies --local-dns)

--skip-dns-check

Do not check the DNS records before installing

--skip-firewall

Do not open the ports in ufw/firewalld; print them instead

--credentials-file <path>

Write the temporary credentials to a file (mode 0600) instead of the console — for automated runs whose output is logged

--advertise-addr <addr>

The address other servers and the product names reach this server on

--monosign-version <ver>

Override the Monosign version the code selects

--validate

Validate the configuration and exit without installing

--force

Rebuild the environment even if one exists (resets Docker Swarm)

--offline[=<path>]

Install without internet from /opt/monofor, a folder, or a .zip

--config <file>

Install from a full YAML file; with a code only its database and network sections are used

Example — unattended, no questions asked:

sudo monofor install \
  --code YOURCODE \
  --domain example.com \
  --install-docker \
  --credentials-file /root/monofor-credentials.txt

4.4 Installing without DNS records

For a disconnected lab where you cannot add records, --local-dns makes the installer write the product names into /etc/hosts on the server and into every service's own resolver, which is what makes the containers able to reach each other:

sudo monofor install --code YOURCODE --domain example.com --local-dns

Clients outside the server will still need those names resolvable — a hosts file entry on each test machine, or a conditional forwarder on your DNS.

4.5 Offline installation

For a server with no internet access, prepare a bundle on a machine that has one:

monofor offline prepare --code YOURCODE     # downloads files, images and the installer

Carry the folder or .zip over, then on the target server:

sudo monofor install --offline=/path/to/bundle.zip

Offline bundles are also available from Monohub. Verify the bundle first with monofor check --offline.


5. What the installer does

Useful when reading the output or diagnosing a stop.

Pre-flight — installation code → configuration → This server (CPU, memory, disk) → Docker → Firewall → DNS. Nothing has been changed yet at this point; a failure here is safe.

Preparing this server (8 steps) — directories under /opt/monofor → network interface → credentials and IDs → installation files → TLS certificate → registry sign-in → Docker Swarm → environment file.

Installing Monosign (9 steps) — hostnames → database → version → configuration files → image download → deploy services → verify → deploy Monopam and Monosync → secure environment.

The last step encrypts the environment variables, signs out of the registry again, and audits the server for plaintext credentials left behind.


6. Verifying the installation

monofor status

A healthy PoC reports, in this order: Installed, Internal database, Services, Node, Monopam stack + its readiness probe, Monosync stack + its readiness probe, Certificate, and finally Everything is healthy. It exits non-zero when anything is unhealthy or incomplete, so it can be used in a script.

A full PoC runs 20 services, all 1/1:

docker service ls

Stack

Services

monofor

db, loadbalancer

monosign

account, management, api, cache, mq, access-gateway, ldap-gateway, radius-server, service-batch, service-critical, service-standard

monopam

app, cache, cdn, gateway

monosync

cache, service, ui

Endpoint check — none of these should return 502:

URL

Expected

https://id.example.com/

302

https://iam.example.com/

200

https://iam-api.example.com/

200

https://pam.example.com/

302 (redirects to Monosign)

https://pam-cdn.example.com/

403 (bucket root; expected)

https://pam-cdn-con.example.com/

200

https://sync.example.com/

302 (redirects to Monosign)

Health probes: https://id.example.com/ping, /ping/hc, https://pam.example.com/probes/ready, https://sync.example.com/ping.


7. After the installation

7.1 Sign in and change the password

The installer prints a temporary root account, or writes it to the file given in --credentials-file (mode 0600).

  1. Open https://id.example.com and sign in as root.

  2. Change the password.

  3. Delete the credentials file:

    rm /root/monofor-credentials.txt

Monopam and Monosync have no separate accounts — open https://pam.example.com or https://sync.example.com and sign in with a Monosign user.

7.2 Install your own certificate

monofor cert install --crt fullchain.pem --key private.key

Use a full chain (leaf plus intermediates) so browsers trust it. The pair is validated before anything changes, the previous certificate is kept, and the whole change is rolled back automatically if the products do not come back healthy. --allow-expired installs an already expired certificate.

7.3 Hardening checklist

The last installation step audits the server and prints what it found. Work through it:

  • Temporary credentials file deleted.
  • DMZ hand-off bundle — /opt/monofor/dmz holds plaintext credentials for the DMZ host. Move it to that host and delete it from this server.
  • Plaintext credential traces — Docker writes the service environment into its own container state (/var/lib/docker/containers/*/config.v2.json), and /opt/monofor/monosync.env holds its secrets in plain form. These are root-only files; treat root on this server as equivalent to the product credentials, and keep the host access-controlled accordingly.
  • TCP/5432 — the internal PoC PostgreSQL is published on all interfaces. Block it at the network layer unless something off-box genuinely needs it.
  • Replace the self-signed certificate (7.2).
  • The registry session is signed out again by the installer — confirm with docker logout cr.monofor.com if you are unsure.

8. Multi-server (Single Data Center)

A Single Data Center installation is 1 manager + N workers, driven by the same code.

  1. Run the install on the manager. It prepares the environment and then stops before deploying, with exit code 6, printing the line to paste on each worker.

  2. On each worker, paste that line — it is a full monofor join --manager <ip[:port]> --token <token> … command. join checks the worker (OS, memory, disk, the manager's ports, the clock), installs Docker Engine if missing, and joins the Swarm.

  3. Run the same install command on the manager again once every worker has joined.

Print the join line at any time with:

monofor node add

With local host entries instead of DNS, point them at a worker — the load balancer runs on the workers, not the manager:

sudo monofor install --code YOURCODE --local-dns-ip <worker-ip>

9. Troubleshooting

Symptom

Cause

What to do

Installer stops at DNS with nothing changed

A product name does not resolve

Add the missing A record, or re-run with --local-dns

This installation code has already been used by another installation

Codes are single-use per installation

Get a new code. Run monofor check --code first next time — it does not consume the code

Install stops at CPUs / Memory / Disk space

Below the PoC thresholds in 2.2. For Disk space the message names the disk it measured — the one holding /var/lib/docker, often a separate /var partition

Resize the server, or give that disk (/var) the free space. On a VM, grow the disk before taking snapshots — most hypervisors refuse to extend a disk that has one

Endpoints return 502 long after install

The services cannot resolve each other

Check DNS from inside a container, not just from the host: docker exec $(docker ps -qf name=monosign_api) getent hosts iam-api.example.com

Unable to read Protection Key from Monosign … Name or service not known

Same as above — container DNS

As above. A host /etc/hosts entry does not reach containers; use --local-dns

monofor: command not found after installing

/usr/local/bin not on the current PATH, or environment not loaded

Open a new login shell, or source /etc/profile.d/monofor-env.sh

Image pull fails with authentication error

Registry session expired

Re-run the install; the code signs in again

checksum mismatch from install.sh

Truncated download, or a build being published at that moment

Run the same command again

Collect the full log before escalating — the installer writes everything it prints to the terminal, so capture it with tee on an attended run, or use --credentials-file and redirect on an unattended one.


10. Reference

Command summary

Command

Purpose

monofor check [--code X]

Pre-installation checks; never consumes the code

monofor install --code X

Install

monofor status

Health of the installed system; read-only, exits non-zero when unhealthy

monofor cert install

Replace the certificate

monofor node add

Print the worker join line

monofor join

Join this server to an installation as a worker

monofor offline prepare

Build an offline bundle

monofor --version

Build information

File layout

Path

Contents

/usr/local/bin/monofor

The installer / management CLI

/opt/monofor

Installation root

/opt/monofor/lb

Load balancer configuration and lb/ssl certificates

/opt/monofor/lb/sites

One vhost file per product

/opt/monofor/cert

Certificate store

/opt/monofor/dmz

DMZ hand-off bundle — move it off this server

/opt/monofor/backup

Backups

/opt/monofor/log

Logs

/opt/monofor/tools

Tools

/opt/monofor/*.env, *.yml

Per-product environment and stack files

/etc/profile.d/monofor-env.sh

Installation state: paths, tenant, domain, swarm address, encrypted secrets

Download URLs

File

URL

Bootstrap script

https://services.monofor.com/install/v2026.10/install.sh

Linux x86_64

https://services.monofor.com/install/v2026.10/monofor-linux-amd64

Linux arm64

https://services.monofor.com/install/v2026.10/monofor-linux-arm64

Checksums

https://services.monofor.com/install/v2026.10/SHA256SUMS

latest and rc can replace v2026.10 in any of these paths.

Permanent link