Access Controller manual Download PDF

Chapter 16

Installation and hosting

This chapter is for whoever runs the panel: 2plus1 for the hosted service, or your own IT for a self-hosted installation. Access Controller is one binary with an embedded database and MQTT broker, so hosting is deliberately simple. Where this chapter describes a layout that is conventional rather than fixed by the software, it is marked typical.

Note: hosted customers can skip this chapter. If 2plus1 hosts your panel, there is nothing here for you to do. The panel is installed, backed up, monitored and kept up to date by 2plus1; new releases are applied for you, and the only thing that ever needs your attention is updating the firmware on your own controllers, which is done from the Controllers page (chapter 5) at a time that suits the site. The rest of this chapter is for self-hosters.

What you get

Requirements: a small Linux virtual machine or on-premise box (1 vCPU, 512 MB RAM and a few GB of disk are ample), a hostname with an A record pointing at it, and the ability to open three inbound ports.

Quick start (any platform)

accesscontroller create-admin admin YOURPASSWORD
accesscontroller

The first command creates (or resets) a super-admin login in the provider tenant. The second starts the server: web interface on http://localhost:8080 and https://localhost:8443 (self-signed), MQTT broker on port 1883, database at data/acs.db relative to the working directory. Sign in and follow chapter 2.

Run accesscontroller help to see the options.

Environment variables

All configuration is by environment variable; there is no config file.

VariableDefaultMeaning
ACS_DBdata/acs.dbPath of the SQLite database file. The directory is created if missing. The TLS certificate is kept in a tls folder beside it.
ACS_ADDR:8080Web interface listen address (plain HTTP). Behind a reverse proxy bind it to localhost, for example 127.0.0.1:8081.
ACS_TLS_ADDR:8443HTTPS listen address with a self-signed certificate. Set to off when a reverse proxy provides TLS.
ACS_MQTT_ADDR:1883MQTT broker listen address for controllers. Must be reachable from every site.
ACS_TZEurope/LondonThe panel timezone used for schedules, "today" counts and displayed times.
ACS_DEVICE_USER / ACS_DEVICE_PASSemptyUsername and password controllers must present to the broker. Empty means an open broker, acceptable only on an isolated LAN. Also written into controllers at provisioning.
ACS_SYNC_HOURS3How often keysets are re-pushed to every controller as a safety net (also carries daylight-saving offsets).
ACS_FW_DIRdata/firmwareWhere controller firmware images live: <kind>/<chip>/ with four .bin files each, for example networked/esp32/ and networked/esp32s3/.

Typical Linux layout (systemd)

The following is how 2plus1 deploys the hosted service and is a sensible template for self-hosting. Adjust paths and names freely.

ACS_ADDR=127.0.0.1:8081
ACS_TLS_ADDR=off
ACS_MQTT_ADDR=:1883
ACS_DB=/opt/accesscontroller/data/acs.db
ACS_FW_DIR=/opt/accesscontroller/data/firmware
ACS_TZ=Europe/London
ACS_DEVICE_USER=doorctl
ACS_DEVICE_PASS=<long random secret>
[Unit]
Description=Access Controller panel
After=network-online.target
Wants=network-online.target

[Service]
User=acs
Group=acs
WorkingDirectory=/opt/accesscontroller
EnvironmentFile=/etc/accesscontroller.env
ExecStart=/opt/accesscontroller/accesscontroller
Restart=always
RestartSec=3

[Install]
WantedBy=multi-user.target

Then:

sudo systemctl daemon-reload
sudo systemctl enable --now accesscontroller
sudo journalctl -u accesscontroller -f

The log line web ui on 127.0.0.1:8081 confirms the panel is up. A warning "no admin accounts" means you still need create-admin (run it as the acs user with the same ACS_DB so it opens the same database).

Reverse proxy and certificates (Caddy)

Put a TLS reverse proxy in front of the panel so that users get HTTPS with an automatically issued Let's Encrypt certificate. Caddy does this in two lines (typical), in /etc/caddy/Caddyfile:

doors.example.com {
    reverse_proxy 127.0.0.1:8081
}

Caddy obtains and renews the certificate, redirects HTTP to HTTPS, and passes X-Forwarded-Proto: https, which the panel uses to know it is on a secure page (needed for Flash & adopt and webcam capture). Prerequisite: the DNS A record doors.example.com must already point at the server before Caddy can issue the certificate. Nginx or Apache with certbot work equally well; forward to the panel's ACS_ADDR and pass the forwarded-proto header.

After the proxy is up, set Public HTTPS URL on the Settings page to https://doors.example.com so that over-the-air firmware downloads use it, and set the Adoption address to doors.example.com (chapter 13).

Ports and firewall

PortProtocolWho connectsNotes
443HTTPSStaff browsers, the reception screen, the PBX, controllers fetching OTA imagesVia the reverse proxy.
80HTTPLet's Encrypt validation, redirect to 443Via the reverse proxy.
1883MQTT (TCP)Controllers at every siteThe panel's embedded broker binds this itself. Restrict to site addresses where possible. Plain text.
22SSHAdministratorsStandard.

Outbound from the panel host: HTTPS (443) to api.telegram.org if any tenant uses Telegram alerts (chapter 4). Nothing else leaves the panel.

The panel binary binds ACS_ADDR (localhost behind a proxy) and ACS_MQTT_ADDR (all interfaces) itself; the proxy binds 80 and 443. If the panel is on a site LAN with no proxy, users connect to 8080 or 8443 directly instead.

Note: at each site the controllers need outbound TCP to the panel on 1883 (and 443 for updates). Most routers allow outbound traffic by default. On a filtering firewall, add a pass rule for the door network to the panel address on 1883. If a rule appears correct but shows zero traffic, check that the firewall actually loaded its rule set: one deployment lost days to a pfSense box whose filter reload was silently failing because of an oversized block list, so every new rule sat idle and the default deny won. Chapter 17 has the diagnosis steps.

Firmware images

Flash & adopt and OTA serve images from ACS_FW_DIR. Copy the built images for each chip into networked/esp32/ and networked/esp32s3/ (and standalone/... if you offer standalone units): bootloader.bin, partitions.bin, boot_app0.bin and firmware.bin. The Flash & adopt page also accepts uploads per chip, and shows per chip whether a build is complete. 2plus1 supplies the images with each release.

Backups

The whole system state is the SQLite database file. To back it up:

Keep the environment file (it holds the device credentials) and the data/firmware folder with the backup. Photos are stored inside the database, so the one file really is everything.

Restore: stop the service, remove acs.db, acs.db-wal and acs.db-shm, copy the backup in as acs.db, make sure it is owned by the service user, start the service. Run create-admin if you need to reset a login. After a restore the panel re-pushes keysets to every controller on its next connection, so doors pick up the restored state automatically.

Updates

On the hosted service, 2plus1 applies updates; nothing below applies to you.

Self-hosting, replace the binary and restart:

sudo systemctl stop accesscontroller
sudo install -m 0755 -o acs -g acs ./accesscontroller /opt/accesscontroller/accesscontroller
sudo systemctl start accesscontroller

Database schema changes are applied automatically at start-up and are additive, so a newer binary opens an older database. Take a backup before updating anyway. Copy any new firmware images into ACS_FW_DIR at the same time, then use Update on the Controllers page to roll firmware out to controllers one at a time (chapter 5).

Moving to a new server

  1. Install the new panel, restore the database backup onto it, set the same ACS_DEVICE_USER and ACS_DEVICE_PASS (or be ready to type the new ones), and put the proxy and DNS in place.
  2. If the hostname stays the same and DNS is switched over, controllers simply reconnect to the new address when their existing connection drops.
  3. If the address changes, use Re-point on the old panel for each controller while it is still online, giving the new address and, if they differ, the new MQTT credentials. Chapter 5 and chapter 17 cover the credential pitfall.

Housekeeping queries (optional)

The database is standard SQLite and can be inspected with the sqlite3 tool while the service runs (read-only queries are safe). Two examples for data-protection requests and retention (typical; take a backup first before any write):

-- everything logged about one fob
SELECT datetime(ts,'unixepoch'), door_name, decision, reason FROM events WHERE fob_code='A1B2C3' ORDER BY ts;

-- trim access events older than a year for one tenant
DELETE FROM events WHERE tenant_id=3 AND kind='access' AND ts < strftime('%s','now','-1 year');

Windows and development use

The binary also runs on Windows (accesscontroller.exe) with the same variables, which is handy for a bench set-up or a single-site installation on an existing office PC. Open port 1883 in Windows Firewall for the door network and use the PC's LAN IP as the adoption address. For anything more than a bench, host it on Linux behind a proxy as above.