Installation

Requirements, installation and initial setup of the oPBWeb stack

Audience: Technical administration

Overview

oPBWeb runs as a Docker Compose stack on a Linux host that can reach the opsi configserver. The stack consists of these services:

ServicePurpose
frontendnginx serving the web interface and this manual; the only service exposed to the outside
apiREST API (FastAPI), sign-in, database migrations
workerBackground jobs: build, install, depot sync, connection to the opsi server
dbMariaDB for all application data
redisJob queue and status information
garageS3-compatible object storage for package files and built packages

Technical administration performs the installation: prepare the host, create the configuration and secrets, start the stack. The subsequent initial setup in the interface (opsi server, depots, users) is done by a user with the Administrator role.

Chapters

  1. Requirements – host, Docker, ports, network to the configserver, opsi-side preparation and versions.
  2. Installation – get the sources, create .env and secrets, add the TLS certificate, start and check the stack.
  3. Initial Setup – first sign-in, set up the configservers, set depot stages, create the first users.
  4. Test Environment – try oPBWeb without an opsi server, with two opsi mocks as config servers Test and Production.

For configuration, LDAP, operation and backup during ongoing operation, see Technical Administration .

Requirements

What the host, the network and the opsi server must provide to run oPBWeb

Audience: Technical administration

Overview

This chapter lists everything that must be in place before the installation: a Docker host, free ports, a network connection to the opsi configserver and a technical opsi user. Check the items in order before you start the Installation .

Host

oPBWeb runs on any Linux host with Docker. You can run the stack directly on the opsi configserver or on a separate host that reaches the configserver via HTTPS.

Ports

The stack exposes only the frontend container to the outside. All other services communicate on internal Docker networks.

Variable in .envDefaultUse
FRONTEND_HTTP_PORT80redirects to HTTPS
FRONTEND_HTTPS_PORT443HTTPS (always with a certificate, self-signed if need be)

The interface is served via HTTPS only; the HTTP port redirects there. If a web server is already running on the host (for example on the configserver), choose different ports.

Network to the opsi configserver

The worker container talks directly to opsiconfd on the configserver:

The connection originates from the worker via the Docker network opsi-net. Firewalls between the Docker host and the configserver must allow port 4447.

opsi-side requirements

oPBWeb is designed for opsi 4.3. On the configserver you need:

Certificates

Images and internet access

You can provide the oPBWeb images (backend, frontend, garage-init) in two ways:

In both cases the third-party images for MariaDB, Redis and Garage come from Docker Hub unless you use a mirror. You choose the way during the Installation with setup-opbweb.sh.

During operation the stack does not need internet access.

Versions

This manual describes the following versions:

ComponentVersion
Backend0.18.8
Frontend0.18.16
Launcher0.18.0

Technical basis:

ComponentVersion
Python3.13 (python:3.13-slim)
FastAPI0.143.1
SQLAlchemy2.1.4
Alembic1.20.0
arq (job worker)0.28.0
Vue3.5
Vite8.3
Node.js (build only)22
nginxstable-alpine
MariaDB11.4
Redis7
Garage (S3)v2.2.0
opsi (configserver)4.3

You can see the installed frontend and backend versions at any time in the status bar at the bottom of the interface.

Installation

Install oPBWeb step by step and start the stack for the first time

Audience: Technical administration

Overview

The installation takes only a few steps: get the sources, run ./setup-opbweb.sh (it writes the configuration file .env and generates the secrets), optionally add a TLS certificate, and start the stack. You either build the images locally with ./start.sh --build or pull prebuilt images from a registry. Then check that all services are running and continue with the Initial Setup in the interface.

Run all commands in the project directory on the Docker host. Check the Requirements first.

1. Get the sources

Clone the oPBWeb repository (opsiPackageBuilder-web) onto the Docker host and change into the directory:

git clone https://gitlab.open-mind.space/pages/opsiPackageBuilder-web.git
cd opsiPackageBuilder-web

Without Git and without sources, use the stack ZIP from the release oPBWeb Stack (oPBWeb-Stack-<no>.zip, see Build and Delivery ): unpack it and change into the folder oPBWeb-Stack. The images then always come from the registry, the enclosed versions.env sets their versions.

All paths in this chapter (.env, secrets/, certs/) are relative to this directory.

2. Setup with setup-opbweb.sh

Run the setup script:

./setup-opbweb.sh

The script first checks that docker, the docker compose plugin and openssl are available. It then asks for the most important settings (the questions are in German). Each question shows the default in square brackets; press Enter to accept it.

AreaQuestions
Imagesbuild the images locally (l) or pull them from a registry (r). With r also: registry prefix of the oPBWeb images and the versions of the backend, frontend and garage-init images
FrontendTLS certificate (see 4. TLS certificate ): take over a supplied one, keep an existing one or create a self-signed one, for that the host name (FQDN); host port for HTTP (default 80, redirects to HTTPS) and HTTPS (443), time zone (Europe/Berlin)
Sign-inname of the first local administrator (admin), whether LDAP/Active Directory is used; with LDAP also server, port, LDAPS, certificate verification, CA file in certs/ldap/, base DN, search base, search filter, bind DN with password and the groups per role
Operationlog level (DEBUG, INFO, WARNING, ERROR; default INFO)

The default registry prefix is the registry of the project’s GitLab CI. Enter a different prefix, for example for an internal mirror, at the question, or set it beforehand as the environment variable OPBWEB_REGISTRY. The chapter LDAP Sign-in explains the LDAP settings.

After a summary, the script asks „Fortfahren und Dateien schreiben?“ (continue and write the files?). If you confirm, it

  1. writes .env,
  2. generates all missing secrets via scripts/init-secrets.sh (see 3. Secrets ) and writes the LDAP password you entered to secrets/ldap_bind_password.txt,
  3. creates the directories certs/ and certs/ldap/, moves supplied certificates there or creates a self-signed certificate,
  4. offers to pull the images right away when you use registry images („Images jetzt ziehen?“ – pull images now?),
  5. shows the next steps.

If files that your answers require are missing, the script warns you, for example if the LDAP CA file you named is not in certs/ldap/ or the certificate expires in less than 30 days.

Values the script does not ask for (time limits, compression, token lifetimes, account lockout, DEBUG) get their defaults. You can change them directly in .env afterwards; a later run of the script keeps them. The chapter Configuration describes all variables.

Options of setup-opbweb.sh

CallEffect
./setup-opbweb.shinteractive; with an existing .env its values are the defaults, existing secrets stay unchanged
./setup-opbweb.sh --updateonlynon-interactive: keeps every value of the existing .env, adds new variables with their default, creates missing secrets and rewrites .env. Variables the script does not know are kept at the end of the file. Requires an existing .env
./setup-opbweb.sh --devdeveloper checkout: creates .env from .env.example if none exists and then works like --updateonly; the images are built locally (./start.sh --dev --build)
./setup-opbweb.sh --yesskips the confirmation before writing
./setup-opbweb.sh --lang de or --lang enlanguage of the messages; the script stores it as OPBWEB_LANG in .env, start.sh and scripts/init-secrets.sh use it too. Without the option, OPBWEB_LANG from the environment or .env applies, otherwise the system locale (de… → German, otherwise English)
./setup-opbweb.sh --helpshows the help

You mainly need --updateonly when updating .

Without .env, start.sh aborts with the message „.env fehlt – bitte ./setup-opbweb.sh ausführen (im Entwickler-Checkout: ./setup-opbweb.sh –dev).“ (.env is missing – please run ./setup-opbweb.sh, in a developer checkout ./setup-opbweb.sh –dev).

Alternative: create .env manually

Instead of using the script, you can copy the template and adjust it yourself:

cp .env.example .env

.env.example lists all variables; commented-out lines show the default. For a first installation the defaults are usually sufficient. Check these variables:

VariableDefaultMeaning
BACKEND_IMAGE, FRONTEND_IMAGE, GARAGE_INIT_IMAGElocally built imagesset only if you use prebuilt images from a registry
FRONTEND_HTTP_PORT80Host port for HTTP
FRONTEND_HTTPS_PORT443Host port for HTTPS
COOKIE_SECUREfalsesetup-opbweb.sh sets true (always HTTPS); false only in the development stack
ADMIN_USERNAMEadminName of the first Administrator account
TZEurope/BerlinTime zone of the containers
LOG_LEVELINFOLog detail level
OPSI_INSTALL_TIMEOUT_SECONDS3600Time limit for uploading and installing large packages on the depot
JOB_TIMEOUT_SECONDS28800Upper limit for a whole job, e.g. an installation on several depots
BUILD_COMPRESSIONzstdCompression of built packages (zstd or gzip)
LDAP_ENABLEDfalseSign-in via LDAP/Active Directory

In this case start.sh generates the secrets on the first start. You enter the password of the LDAP service account yourself in secrets/ldap_bind_password.txt, see LDAP Sign-in .

Credentials do not belong in .env but in the secrets/ directory. The chapter Configuration describes all variables.

3. Secrets

The script scripts/init-secrets.sh creates all missing secrets in the secrets/ directory. It never overwrites existing files. setup-opbweb.sh calls it, and start.sh runs it on every start anyway. You can also run it yourself:

./scripts/init-secrets.sh

The script creates these files:

FileContents
db_password.txtPassword of the MariaDB application user
db_root_password.txtMariaDB root password (also used for database dumps)
redis_password.txtPassword for Redis
redis.aclRedis ACL, generated from the Redis password
jwt_secret_key.txtKey for signing the sign-in tokens
opsi_key_public.pem, opsi_key_private.pemkey pair for the opsi passwords: the API encrypts, only the worker can decrypt
settings_encryption_key.txtAES-256 key of versions before 0.18.6 (only for converting old entries)
garage_rpc_secret.txtRPC secret of the object storage
garage_admin_token.txtToken for the admin API of the object storage
admin_password.txtPassword of the first Administrator account
ldap_bind_password.txtempty; setup-opbweb.sh writes the password of the LDAP service account into it

In addition, the script creates the empty directory certs/ldap/.

The secrets/ directory gets permissions 750, the files 444. Docker passes the secret files into the containers with the host permissions. Inside, the processes run as other users (MariaDB, Redis, the application as appuser with UID 1000); with 600 they could not read the files on a Linux host. The directory permissions keep other users of the host out.

On its first run, the script displays the password of the first administrator exactly once (the output is in German: first admin account, user, password; also stored in secrets/admin_password.txt, please change after the first sign-in):

  >>> Erstes Admin-Konto: Benutzer 'admin', Passwort: <Passwort>
  >>> (steht auch in secrets/admin_password.txt; bitte nach der ersten Anmeldung ändern)

Write down the password or read it later from secrets/admin_password.txt.

4. TLS certificate

oPBWeb always runs with HTTPS. Port FRONTEND_HTTP_PORT only redirects to HTTPS, and the setup sets COOKIE_SECURE to true. There are three ways to the certificate; the setup picks one itself:

Before the setupResult
fullchain.pem and key.pem lie next to setup-opbweb.shThe setup checks that certificate and key match and moves both to certs/. An existing certificate stays as certs/fullchain.pem.bak-<time> and certs/key.pem.bak-<time>.
certs/fullchain.pem and certs/key.pem already existThe setup keeps them (after the same check).
no certificateThe setup creates a self-signed certificate for the host name it asks for (default: hostname -f), valid for 825 days, with the names host name, short name, localhost and 127.0.0.1. The browser warns on the first visit.

fullchain.pem contains the server certificate with all intermediate certificates, key.pem the private key without a password. If only one of the two files is present or they do not match, the setup stops with a message.

Place the CA of the LDAP server the same way as ldap-ca.pem next to the script; the setup moves it to certs/ldap/ and proposes it as CA file in the LDAP questions, see LDAP Sign-in .

To install your own certificate later or renew it: put fullchain.pem and key.pem next to the script, run ./setup-opbweb.sh --updateonly and restart the frontend (docker restart opbweb-frontend).

5. Provide the images and start the stack

oPBWeb has three images of its own: backend (for api and worker), frontend and garage-init. You chose the way to provide them in the setup.

Build the images locally

Start the stack and build the images:

./start.sh --build

The first build takes a few minutes because all dependencies are downloaded. The host needs internet access for this, see Requirements .

Images from a registry

The GitLab CI builds the images and pushes them with their version number and as latest to the project registry (<Registry>/backend, …/frontend, …/garage-init, see Build and Delivery ). setup-opbweb.sh writes the full names as BACKEND_IMAGE, FRONTEND_IMAGE and GARAGE_INIT_IMAGE to .env. Pull the images (unless you already did so in the setup) and start without --build. The project’s registry is public; only if you use your own registry that requires a sign-in, run docker login <registry-host> first:

docker compose pull
./start.sh

Nothing is built on this host then; only the machine that builds the images needs internet access for building.

start.sh

start.sh checks that .env exists, runs scripts/init-secrets.sh, starts the containers in the background and then shows their status.

OptionEffect
(none)starts the production stack with the existing images
--buildrebuilds the images before starting
--logsfollows the container logs after starting; Ctrl+C only stops the output, the containers keep running
--devadditionally starts the development environment (docker-compose.dev.yml); not for production
--lang de or --lang enlanguage of the messages for this run (otherwise OPBWEB_LANG from .env)
-h, --helpshows the help

You can combine the options, for example ./start.sh --build --logs.

What happens on the first start

The services start in a fixed order; each one waits for its dependencies:

  1. db, redis and garage start and report ready via their health checks.
  2. garage-init sets up the object storage: layout, access key opbweb and bucket packages. The container then exits. This happens again on every start and does not change existing data.
  3. api waits up to 60 seconds for the database, applies the database migrations and creates the first Administrator account as long as no user exists. The log then shows “Initial admin ‘admin’ created”.
  4. worker starts and reports regularly via heartbeat.
  5. frontend chooses HTTPS or HTTP depending on the certificate and logs „TLS-Zertifikat gefunden – HTTPS auf Port 443“ (TLS certificate found – HTTPS on port 443) or „Kein TLS-Zertifikat – HTTP auf Port 80“ (no TLS certificate – HTTP on port 80). The port refers to the container; externally the ports from .env apply.

All services start with restart: unless-stopped and come back up automatically after a host reboot.

6. Check the installation

First check the status of the containers:

docker compose ps

The services opbweb-frontend, opbweb-api, opbweb-worker, opbweb-db, opbweb-redis and opbweb-garage must be running. opbweb-garage-init has usually already exited (exit code 0); docker compose ps -a also shows exited containers. If there are problems, the logs help, for example:

docker logs opbweb-api
docker logs opbweb-worker

Then open oPBWeb in the browser at https://<host>/ (or http://<host>/ without a certificate, with the port if you use non-default ports). After signing in, the System status page shows the state of the database, Redis, object storage, worker and opsi server. As long as no configserver is set up, the opsi server row reports an error – this is normal before the initial setup. More on this in System Status .

You can check the API without signing in:

curl -k https://<host>/api/health

The response contains "status":"ok" and the backend version.

Stop the stack

./stop.sh

The script shuts down and removes all containers. The Docker volumes with the database and object storage are kept; on the next ./start.sh everything is back.

What’s next?

Initial Setup

First sign-in, set up configservers, define depot stages and create the first users

Role: Administrator

Overview

After the Installation , oPBWeb is reachable but does not know any opsi server yet and has only one account: the first administrator. During the initial setup you sign in with this account, change its password, connect oPBWeb to one or more opsi configservers, define the depot stages and set up the first users.

For this you need the admin password from secrets/admin_password.txt, the credentials of the technical opsi user and shell access to the configserver to verify the fingerprint of the CA certificate.

1. Sign in as administrator

  1. Open oPBWeb in the browser, for example https://opbweb.example.local/.

    oPBWeb sign-in page with the User name and Password fields

  2. Enter admin in User name (or the value of ADMIN_USERNAME from .env).

  3. Enter the password from secrets/admin_password.txt in Password.

  4. Click Sign in.

After signing in you see the package list. The orange notice “No config server configured” appears in the status bar at the bottom until you have set up the first configserver.

2. Change the admin password

The generated password is stored in plain text in secrets/admin_password.txt. Change it right after the first sign-in:

  1. Click your avatar (your initials) in the top right corner.
  2. Select Change password.
  3. Enter the Current password, then the new password twice in New password and Repeat new password. The password must be at least 10 characters long.
  4. Click Save.

The file secrets/admin_password.txt is not changed. It is only evaluated as long as no user exists, that is, on the very first start.

3. Set up configservers

oPBWeb can work with several opsi configservers, for example a test and a production system. You add them in the Depots view; the password is stored encrypted in the database and decrypted only by the worker. Repeat the following steps for every additional configserver.

  1. Click Depots in the activity bar on the left.

  2. Click + (“New config server”) at the top of the list on the left.

  3. Enter the following values:

    • Name – a label, for example Configserver. If you leave the field empty, the host name from the URL is used.
    • Config server URL – fully qualified host name with port 4447, for example https://opsi.example.local:4447. Use the FQDN, not the IP address: the opsiconfd certificate is issued for the name.
    • Technical user – the opsi user with admin rights (default opsiadm).
    • Password – the password of this user.
    • Stage – Production (default), Staging or Test. For a test server, select Test; all depots of the server take over this stage (see step 4 ).
  4. Leave Verify the server TLS certificate (recommended) switched on.

  5. Under TRUSTED CA CERTIFICATE, click Fetch from server. oPBWeb loads the CA certificate of the configserver and shows it with its SHA-256 fingerprint in the CA certificate of the server dialog.

  6. On the configserver, determine the fingerprint of the opsi CA:

    openssl x509 -in /etc/opsi/ssl/opsi-ca-cert.pem -noout -fingerprint -sha256
    
  7. Compare both fingerprints. If they match, click Trust. If they differ, cancel and find out which server you are actually connected to.

  8. Click Add. The message “opsi server saved” confirms this.

    Depots view with the “New config server” form

Right after adding, oPBWeb runs Test connection for the new server. The test checks sign-in, admin rights and opsi version and reads the depots of the configserver; they then appear in the list below the server. If it succeeds, the dot in front of the server name turns green and the badge in the form shows “reachable”. Later you can repeat the test at any time with Test connection in the server’s form.

Afterwards you see a line such as “Last checked … · opsi 4.3 … · 2 depots” below the CA certificate.

If the test fails, check the most common causes:

Message or symptomCause
“… has no opsi admin rights”The technical user is not an admin in opsi.
HTTP 403opsiconfd only allows admin calls from the admin-networks; the worker’s Docker network is missing there, see Requirements .
Certificate errorThe URL contains an IP address instead of the FQDN, or no CA certificate or a wrong one is stored.

The chapter Troubleshooting describes further causes. The chapter Config Servers explains all functions of the form, including removing a configserver and replacing the CA certificate after a rotation.

4. Define depot stages

With the successful connection test, oPBWeb reads the depots from the configserver. After that, the worker syncs the depots of all configservers automatically every 5 minutes; under Depots you can also trigger a sync yourself with Sync (one configserver) or ⟳ (all configservers).

Each depot has a stage: Test, Staging or Production. Packagers may install on test and staging depots; only Releasers may install on production depots. A depot inherits the stage of its configserver; you recognize this by the italic badge. If you already chose the right stage for the configserver, there is nothing left to do here.

If individual depots should differ from the stage of their configserver, for example a test depot on a production configserver, change the stage on the depot itself:

  1. Click Depots in the activity bar.

  2. Select the depot on the left.

  3. In the Settings area, select the value you want for Stage, for example Test. With “as config server (…)” the depot inherits the stage of its server again.

    Depot settings with the Stage field (inherited from the config server)

  4. Click Save. The message “Settings saved” confirms the change, and the depot shows the Test badge in the list.

  5. Repeat the steps for all other depots that differ.

The chapter Depot Management describes the other depot settings (Service URL, Enabled).

5. Create the first users

Create separate accounts for everyone who works with oPBWeb instead of sharing the admin account:

  1. Click Users and roles in the activity bar.
  2. Click New user.
  3. Fill in User name, Role, Name, Email, Default language and New password, and click Create.

The chapter Users and Roles explains which role may do what and how to edit, lock or delete accounts later.

6. Optional: sign-in via LDAP

In addition to local accounts, users can sign in with their directory account (LDAP or Active Directory). Their role is then derived from their group membership at every sign-in. The setup is done via .env and is a task for technical administration, see LDAP Sign-in .

Result

After the initial setup:

The chapter Getting Started shows what working in oPBWeb looks like from there.

Test Environment

Try oPBWeb without an opsi server: two opsi mocks as config servers Test and Production

Audience: Technical administration, anyone who wants to try oPBWeb

Overview

The test environment starts oPBWeb together with two simulated opsi servers (opsiconfd mocks). With them you try the editor and the whole workflow, from the import from the workbench through building to promoting from Test to Production, without a real opsi server.

Config server in oPBWebStageDepotsMock container
opsi-testTestopsi-test.mock (config server), depot-test.mockopbweb-opsi-mock-test
opsi-prodProductionopsi-prod.mock (config server), depot-prod.mockopbweb-opsi-mock-prod

The mocks run with the oPBWeb backend image, their code comes from tools/opsi-mock/opsi_mock.py. Both are part of the repository clone and of the stack ZIP . The short version of this guide is next to them as START-TEST-ENVIRONMENT_en.md.

Requirements

Set up and start

  1. Change into the directory with the files and run the setup:

    ./setup-opbweb.sh
    

    The defaults suit a test, Enter accepts them. At the images question choose r (registry) or, in a clone, l (build locally). In the stack ZIP the setup selects the registry images from versions.env. At the end the setup shows the password of the first administrator admin; it is also in secrets/admin_password.txt.

  2. Start the stack with the mocks:

    ./start.sh --test            # images from the registry
    ./start.sh --test --build    # in a clone with locally built images
    

    --test adds docker-compose.test.yml. On the first start the API registers the two mocks as config servers, as long as no opsi server is configured yet (variable OPSI_MOCK_SERVERS in the overlay). The technical user is opsiadm with the password mock, TLS verification is off.

  3. Open https://localhost/ (or the port from the setup) and sign in as admin. Without your own certificate the setup created a self-signed one; confirm the browser warning.

  4. Open Depots. opsi-prod (Production) and opsi-test (Test) are listed on the left. Click opsi-test, then Test connection; oPBWeb reads the depots of the server. Do the same for opsi-prod. Without this step the depots arrive with the next opsi check, after 5 minutes at the latest.

Trying the workflow

  1. In Packages, click Workbench … and choose the config server opsi-test. The workbench of the mock contains the project mock-demo and the folder kein-paket (not a valid project, to see the error message). Select mock-demo and click Import selected (1), see Packages .
  2. Open mock-demo with Open in editor, change something, for example in CLIENT_DATA/setup.opsiscript in the script editor , and save.
  3. Click Build, then Install …. Select the two depots of opsi-test (stage Test) and click Install. The version is released afterwards, see Build and Deploy .
  4. In Packages, click Promote …, set From Test to Production and click Promote (1). oPBWeb installs the same build on the depots of opsi-prod, see Promoting to another stage .
  5. Under Depots you see the installed products, the files and the repository of each depot, under Jobs the logs of all steps.

What the mocks can do

Stop, continue, remove

GoalSteps
Stop./stop.sh (also stops the mocks; the data is kept)
Start again./start.sh --test
Continue with a real opsi serveradd the real config server under Depots (Initial Setup ), remove the two mock servers and start without --test from then on
Remove everything, including all datadocker compose -f docker-compose.yml -f docker-compose.test.yml down -v, then delete the directory