Initial Setup
This section aims to make setting up your server to host an instance of BOMnipotent Server as easy as possible.
The setup consists of the following, necessary steps:
After that you can configure the server to your personal needs.
This section aims to make setting up your server to host an instance of BOMnipotent Server as easy as possible.
The setup consists of the following, necessary steps:
After that you can configure the server to your personal needs.
Several setup variants are presented here. You can pick the one best suited to your needs, and modify it at will.
After following the steps of one of the variants, your server has a default configuration and should be reachable from the internet. After that, you should create an admin user account .
The recommended and easiest setup for BOMnipotent Server uses docker compose . This variant of the setup will make BOMnipotent Server directly reachable from the internet. If you want to handle traffic through a reverse proxy, check out another setup instead.
The suggested file structure in the favourite directory of your server looks like this:
├── .env
├── bomnipotent_config
│ ├── config.toml
│ └── config.toml.default
└── compose.yaml
This tutorial will walk through the files and explain them one by one.
BOMnipotent server communicates with a database. Currently, only PostgreSQL is supported as a backend. The database is protected by a password. It is best practice to store the password inside a separate .env file instead of directly in the compose.yaml.
The name of the file must be “.env”, otherwise docker will not recognise it.
Your .env file should look like this:
BOMNIPOTENT_DB_PW=<your-database-password>
SMTP_SECRET=<your-smtp-authentication-secret>
If you are using a versioning system to store your setup, do not forget to add “.env” to your .gitignore or analogous ignore file!
BOMnipotent Server needs a configuration file, which is explained in more detail in another section .
The name of the file is arbitrary in principle, but the ready-to-deploy BOMnipotent Server docker container is set up to look for “config.toml”.
A minimal configuration looks like this:
# The db_url has the structure [db_client]://[user]:[password]@[container]:[port]/[db]
# Note that ${BOMNIPOTENT_DB_PW} references an environment variable.
db_url = "postgres://bomnipotent_user:${BOMNIPOTENT_DB_PW}@bomnipotent_db:5432/bomnipotent_db"
# Domain behind which bomnipotent server will be hosted
domain = "https://bomnipotent.<your-domain>.<top-level>"
[tls]
# The path to your full TLS certificate chain
certificate_chain_path = "/etc/ssl/certs/<your-TLS-certificate-chain.crt>"
# The path to your secret TLS key
secret_key_path = "/etc/ssl/private/<your-secret-TLS-key>"
[smtp]
# The username for your mail provider, typically your mail address
user = "<you@yourdomain.com>"
# The smtp endpoint of your mail provider
endpoint = "<your.smtp.host>"
# The secret to authenticate against the mail provider, typically your password
secret = "${SMTP_SECRET}"
# Publisher data according to the CSAF Standard linked below
[provider_metadata.publisher]
name = "<Provide the name of your organsiation>"
# Namespace of your organisation, in form of a complete URL
namespace = "https://<your-domain>.<top-level>"
# This is most likely the enum variant you want
category = "vendor"
# Contact details are optional and in free form
contact_details = "<For security inquiries, please contact us at...>"
Fill in the braces with your data.
The section about TLS configuration contains more detailed information to avoid common pitfalls.
If you prefer using a local smtp releay station, have a look at the necessary adjustments to the compose file.
The publisher data is used to comply with the OASIS CSAF standard .
The section about provider-metadata goes into more details what the fields actually mean.
It is recommended to store your config.toml file inside a dedicated directory, “bomnipotent_config” in this example. The docker compose file will grant read access to this folder. This setup has two advantages:
Many configuration values support hot reloading, meaning they can be modified without restarting the server.
After having set up your config.toml, you may want to copy it as for example config.toml.default, to be able to quickly restore your initial configuration. This is entirely optional, though.
The compose file is where you specify the container setup. Once it is running smoothly, it does not need to be modified very often, but initially understanding it can take some time if you are new to docker.
The file needs to be called “compose.yaml”, docker can be a bit pecky otherwise.
A completely ready to deploy compose file looks like this:
# Giving the setup a name is optional, it will be derived by docker otherwise.
name: bomnipotent_server_containers
# The docker containers need to communicate, and they need a network for that.
networks:
# This network needs a reference
bomnipotent_network:
# Since the containers are on the same docker host, "bridge" is a reasonable driver choice.
driver: bridge
# Giving the network the same name as the reference is ok.
name: bomnipotent_network
volumes:
# Define the volume for persistent storage of the database
bomnipotent_data:
driver: local
# The server itself also needs persistence if you do not want to activate the subscription after every reboot
bomnipotent_subscription:
driver: local
services:
bomnipotent_db:
# Name of the database container
container_name: bomnipotent_db
deploy:
resources:
limits:
# Limit the CPU usage to 0.5 cores
cpus: "0.5"
# Limit the memory usage to 512MB
memory: "512M"
environment:
# Set the database name
POSTGRES_DB: bomnipotent_db
# Set the database user
POSTGRES_USER: bomnipotent_user
# Set the database password from the .env file variable
POSTGRES_PASSWORD: ${BOMNIPOTENT_DB_PW}
healthcheck:
# Check if the database is ready
test: ["CMD-SHELL", "pg_isready -U bomnipotent_user -d bomnipotent_db"]
# Interval between health checks
interval: 60s
# Timeout for each health check
timeout: 10s
# Number of retries before considering the container unhealthy
retries: 5
# Start period before the first health check
start_period: 10s
# Use the specified PostgreSQL image
# You may ddjust the container tag at will
image: postgres:17
logging:
# Use the local logging driver
driver: local
options:
# Limit the log size to 10MB
max-size: "10m"
# Keep a maximum of 3 log files
max-file: "3"
networks:
# Connect to the specified network
- bomnipotent_network
# Restart the container if it has stopped for some reason other than a user command
restart: always
volumes:
# Mount the volume for persistent data storage
- bomnipotent_data:/var/lib/postgresql/data
bomnipotent_server:
# Name of the server container
container_name: bomnipotent_server
depends_on:
# Ensure the database service is healthy before starting the server
bomnipotent_db:
condition: service_healthy
deploy:
resources:
limits:
# Limit the CPU usage to 0.5 cores
cpus: "0.5"
# Limit the memory usage to 512MB
memory: "512M"
environment:
# Pass the database password on to the server.
BOMNIPOTENT_DB_PW: ${BOMNIPOTENT_DB_PW}
# Pass the SMTP secret on to the server.
SMTP_SECRET: ${SMTP_SECRET}
healthcheck:
# Check if the server is healthy
# Your TLS certificate is most likely not valid for "localhost"
# Hence the --insecure flag
test: ["CMD-SHELL", "curl --fail --insecure https://localhost:8443/health || exit 1"]
# Interval between health checks
interval: 60s
# Timeout for each health check
timeout: 10s
# Number of retries before considering the container unhealthy
retries: 5
# Start period before the first health check
start_period: 10s
# This is the official docker image running a BOMnipotent Server instance.
image: wwhsoft/bomnipotent_server:latest
logging:
# Use the local logging driver
driver: local
options:
# Limit the log size to 10MB
max-size: "10m"
# Keep a maximum of 3 log files
max-file: "3"
networks:
# Connect to the specified network
- bomnipotent_network
ports:
# Map port 443 on the host to port 8443 on the container
# This allows to connect to it via encrypted communication from the internet
- target: 8443
published: 443
# Restart the container if it has stopped for some reason other than a user command
restart: always
volumes:
# Bind mount the config folder on the host
- type: bind
source: ./bomnipotent_config
target: /etc/bomnipotent_server/configs/
read_only: true
# Bind mount the SSL directory, so that BOMnipotent can find the TLS certificate and key
- type: bind
source: /etc/ssl
target: /etc/ssl
read_only: true
# The subscription can be stored inside the container
- bomnipotent_subscription:/root/.config/bomnipotent
name: bomnipotent_server_containers
networks:
bomnipotent_network:
driver: bridge
name: bomnipotent_network
volumes:
bomnipotent_data:
driver: local
bomnipotent_subscription:
driver: local
services:
bomnipotent_db:
container_name: bomnipotent_db
deploy:
resources:
limits:
cpus: "0.5"
memory: "512M"
environment:
POSTGRES_DB: bomnipotent_db
POSTGRES_USER: bomnipotent_user
POSTGRES_PASSWORD: ${BOMNIPOTENT_DB_PW}
healthcheck:
test: ["CMD-SHELL", "pg_isready -U bomnipotent_user -d bomnipotent_db"]
interval: 60s
timeout: 10s
retries: 5
start_period: 10s
image: postgres:17
logging:
driver: local
options:
max-size: "10m"
max-file: "3"
networks:
- bomnipotent_network
restart: always
volumes:
- bomnipotent_data:/var/lib/postgresql/data
bomnipotent_server:
container_name: bomnipotent_server
depends_on:
bomnipotent_db:
condition: service_healthy
deploy:
resources:
limits:
cpus: "0.5"
memory: "512M"
environment:
BOMNIPOTENT_DB_PW: ${BOMNIPOTENT_DB_PW}
SMTP_SECRET: ${SMTP_SECRET}
healthcheck:
test: ["CMD-SHELL", "curl --fail --insecure https://localhost:8443/health || exit 1"]
interval: 60s
timeout: 10s
retries: 5
start_period: 10s
image: wwhsoft/bomnipotent_server:latest
logging:
driver: local
options:
max-size: "10m"
max-file: "3"
networks:
- bomnipotent_network
ports:
- target: 8443
published: 443
restart: always
volumes:
- type: bind
source: ./bomnipotent_config
target: /etc/bomnipotent_server/configs/
read_only: true
- type: bind
source: /etc/ssl
target: /etc/ssl
read_only: true
- bomnipotent_subscription:/root/.config/bomnipotent
Store this as “compose.yaml”. Then, call:
docker compose --detach
docker compose -d
Your server is now up and running!
Run “docker ps” to check if it is healthy.
This variant of the very similar setup with docker compose not only sets up a running BOMnipotent Server, but also an nginx reverse proxy.
The suggested file structure in the favourite directory of your server looks like this:
├── .env
├── bomnipotent_config
│ ├── config.toml
│ └── config.toml.default
├── proxy_config
│ └── conf.d
│ └── default.conf
└── compose.yaml
This tutorial will walk through the files and explain them one by one.
The use of nginx as the reverse proxy is merely a suggestion. You can substitute it with any other server software you prefer.
In very crude terms, the reverse proxy serves as a gateway to your server: It allows you to host several services (BOMnipotent Server, a website, etc.) behind the same IP address. Any request to one of your URLs will end up at the reverse proxy, which then passes them on to the correct service. This is how you land on a different website when you visit doc.bomnipotent.de than when you visit www.bomnipotent.de , although they are hosted behind the same IP address.
Nginx looks up its configuration in various locations. Later on in the compose.yaml we will use mount binding to sneakily inject our configuration into the nginx docker container.
You can use the following as the starting point for your default.conf:
# Rate limiting: Allows up to 5 requests per second per IP address, stored in a memory zone of 10 MB.
limit_req_zone $binary_remote_addr zone=api_limit:10m rate=5r/s;
# BOMnipotent Server
server {
# This makes the server listen on port 443, which is typically used for HTTPS.
listen 443 ssl http2;
# Replace this with the actual domain of your BOMnipotent Server.
server_name bomnipotent.your-domain.com;
# Replace this with the actual certificate for your domain.
ssl_certificate /etc/ssl/certs/your-domain-fullchain.crt;
# Replace this with the actual private key for your certificate.
ssl_certificate_key /etc/ssl/private/your-domain_private_key.key;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers on;
ssl_ciphers "ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384";
location / {
# Apply rate limiting
limit_req zone=api_limit burst=10 nodelay;
# This tells nginx to pass on requests to port 8080 of the docker container.
proxy_pass http://bomnipotent_server:8080;
proxy_set_header Host $host;
# The following lines assure that the BOMnipotent logs contain the IP of the sender,
# instead of the local IP of the reverse proxy.
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;
}
}
You probably want to add more “server” blocks – why else would you decide to set up a reverse proxy?
BOMnipotent server communicates with a database. Currently, only PostgreSQL is supported as a backend. The database is protected by a password. It is best practice to store the password inside a separate .env file instead of directly in the compose.yaml.
The name of the file must be “.env”, otherwise docker will not recognise it.
Your .env file should look like this:
BOMNIPOTENT_DB_PW=<your-database-password>
SMTP_SECRET=<your-smtp-authentication-secret>
If you are using a versioning system to store your setup, do not forget to add “.env” to your .gitignore or analogous ignore file!
BOMnipotent Server needs a configuration file, which is explained in more detail in another section .
The name of the file is arbitrary in principle, but the ready-to-deploy BOMnipotent Server docker container is set up to look for “config.toml”.
A minimal configuration for a BOMnipotent Server behind a reverse proxy looks like this:
# The db_url has the structure [db_client]://[user]:[password]@[container]:[port]/[db]
# Note that ${BOMNIPOTENT_DB_PW} references an environment variable.
db_url = "postgres://bomnipotent_user:${BOMNIPOTENT_DB_PW}@bomnipotent_db:5432/bomnipotent_db"
# Domain behind which bomnipotent server will be hosted
domain = "https://bomnipotent.<your-domain>.<top-level>"
[tls]
# TLS encryption is handled by the reverse proxy,
# BOMnipotent Server is not directly reachable from the internet.
allow_http = true
[smtp]
# The username for your mail provider, typically your mail address
user = "<you@yourdomain.com>"
# The smtp endpoint of your mail provider
endpoint = "<your.smtp.host>"
# The secret to authenticate against the mail provider, typically your password
secret = "${SMTP_SECRET}"
# Publisher data according to the CSAF Standard linked below
[provider_metadata.publisher]
name = "<Provide the name of your organsiation>"
# Namespace of your organisation, in form of a complete URL
namespace = "https://<your-domain>.<top-level>"
# This is most likely the enum variant you want
category = "vendor"
# Contact details are optional and in free form
contact_details = "<For security inquiries, please contact us at...>"
Fill in the braces with your data.
If you prefer using a local smtp releay station, have a look at the necessary adjustments to the compose file.
The publisher data is used to comply with the OASIS CSAF standard .
The section about provider-metadata goes into more details what the fields actually mean.
It is recommended to store your config.toml file inside a dedicated directory, “bomnipotent_config” in this example. The docker compose file will grant read access to this folder. This setup has two advantages:
Many configuration values support hot reloading, meaning they can be modified without restarting the server.
After having set up your config.toml, you may want to copy it as for example config.toml.default, to be able to quickly restore your initial configuration. This is entirely optional, though.
The compose file is where you specify the container setup. Once it is running smoothly, it does not need to be modified very often, but initially understanding it can take some time if you are new to docker.
The file needs to be called “compose.yaml”, docker can be a bit pecky otherwise.
A completely ready to deploy compose file looks like this:
# Giving the setup a name is optional, it will be derived by docker otherwise.
name: bomnipotent_server_containers
# The docker containers need to communicate, and they need a network for that.
networks:
# This network needs a reference
bomnipotent_network:
# Since the containers are on the same docker host, "bridge" is a reasonable driver choice.
driver: bridge
# Giving the network the same name as the reference is ok.
name: bomnipotent_network
# The reverse proxy needs to communicate with BOMnipotent Server, but not with the database.
proxy_network:
driver: bridge
name: proxy_network
volumes:
# Define the volume for persistent storage of the database
bomnipotent_data:
driver: local
# The server itself also needs persistence if you do not want to activate the subscription after every reboot
bomnipotent_subscription:
driver: local
services:
reverse_proxy:
# Name of the reverse proxy container
container_name: reverse_proxy
deploy:
resources:
limits:
# Limit the CPU usage to 0.5 cores
cpus: "0.5"
# Limit the memory usage to 512MB
memory: "512M"
healthcheck:
# Check if nginx is running and could parse the config.
test: ["CMD-SHELL", "nginx -t || exit 1"]
# Interval between health checks
interval: 60s
# Timeout for each health check
timeout: 10s
# Number of retries before considering the container unhealthy
retries: 3
# Start period before the first health check
start_period: 60s
image: nginx:latest
logging:
# Use the local logging driver
driver: local
options:
# Limit the log size to 10MB
max-size: "10m"
# Keep a maximum of 3 log files
max-file: "3"
networks:
# Connect to the specified network
- proxy_network
ports:
# Expose port 443 of the container
# This allows to connect to it via encrypted communication from the internet
- "443:443"
# Restart the container if it has stopped for some reason other than a user command
restart: on-failure
volumes:
# Bind mount the SSL directory, so that nginx can find the TLS certificate and key
- type: bind
source: /etc/ssl
target: /etc/ssl
read_only: true
# Bind mount the config folder on the host
- type: bind
source: ./proxy_config/conf.d
target: /etc/nginx/conf.d
read_only: true
bomnipotent_db:
# Name of the database container
container_name: bomnipotent_db
deploy:
resources:
limits:
# Limit the CPU usage to 0.5 cores
cpus: "0.5"
# Limit the memory usage to 512MB
memory: "512M"
environment:
# Set the database name
POSTGRES_DB: bomnipotent_db
# Set the database user
POSTGRES_USER: bomnipotent_user
# Set the database password from the .env file variable
POSTGRES_PASSWORD: ${BOMNIPOTENT_DB_PW}
healthcheck:
# Check if the database is ready
test: ["CMD-SHELL", "pg_isready -U bomnipotent_user -d bomnipotent_db"]
# Interval between health checks
interval: 60s
# Timeout for each health check
timeout: 10s
# Number of retries before considering the container unhealthy
retries: 5
# Start period before the first health check
start_period: 10s
# Use the specified PostgreSQL image
# You may ddjust the container tag at will
image: postgres:17
logging:
# Use the local logging driver
driver: local
options:
# Limit the log size to 10MB
max-size: "10m"
# Keep a maximum of 3 log files
max-file: "3"
networks:
# Connect to the specified network
- bomnipotent_network
# Restart the container if it has stopped for some reason other than a user command
restart: always
volumes:
# Mount the volume for persistent data storage
- bomnipotent_data:/var/lib/postgresql/data
bomnipotent_server:
# Name of the server container
container_name: bomnipotent_server
depends_on:
# Ensure the database service is healthy before starting the server
bomnipotent_db:
condition: service_healthy
deploy:
resources:
limits:
# Limit the CPU usage to 0.5 cores
cpus: "0.5"
# Limit the memory usage to 512MB
memory: "512M"
environment:
# Pass the database password on to the server.
BOMNIPOTENT_DB_PW: ${BOMNIPOTENT_DB_PW}
# Pass the SMTP secret on to the server.
SMTP_SECRET: ${SMTP_SECRET}
healthcheck:
# Check if the server is healthy
test: ["CMD-SHELL", "curl --fail http://localhost:8080/health || exit 1"]
# Interval between health checks
interval: 60s
# Timeout for each health check
timeout: 10s
# Number of retries before considering the container unhealthy
retries: 5
# Start period before the first health check
start_period: 10s
# This is the official docker image running a BOMnipotent Server instance.
image: wwhsoft/bomnipotent_server:latest
logging:
# Use the local logging driver
driver: local
options:
# Limit the log size to 10MB
max-size: "10m"
# Keep a maximum of 3 log files
max-file: "3"
networks:
# Connect the server to the reverse proxy
- proxy_network
# Connect the server to the database
- bomnipotent_network
# Restart the container if it has stopped for some reason other than a user command
restart: always
volumes:
# Bind mount the config folder on the host
- type: bind
source: ./bomnipotent_config
target: /etc/bomnipotent_server/configs/
read_only: true
# The subscription can be stored inside the container
- bomnipotent_subscription:/root/.config/bomnipotent
name: bomnipotent_server_containers
networks:
bomnipotent_network:
driver: bridge
name: bomnipotent_network
proxy_network:
driver: bridge
name: proxy_network
volumes:
bomnipotent_data:
driver: local
bomnipotent_subscription:
driver: local
services:
reverse_proxy:
container_name: reverse_proxy
deploy:
resources:
limits:
cpus: "0.5"
memory: "512M"
healthcheck:
test: ["CMD-SHELL", "nginx -t || exit 1"]
interval: 60s
timeout: 10s
retries: 3
start_period: 60s
image: nginx:latest
logging:
driver: local
options:
max-size: "10m"
max-file: "3"
networks:
- proxy_network
ports:
- "443:443"
restart: on-failure
volumes:
- type: bind
source: /etc/ssl
target: /etc/ssl
read_only: true
- type: bind
source: ./proxy_config/conf.d
target: /etc/nginx/conf.d
read_only: true
bomnipotent_db:
container_name: bomnipotent_db
deploy:
resources:
limits:
cpus: "0.5"
memory: "512M"
environment:
POSTGRES_DB: bomnipotent_db
POSTGRES_USER: bomnipotent_user
POSTGRES_PASSWORD: ${BOMNIPOTENT_DB_PW}
healthcheck:
test: ["CMD-SHELL", "pg_isready -U bomnipotent_user -d bomnipotent_db"]
interval: 60s
timeout: 10s
retries: 5
start_period: 10s
image: postgres:17
logging:
driver: local
options:
max-size: "10m"
max-file: "3"
networks:
- bomnipotent_network
restart: always
volumes:
- bomnipotent_data:/var/lib/postgresql/data
bomnipotent_server:
container_name: bomnipotent_server
depends_on:
bomnipotent_db:
condition: service_healthy
deploy:
resources:
limits:
cpus: "0.5"
memory: "512M"
environment:
BOMNIPOTENT_DB_PW: ${BOMNIPOTENT_DB_PW}
SMTP_SECRET: ${SMTP_SECRET}
healthcheck:
test: ["CMD-SHELL", "curl --fail http://localhost:8080/health || exit 1"]
interval: 60s
timeout: 10s
retries: 5
start_period: 10s
image: wwhsoft/bomnipotent_server:latest
logging:
driver: local
options:
max-size: "10m"
max-file: "3"
networks:
- proxy_network
- bomnipotent_network
restart: always
volumes:
- type: bind
source: ./bomnipotent_config
target: /etc/bomnipotent_server/configs/
read_only: true
- bomnipotent_subscription:/root/.config/bomnipotent
Store this as “compose.yaml”. Then, call:
docker compose --detach
docker compose -d
Your server is now up and running!
Run “docker ps” to check if it is healthy.
You are not required to run the official BOMnipotent Server docker container . Instead, you can download and directly run the BOMnipotent Server binary as a standalone application.
This setup only really makes sense for version 0.4.2 onwards, because the server did not offer port adjustments and logging to files before that.
BOMnipotent Server requires a PostgreSQL database for storing its data. The setup depends on your server operating system.
On the most common distributions, PostgreSQL is offered as a package. You can install it via for example apt/apt-get/aptitude:
sudo apt-get install postgresql postgresql-contrib
Now PostgeSQL is running as a service. To further modify it, you need to become the postgres system user:
sudo -i -u postgres
Now you can open the interactive PostgreSQL shell:
psql
Inside the shell, you need to add the user “bomnipotent_user”, a password, and create a database “bomnipotent_db”:
CREATE USER bomnipotent_user WITH PASSWORD 'your-password';
CREATE DATABASE bomnipotent_db OWNER bomnipotent_user;
GRANT ALL PRIVILEGES ON DATABASE bomnipotent_db TO bomnipotent_user;
\q
You could use different names for the user and database, but would need to adjust the “db_url” entry of your config file accordingly.
Finally, restart PostgreSQL and switch back to your regular user:
sudo systemctl restart postgresql;
exit
For Windows, PostgreSQL offers an interactive installer .
After it has completed, PostgeSQL is running as a service. Open an interactive PostgreSQL shell by starting an admin console and prompting:
psql -U postgres
Inside the shell, you need to add the user “bomnipotent_user”, a password, and create a database “bomnipotent_db”:
CREATE USER bomnipotent_user WITH PASSWORD 'your-password';
CREATE DATABASE bomnipotent_db OWNER bomnipotent_user;
GRANT ALL PRIVILEGES ON DATABASE bomnipotent_db TO bomnipotent_user;
\q
You could use different names for the user and database, but would need to adjust the “db_url” entry of your config file accordingly.
If you only want to run BOMnipotent Server as a standalone application, but still want to containerise PostgreSQL, you can spin it up via:
docker run --name bomnipotent_db \
-e POSTGRES_DB=bomnipotent_db \
-e POSTGRES_USER=bomnipotent_user \
-e POSTGRES_PASSWORD=<your-password> \
-p 5432:5432 \
-v pgdata:/var/lib/postgresql/data \
-d postgres:latest
This creates a container named “bomnipotent_db”, with a database also called “bomnipotent_db”, a user called “bomnipotent_user”, and a password that you need to set. It exposes port 5432 of the container, persists the data in a docker volume, and spins up the “postgres:latest” image in detached mode.
You could use different names for the user and database, but would need to adjust the “db_url” entry of your config file accordingly.
The suggested file structure in the favourite directory of your server looks like this:
├── bomnipotent_config
│ ├── .env
│ ├── config.toml
│ └── config.toml.default
└── bomnipotent_server
This tutorial will walk through the files and explain them one by one.
BOMnipotent server communicates with a database. Currently, only PostgreSQL is supported as a backend. The database is protected by a password. It is best practice to store the password inside a separate .env file instead of directly in the compose.yaml.
The name of the file must be “.env”, otherwise BOMnipotent Server will not recognise it.
Your .env file should look like this:
BOMNIPOTENT_DB_PW=<your-database-password>
SMTP_SECRET=<your-smtp-authentication-secret>
If you are using a versioning system to store your setup, do not forget to add “.env” to your .gitignore or analogous ignore file!
BOMnipotent Server needs a configuration file, which is explained in more detail in another section .
The name of the file is arbitrary.
A minimal configuration looks like this:
# The db_url has the structure [db_client]://[user]:[password]@[address]:[port]/[db]
# Note that ${BOMNIPOTENT_DB_PW} references an environment variable.
db_url = "postgres://bomnipotent_user:${BOMNIPOTENT_DB_PW}@localhost:5432/bomnipotent_db"
# Domain behind which bomnipotent server will be hosted
domain = "https://bomnipotent.<your-domain>.<top-level>"
# Bind to the typical port used for HTTPS
https_port = 443
[log]
# Tell the server to log to a file instead of to stdout
file = "/var/log/bomnipotent.log"
[tls]
# The path to your full TLS certificate chain
certificate_chain_path = "/etc/ssl/certs/<your-TLS-certificate-chain.crt>"
# The path to your secret TLS key
secret_key_path = "/etc/ssl/private/<your-secret-TLS-key>"
[smtp]
# The username for your mail provider, typically your mail address
user = "<you@yourdomain.com>"
# The smtp endpoint of your mail provider
endpoint = "<your.smtp.host>"
# The secret to authenticate against the mail provider, typically your password
secret = "${SMTP_SECRET}"
# Publisher data according to the CSAF Standard linked below
[provider_metadata.publisher]
name = "<Provide the name of your organsiation>"
# Namespace of your organisation, in form of a complete URL
namespace = "https://<your-domain>.<top-level>"
# This is most likely the enum variant you want
category = "vendor"
# Contact details are optional and in free form
contact_details = "<For security inquiries, please contact us at...>"
Fill in the braces with your data.
The section about TLS configuration contains more detailed information to avoid common pitfalls.
If you prefer using a local smtp releay station, have a look at the necessary adjustments to the compose file.
The publisher data is used to comply with the OASIS CSAF standard .
The section about provider-metadata goes into more details what the fields actually mean.
It is recommended to store your config.toml file inside a dedicated directory, “bomnipotent_config” in this example. BOMnipotent Server will watch the directory for any changes, meaning that it has less to watch the less files are in the folder. The server will try to reload the configuration file and the .env file if either have changed.
Many configuration values support hot reloading, meaning they can be modified without restarting the server.
After having set up your config.toml, you may want to copy it as for example config.toml.default, to be able to quickly restore your initial configuration. This is entirely optional, though.
This is the binary that runs BOMnipotent Server. You can download any version for your server platform from www.bomnipotent.de .
In principle, all BOMnipotent Server needs to run is to know the path to its config file. If you run the binary and provide the path as the first argument, you have created a working server instance. However, your terminal is now eternally blocked, and the service will not restart if you reboot your system. The rest of this section only serves to ensure that the operating system properly supports the server.
Unlike BOMnipotent Client, which runs under all major operating systems, BOMnipotent Server is currently only supported under Linux and Windows. If you want to host it on a server running MacOS, please create an issue .
This setup requires your distribution to incorporate systemd.
If you’re not sure if it does, it probably does.
If you’re sure that it does not, you probably don’t need these instructions.
Create the file “/etc/systemd/system/bomnipotent.service” with the following content:
[Unit]
Description=BOMnipotent Server
After=network.target
[Service]
ExecStart=/path/to/bomnipotent_server /path/to/bomnipotent_config/config.toml
WorkingDirectory=/path/to/bomnipotent_config
Restart=on-failure
User=<youruser>
[Install]
WantedBy=multi-user.target
Make sure to adjust the values to your specific server. Then run:
sudo systemctl daemon-reexec
sudo systemctl enable --now bomnipotent.service
Open the Task Scheduler (taskschd.msc).
In the right panel, click Create Task.
In the “General” tab:
In the “Triggers” tab:
In the “Actions” tab:
Click “OK” to save the task.
Several interactions with BOMnipotent require a user with admin rights. One of these is granting a new user admin rights. This means that some kind of bootstrapping mechanism is required.
First, you will need to create a user account :
bomnipotent_client --domain=<server> user request <your-email>
bomnipotent_client -d <server> user request <your-email>
[INFO] Generating new key pair
[INFO] Storing secret key to "/home/simon/.config/bomnipotent/secret_key.pem" and public key to "/home/simon/.config/bomnipotent/public_key.pem"
[INFO] User request submitted. It now needs to be confirmed by a user manager.
To make things a litle less verbose, let’s store the domain of your server and your email address in a user session :
bomnipotent_client --domain=<server> --email=<your-email> session login
bomnipotent_client -d <server> -e <your-email> session login
[INFO] Storing session data in /home/simon/.config/bomnipotent/session.toml
Due to security reasons, the user needs to already exist in the database at this point. Otherwise, a malicious actor could anticipate the email address you use for your admin, and make their own request at an opportune time. To prevent this, the tmp admin mechanism blocks all requests to newly add this particular user to the database.
Next, you will become the user manager that was mentioned in the server reply: Log onto your server machine, and in your server configuration file prepend
tmp_admin = "<your-email>"
It is important to add this line at the beginning of the file, otherwise BOMnipotent might try to interpret this field as part of another section.
Your server logs should now show that the configuration has been reloaded, in addition to the user request you made earlier.
docker logs bomnipotent_server
...
2025-03-06 11:30:15 +00:00 [INFO] Received POST request from 101.102.103.104 to https://bomnipotent.wwh-soft.com/user/info@wwh-soft.com
2025-03-06 11:32:56 +00:00 [INFO] Configuration successfully reloaded from "/etc/bomnipotent_server/configs/config.toml"
...
The server now treats authenticated requests from that user as if that user was an admin. To become a permanent admin, you first need to approve your user request. Back on the client, call
bomnipotent_client user approve <your-email>
[INFO] Changed status of info@wwh-soft.com to APPROVED
Now you can make yourself a full server admin:
bomnipotent_client user-role add <your-email> admin
[INFO] Added role to user
The stat of being a temporary admin is intended to be, well, temporary. The server logs a warning whenever you use temporary access rights:
docker logs bomnipotent_server -n 4
2025-03-06 14:51:35 +00:00 [INFO] Received POST request from info@wwh-soft.com to https://bomnipotent.wwh-soft.com/user/info@wwh-soft.com/roles
2025-03-06 14:51:35 +00:00 [WARN] Temporary admin functionality is enabled for info@wwh-soft.com
2025-03-06 14:51:35 +00:00 [INFO] User info@wwh-soft.com was authenticated as a temporary admin
2025-03-06 14:51:35 +00:00 [INFO] Temporary admin info@wwh-soft.com has permission USER_MANAGEMENT to perform this action
But now that you have successfully made yourself a permanent admin, you can and should remove the “tmp_admin” field from the configuration file again.
You are now ready to activate your subscription .
Most actions that add data to your BOMnipotent database require an active subscription, while reading and removing data do not. This policy ensures that your users do not loose access to the existing data should you one day choose to stop paying for the product.
Commercial entities like companies can acquire a subscription on bomnipotent.de . If you are a non-commercial entity, you can use BOMnipotent without any charge. Request access by sending an email to info@wwh-soft.com .
Shortly after you have acquired a subscription, you will receive an email containing your subscription key.
Subscriptions can only be managed by a user with the “admin” role. Create one if you haven’t already.
Logged in as that user, call
bomnipotent_client subscription activate <your-subscription-key>
[INFO] Successfully stored subscription key.
To check the current status of your subscription, run
bomnipotent_client subscription status
╭──────────┬─────────────┬─────────────────────┬─────────────────────────┬─────────────────────────┬───────────────────────────╮
│ Key │ Product │ Subscription Status │ Valid Until │ Last Updated │ Assessment │
├──────────┼─────────────┼─────────────────────┼─────────────────────────┼─────────────────────────┼───────────────────────────┤
│ ***ccfb3 │ BOMnipotent │ active │ 2025-04-10 17:26:29 UTC │ 2025-03-10 16:26:29 UTC │ The subscription is valid │
│ │ │ │ │ │ . │
╰──────────┴─────────────┴─────────────────────┴─────────────────────────┴─────────────────────────┴───────────────────────────╯