Run On-Premises

Once you have installed Pro Custodibus CE or EE, you can start up the components of Pro Custodibus, and create an Initial User with which to log in.

Docker

If you installed Pro Custodibus with the generate-docker-compose.sh script, simply navigate to the directory containing the docker-compose.yml file and run docker-compose up:

$ cd /srv/containers/procustodibus
$ sudo docker-compose up
Creating network "procustodibus_default" with the default driver
Creating volume "procustodibus_db" with default driver
Pulling api (procustodibus/api-ee:latest)...
latest: Pulling from procustodibus/api-ee
1d5252f66ea9: Pull complete
bc527e853129: Pull complete
219e304fff12: Pull complete
57679093591f: Pull complete
6551e33de23b: Pull complete
3660ffe155dd: Pull complete
Digest: sha256:9749ece50ddace165b48701bc4036711c13d4d239420c6ef0363d0c6755e08d4
Status: Downloaded newer image for procustodibus/api-ee:latest
Pulling app (procustodibus/app-ee:latest)...
latest: Pulling from procustodibus/app-ee
4db1b89c0bd1: Pull complete
bd338968799f: Pull complete
6a107772494d: Pull complete
9f05b0cc5f6e: Pull complete
4c5efdb87c4a: Pull complete
c8794a7158bf: Pull complete
8de2a93581dc: Pull complete
768e67c521a9: Pull complete
40e01f98c096: Pull complete
cc0c6234f563: Pull complete
c32ed97c081d: Pull complete
4f4fb700ef54: Pull complete
Digest: sha256:b106dd4852aae6a9f56f126872a925e55472dd51564f5a72589bc8a1a6a56522
Status: Downloaded newer image for procustodibus/app-ee:latest
Pulling db (postgres:alpine)...
alpine: Pulling from library/postgres
31e352740f53: Pull complete
d7c8ef16402f: Pull complete
36cb57831f52: Pull complete
a120e2610875: Pull complete
64f9e9ad23bd: Pull complete
dd2a4281faaa: Pull complete
daef310ca2c6: Pull complete
c47c060e762a: Pull complete
Digest: sha256:48d8422c6ae570a5bda52f07548b8e65dd055ac0b661f25b44b20e8cff2f75f0
Status: Downloaded newer image for postgres:alpine
Creating procustodibus_app_1 ... done
Creating procustodibus_db_1  ... done
Creating procustodibus_api_1 ... done
Attaching to procustodibus_db_1, procustodibus_app_1, procustodibus_api_1
app_1  | Mon Aug  7 01:46:57 UTC 2023 generate dummy cert
db_1   | The files belonging to this database system will be owned by user "postgres".
db_1   | This user must also own the server process.
db_1   |
db_1   | The database cluster will be initialized with locale "en_US.utf8".
db_1   | The default database encoding has accordingly been set to "UTF8".
db_1   | The default text search configuration will be set to "english".
db_1   |
db_1   | Data page checksums are disabled.
db_1   |
db_1   | fixing permissions on existing directory /var/lib/postgresql/data ... ok
db_1   | creating subdirectories ... ok
db_1   | selecting dynamic shared memory implementation ... posix
db_1   | selecting default max_connections ... 100
db_1   | selecting default shared_buffers ... 128MB
app_1  | 2023/08/07 01:46:57 [notice] 24#24: using the "epoll" event method
app_1  | 2023/08/07 01:46:57 [notice] 24#24: nginx/1.25.1
app_1  | 2023/08/07 01:46:57 [notice] 24#24: built by gcc 12.2.1 20220924 (Alpine 12.2.1_git20220924-r4)
app_1  | 2023/08/07 01:46:57 [notice] 24#24: OS: Linux 5.19.0-1029-aws
app_1  | 2023/08/07 01:46:57 [notice] 24#24: getrlimit(RLIMIT_NOFILE): 1048576:1048576
app_1  | 2023/08/07 01:46:57 [notice] 24#24: start worker processes
app_1  | 2023/08/07 01:46:57 [notice] 24#24: start worker process 26
app_1  | 2023/08/07 01:46:57 [notice] 24#24: start worker process 27
db_1   | selecting default time zone ... UTC
db_1   | creating configuration files ... ok
db_1   | running bootstrap script ... ok
db_1   | performing post-bootstrap initialization ... sh: locale: not found
db_1   | 2023-08-07 01:46:58.049 UTC [30] WARNING:  no usable system locales were found
db_1   | ok
db_1   | syncing data to disk ... ok
db_1   |
db_1   |
db_1   | Success. You can now start the database server using:
db_1   |
db_1   |     pg_ctl -D /var/lib/postgresql/data -l logfile start
db_1   |
db_1   | initdb: warning: enabling "trust" authentication for local connections
db_1   | initdb: hint: You can change this by editing pg_hba.conf or using the option -A, or --auth-local and --auth-host, the next time you run initdb.
db_1   | waiting for server to start....2023-08-07 01:46:58.957 UTC [36] LOG:  starting PostgreSQL 15.3 on x86_64-pc-linux-musl, compiled by gcc (Alpine 12.2.1_git20220924-r10) 12.2.1 20220924, 64-bit
db_1   | 2023-08-07 01:46:58.959 UTC [36] LOG:  listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432"
db_1   | 2023-08-07 01:46:58.966 UTC [39] LOG:  database system was shut down at 2023-08-07 01:46:58 UTC
db_1   | 2023-08-07 01:46:58.973 UTC [36] LOG:  database system is ready to accept connections
api_1  | 01:46:58.989 [error] Postgrex.Protocol (#PID<0.167.0>) failed to connect: ** (DBConnection.ConnectionError) tcp connect (db:5432): connection refused - :econnrefused
api_1  | 01:46:58.989 [error] Postgrex.Protocol (#PID<0.166.0>) failed to connect: ** (DBConnection.ConnectionError) tcp connect (db:5432): connection refused - :econnrefused
db_1   |  done
db_1   | server started
db_1   |
db_1   | /usr/local/bin/docker-entrypoint.sh: running /docker-entrypoint-initdb.d/init.sql
db_1   | CREATE ROLE
db_1   | CREATE DATABASE
db_1   |
db_1   |
db_1   | waiting for server to shut down...2023-08-07 01:46:59.123 UTC [36] LOG:  received fast shutdown request
db_1   | .2023-08-07 01:46:59.125 UTC [36] LOG:  aborting any active transactions
db_1   | 2023-08-07 01:46:59.128 UTC [36] LOG:  background worker "logical replication launcher" (PID 42) exited with exit code 1
db_1   | 2023-08-07 01:46:59.129 UTC [37] LOG:  shutting down
db_1   | 2023-08-07 01:46:59.132 UTC [37] LOG:  checkpoint starting: shutdown immediate
db_1   | 2023-08-07 01:46:59.188 UTC [37] LOG:  checkpoint complete: wrote 927 buffers (5.7%); 0 WAL file(s) added, 0 removed, 0 recycled; write=0.044 s, sync=0.005 s, total=0.059 s; sync files=257, longest=0.002 s, average=0.001 s; distance=4226 kB, estimate=4226 kB
db_1   | 2023-08-07 01:46:59.195 UTC [36] LOG:  database system is shut down
db_1   |  done
db_1   | server stopped
db_1   |
db_1   | PostgreSQL init process complete; ready for start up.
db_1   |
db_1   | 2023-08-07 01:46:59.251 UTC [1] LOG:  starting PostgreSQL 15.3 on x86_64-pc-linux-musl, compiled by gcc (Alpine 12.2.1_git20220924-r10) 12.2.1 20220924, 64-bit
db_1   | 2023-08-07 01:46:59.252 UTC [1] LOG:  listening on IPv4 address "0.0.0.0", port 5432
db_1   | 2023-08-07 01:46:59.252 UTC [1] LOG:  listening on IPv6 address "::", port 5432
db_1   | 2023-08-07 01:46:59.255 UTC [1] LOG:  listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432"
db_1   | 2023-08-07 01:46:59.261 UTC [52] LOG:  database system was shut down at 2023-08-07 01:46:59 UTC
db_1   | 2023-08-07 01:46:59.267 UTC [1] LOG:  database system is ready to accept connections
api_1  | 01:47:00.269 [info] initializing database
api_1  | 01:47:01.292 [info] database initialized successfully
api_1  | 01:47:01.940 [info] == Running 20200101000000 Api.Repo.Migrations.CreateSuperArcemOrganization.up/0 forward
api_1  | 01:47:01.969 [info] == Migrated 20200101000000 in 0.0s
app_1  | Mon Aug  7 01:47:02 UTC 2023 run certbot
app_1  | Saving debug log to /var/log/letsencrypt/letsencrypt.log
app_1  | Account registered.
app_1  | Requesting a certificate for custos.internal.example.net
api_1  | 01:47:08.094 [info] Running ApiWeb.Endpoint with cowboy 2.10.0 at :::4000 (http)
api_1  | 01:47:08.102 [info] Access ApiWeb.Endpoint at https://custos.internal.example.net
app_1  | 34.212.35.223 - - [07/Aug/2023:01:47:16 +0000] "GET /.well-known/acme-challenge/u2Gd2NvhU_1TyYyolrcVW7_epJ7dTvzwDFeMOF7M3iA HTTP/1.1" 200 87 "-" "Mozilla/5.0 (compatible; Let's Encrypt validation server; +https://www.letsencrypt.org)" "-"
app_1  | 18.118.32.253 - - [07/Aug/2023:01:47:16 +0000] "GET /.well-known/acme-challenge/u2Gd2NvhU_1TyYyolrcVW7_epJ7dTvzwDFeMOF7M3iA HTTP/1.1" 200 87 "-" "Mozilla/5.0 (compatible; Let's Encrypt validation server; +https://www.letsencrypt.org)" "-"
app_1  | 23.178.112.203 - - [07/Aug/2023:01:47:16 +0000] "GET /.well-known/acme-challenge/u2Gd2NvhU_1TyYyolrcVW7_epJ7dTvzwDFeMOF7M3iA HTTP/1.1" 200 87 "-" "Mozilla/5.0 (compatible; Let's Encrypt validation server; +https://www.letsencrypt.org)" "-"
app_1  |
app_1  | Successfully received certificate.
app_1  | Certificate is saved at: /etc/letsencrypt/live/custos.internal.example.net/fullchain.pem
app_1  | Key is saved at:         /etc/letsencrypt/live/custos.internal.example.net/privkey.pem
app_1  | This certificate expires on 2023-11-05.
app_1  | These files will be updated when the certificate renews.
app_1  | NEXT STEPS:
app_1  | - The certificate will need to be renewed before it expires. Certbot can automatically renew the certificate in the background, but you may need to take steps to enable that functionality. See https://certbot.org/renewal-setup for instructions.
app_1  |
app_1  | - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
app_1  | If you like Certbot, please consider supporting our work by:
app_1  |  * Donating to ISRG / Let's Encrypt:   https://letsencrypt.org/donate
app_1  |  * Donating to EFF:                    https://eff.org/donate-le
app_1  | - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
app_1  | 2023/08/07 01:47:21 [notice] 14#14: signal process started
app_1  | 2023/08/07 01:47:21 [notice] 24#24: signal 1 (SIGHUP) received from 14, reconfiguring
app_1  | 2023/08/07 01:47:21 [notice] 24#24: reconfiguring
app_1  | 2023/08/07 01:47:21 [notice] 24#24: using the "epoll" event method
app_1  | 2023/08/07 01:47:21 [notice] 24#24: start worker processes
app_1  | 2023/08/07 01:47:21 [notice] 24#24: start worker process 32
app_1  | 2023/08/07 01:47:21 [notice] 24#24: start worker process 33
app_1  | 2023/08/07 01:47:21 [notice] 26#26: gracefully shutting down
app_1  | 2023/08/07 01:47:21 [notice] 26#26: exiting
app_1  | 2023/08/07 01:47:21 [notice] 27#27: gracefully shutting down
app_1  | 2023/08/07 01:47:21 [notice] 26#26: exit
app_1  | 2023/08/07 01:47:21 [notice] 27#27: exiting
app_1  | 2023/08/07 01:47:21 [notice] 27#27: exit
app_1  | 2023/08/07 01:47:21 [notice] 24#24: signal 17 (SIGCHLD) received from 27
app_1  | 2023/08/07 01:47:21 [notice] 24#24: worker process 26 exited with code 0
app_1  | 2023/08/07 01:47:21 [notice] 24#24: worker process 27 exited with code 0
app_1  | 2023/08/07 01:47:21 [notice] 24#24: signal 29 (SIGIO) received

This will start up the API server, database, and app UI container concurrently. You may see some errors like the following from the API server until the database has been initialized:

api_1  | 01:46:58.989 [error] Postgrex.Protocol (#PID<0.167.0>) failed to connect: ** (DBConnection.ConnectionError) tcp connect (db:5432): connection refused - :econnrefused

Once the API server prints the following line, the API is up, connected to the database, and fully operational:

api_1  | 01:47:08.102 [info] Access ApiWeb.Endpoint at https://custos.internal.example.net

Certbot Initialization

However, if you are Using Let’s Encrypt Certbot, the first time you start up, you’ll still have to wait another half-minute or so for the Certbot to acquire the TLS certificate needed for you to successfully connect to the API and app UI.

First you should see the Certbot challenges show up in the app container’s logs:

app_1  | 34.212.35.223 - - [07/Aug/2023:01:47:16 +0000] "GET /.well-known/acme-challenge/u2Gd2NvhU_1TyYyolrcVW7_epJ7dTvzwDFeMOF7M3iA HTTP/1.1" 200 87 "-" "Mozilla/5.0 (compatible; Let's Encrypt validation server; +https://www.letsencrypt.org)" "-"
app_1  | 18.118.32.253 - - [07/Aug/2023:01:47:16 +0000] "GET /.well-known/acme-challenge/u2Gd2NvhU_1TyYyolrcVW7_epJ7dTvzwDFeMOF7M3iA HTTP/1.1" 200 87 "-" "Mozilla/5.0 (compatible; Let's Encrypt validation server; +https://www.letsencrypt.org)" "-"
app_1  | 23.178.112.203 - - [07/Aug/2023:01:47:16 +0000] "GET /.well-known/acme-challenge/u2Gd2NvhU_1TyYyolrcVW7_epJ7dTvzwDFeMOF7M3iA HTTP/1.1" 200 87 "-" "Mozilla/5.0 (compatible; Let's Encrypt validation server; +https://www.letsencrypt.org)" "-"

Then you should see messages announcing the acquisition of the certificate:

app_1  | Successfully received certificate.
app_1  | Certificate is saved at: /etc/letsencrypt/live/custos.internal.example.net/fullchain.pem
app_1  | Key is saved at:         /etc/letsencrypt/live/custos.internal.example.net/privkey.pem

And finally you should see messages announcing that NGINX is reloading its configuration (to use the new cert):

app_1  | 2023/08/07 01:47:21 [notice] 14#14: signal process started
app_1  | 2023/08/07 01:47:21 [notice] 24#24: signal 1 (SIGHUP) received from 14, reconfiguring
app_1  | 2023/08/07 01:47:21 [notice] 24#24: reconfiguring

App Web UI

If you installed the app UI natively (instead of via Docker), start up the webserver, if it’s not already running.

You should be able to access the app UI at the canonical URL that you chose for the app (such as https://procustodibus.example.com):

$ curl -sS https://procustodibus.example.com/ | head
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <link rel="icon" href="/favicon.ico">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Pro Custodibus</title>
    <link rel="apple-touch-icon" href="/img/icons/apple-touch-icon-180x180.png" sizes="180x180">
    <link rel="mask-icon" href="/img/icons/icon.svg" color="#eeeee4">
    <meta name="theme-color" content="#881111">

If you configured the webserver correctly, you should see the same page with any path for the same domain name (since the app is a SPA):

$ curl -sS https://procustodibus.example.com/foo/bar | head
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <link rel="icon" href="/favicon.ico">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Pro Custodibus</title>
    <link rel="apple-touch-icon" href="/img/icons/apple-touch-icon-180x180.png" sizes="180x180">
    <link rel="mask-icon" href="/img/icons/icon.svg" color="#eeeee4">
    <meta name="theme-color" content="#881111">

Database

If you installed the database natively (instead of via Docker), start up the database, if it’s not already running:

$ sudo systemctl start postgresql

On the machine hosting the API server, you should be able to connect to the database using the same username and password as you configured in the /etc/default/procustodibus-api settings for the API server:

$ psql --host db.example.com --user procustodibus_user --password procustodibus_db
Password:
psql (14.9 (Ubuntu 14.9-0ubuntu0.22.04.1))
SSL connection (protocol: TLSv1.3, cipher: TLS_AES_256_GCM_SHA384, bits: 256, compression: off)
Type "help" for help.

+procustodibus_db=>

API Server

If you installed the API server natively (instead of via Docker), start up the API service:

$ sudo systemctl start procustodibus-api

If you tail its logs, you should see the following output:

$ journalctl -u procustodibus-api -f
Aug 07 01:33:19 colossus systemd[1]: Started Pro Custodibus API.
Aug 07 01:33:21 colossus start.sh[127438]: 01:33:21.239 [info] initializing database
Aug 07 01:33:21 colossus start.sh[127438]: 01:33:21.929 [info] database initialized successfully
Aug 07 01:33:22 colossus start.sh[127438]: 01:33:22.334 [info] == Running 20200101000000 Api.Repo.Migrations.CreateSuperArcemOrganization.up/0 forward
Aug 07 01:33:22 colossus start.sh[127438]: 01:33:22.347 [info] == Migrated 20200101000000 in 0.0s
Aug 07 01:33:26 colossus start.sh[127548]: 01:33:26.031 [info] Running ApiWeb.Endpoint with cowboy 2.10.0 at :::4000 (http)
Aug 07 01:33:26 colossus start.sh[127548]: 01:33:26.040 [info] Access ApiWeb.Endpoint at http://localhost:4000

Test Request

Once the API server is up and running, you should be able to send a test request to it via cURL:

$ curl -w'\n' https://custos.internal.example.net/api/health
[
  {
    "error": null,
    "healthy": true,
    "name": "DB",
    "time": 4051
  }
]

The request should appear like this in the logs for the Docker containers:

api_1  | 01:47:40.050 request_id=F3ojVXmhI1qA_ZcAAAFi remote_ip=::ffff:172.17.0.3 [info] GET /health
api_1  | 01:47:40.055 request_id=F3ojVXmhI1qA_ZcAAAFi remote_ip=::ffff:172.17.0.3 [info] Sent 200 in 4ms
app_1  | 172.17.0.1 - - [07/Aug/2023:01:47:40 +0000] "GET /api/health HTTP/1.1" 200 86 "-" "curl/7.81.0" "-"

Or like this in the API server’s logs (if you installed natively):

Aug 07 01:33:39 colossus start.sh[127548]: 01:33:39.057 request_id=F34iZ8dA74dw2ukAAAEi remote_ip=::ffff:127.0.0.1 [info] GET /health
Aug 07 01:33:39 colossus start.sh[127548]: 01:33:39.059 request_id=F34iZ8dA74dw2ukAAAEi remote_ip=::ffff:127.0.0.1 [info] Sent 200 in 2ms

Initial User

To start using Pro Custodibus, you must first create an initial admin user. Open up a web browser, and navigate to the following URL (replacing procustodibus.example.com with the actual DNS name you configured for Pro Custodibus):

https://procustodibus.example.com/signup

This should load the Sign Up page. On this page you will create a new account for your organization, with you as its administrator. You can create more user accounts for other users in this organization once you sign up.

Organization Name

Enter your organization’s name, like “Remington Rand UNIVAC Lab” in the Organization Name field. This name will be used as the display name for your organization on various pages in the UI. There are no character restrictions, and you can change it later.

Your Name

Enter your own name, like “Grace Hopper” in the Your Name field. This name will be used as the display name for you on various pages in the UI. There are no character restrictions, and you can change it later.

Email Address

Optionally, enter your own email address, like “grace@example.com” in the Email Address field.

If you enter an email address (and you’ve configured the API with a working SMTP server), Pro Custodibus will send an email to this address with your login ID. Note that you’ll need to click on the link included in this email in order to receive any further emails from Pro Custodibus (including password resets or security alerts).

You can change this address later, as well as add other additional email addresses.

Password

Enter the password you want to use for log-in in the Password field. There are no character restrictions, other than it must be at least 16 characters long. You can change it later.

Click the “eye” icon on the right side of the Password field to show the characters you’ve typed in.

Signup Key

Enter the value of the API’s SIGNUP_KEY environment variable in the Signup Key field.

If you installed Pro Custodibus with the generate-docker-compose.sh script, you can find the value of this variable in the generated api.env file. If you installed the API server natively, check its /etc/default/procustodibus-api file.

If you open up this file and the SIGNUP_KEY variable is blank or has not been set, set it to a short, un-guessable string like “abcd1234”, and then restart the API.

Form Submit

Click the Sign Up button to submit the form and complete the sign-up process. A new account will be created for your organization, with a new user account for you. You will automatically be logged into Pro Custodibus with your new account.

Write down the Login ID value displayed on the resulting page. Your login ID will be a short, random string of letters and numbers, like “Ahg1opVcGX”. You will need to enter this ID into the Login ID field of the Log In form in the future, whenever you log into Pro Custodibus.

Next Steps

Use the app UI to add a host for the first WireGuard host you want to monitor.