Docker configuration for hosting HexVault, Lumina, and HexLicSrv.
Installer files go into each service’s ./<service>/image
folder.
Supported version:
.
├─ docker-compose.yml # runs all services (hexlicsrv, hexvault, lumina + mysql)
├─ hexlicsrv/
│ ├─ image/ # put hexlicsrv installer here (e.g., hexlicsrv90_x64linux.run)
│ ├─ CA/ # CA.pem + CA.key
│ ├─ config/ # persistent config (mounted)
│ ├─ data/ # persistent data (mounted)
│ └─ logs/ # persistent logs (mounted)
├─ hexvault/
│ ├─ image/ # put hexvault installer here (e.g., hexvault90_x64linux.run)
│ ├─ CA/ config/ data/ logs/
└─ lumina/
├─ image/ # put lumina installer here (e.g., lumina90_x64linux.run)
├─ CA/ config/ data/ logs/
└─ mysql/ # MySQL persistent volume
- Linux host with Docker and Docker Compose
- Your own internal Certificate Authority (CA) pair:
CA.pem
(cert) andCA.key
(private key) - For Lumina: MySQL 8 (provided by the included
mysql
service)
Create a CA once and place it into every service’s CA/
folder:
openssl req -x509 \
-newkey rsa:4096 -sha512 -keyout CA.key -out CA.pem -days 3650 -nodes \
-subj "/C=BE/L=Liège/O=Hex-Rays SA./CN=Hex-Rays SA. Root CA"
The containers refuse to start if
CA/CA.pem
orCA/CA.key
is missing.
- Create
C:\Program Files\IDA Professional 9.0\CA
- Copy your
CA.key
andCA.pem
into that folder - Copy
license_patch.py
into the IDA install root - Run as Administrator:
python3 license_patch.py ida-pro
- Start IDA
The provided top-level docker-compose.yml
brings up all services:
- hexlicsrv --> port 65434
- hexvault --> port 65433
- mysql for lumina
- lumina --> port 443
hexlicsrv/image/hexlicsrv90_x64linux.run
hexvault/image/hexvault90_x64linux.run
lumina/image/lumina90_x64linux.run
Copy CA.key
and CA.pem
into:
hexlicsrv/CA/
hexvault/CA/
lumina/CA/
Edit environment in docker-compose.yml
:
LICENSE_HOST
for hexlicsrvVAULT_HOST
for hexvaultLUMINA_HOST
for lumina
These become the CN/SAN in the auto-issued service certificates.
docker compose up -d --build
The entrypoints run
license_patch.py
inside each container automatically.
- Mounts:
./hexlicsrv/{CA,config,data,logs}
-->/opt/hexlicsrv/...
- Config file auto-generated at first start:
config/hexlicsrv.conf
- Mounts:
./hexvault/{CA,config,data,logs}
-->/opt/hexvault/...
- Config file auto-generated at first start:
config/hexvault.conf
- Depends on the
mysql
service (health-checked) - DB env must match
mysql
service:MYSQL_HOST=mysql
,MYSQL_PORT=3306
,MYSQL_DATABASE=lumina
,MYSQL_USER=lumina
,MYSQL_PASSWORD=lumina
- Mounts:
./lumina/{CA,config,data,logs}
-->/opt/lumina/...
- Config file auto-generated at first start:
config/lumina.conf
All three services can backup/restore their state to GitHub in one of two modes:
- commits: push chunks +
manifest.json
into a branch underbackups/<SYNC_HOST_ID>/
- releases: upload chunks +
manifest.json
as release assets of a tag
- If local data is empty and a remote snapshot exists --> restore
- Else package local state and push only if changed (SHA-256 compare)
- HexLicSrv / HexVault:
tar
-->zstd -19
-->data.tar.zst
--> split -->data.tar.zst.part_000
,...001
, ... - Lumina:
mysqldump
-->zstd -19
-->dump.sql.zst
--> split -->dump.sql.zst.part_000
, ...
manifest.json
stores (among others): archive_sha256
, chunk_count
, chunk_size_mb
, timestamp_utc
.
Keep
SYNC_CHUNK_SIZE_MB ≤ 49
for GitHub’s 50 MB file limit in repos (default is49
).
In docker-compose.yml
, per service set:
environment:
SYNC_ENABLED: "true" # enable sync
SYNC_METHOD: "releases" # or "commits"
GH_REMOTE: https://github.com/yourorg/yourrepo.git # or SSH: [email protected]:yourorg/yourrepo.git
SYNC_HOST_ID: "hexvault" # logical node id, used in path under commits mode
SYNC_CHUNK_SIZE_MB: "49"
# For write access / private repos or releases:
# SYNC_AUTH_TOKEN: github_pat_token_here
# Commits mode (optional identity)
# GH_BRANCH: main
# GH_COMMIT_NAME: HexVault CI
# GH_COMMIT_EMAIL: [email protected]
# GH_SSH_PRIVATE_KEY: |-
# -----BEGIN OPENSSH PRIVATE KEY-----
# ...
# GH_KNOWN_HOSTS: |-
# github.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAI...
# Releases mode
# GH_RELEASE_TAG: hexvault
# GH_RELEASE_NAME: HexVault
# GH_API: https://ghe.example.com/api/v3 # for GHE
# GH_UPLOAD: https://ghe.example.com/api/uploads # for GHE
PAT vs SSH: For HTTPS URLs set
SYNC_AUTH_TOKEN
(Bearer for releases, x-access-token for commits). For SSH, provideGH_SSH_PRIVATE_KEY
and optionallyGH_KNOWN_HOSTS
.
A *_schema.lock
file prevents schema recreation on subsequent boots.
Delete the lock if you intentionally want the service to run --recreate-schema
again.
-
Missing tools
Images must include:git
,ssh-keyscan
,curl
,tar
,zstd
,jq
,sha256sum
,split
,openssl
, and for Lumina alsomysql
,mysqldump
,nc
. -
Auth / permissions fail
VerifyGH_REMOTE
, token/SSH key validity, and repo access. For SSH, either supplyGH_KNOWN_HOSTS
or the entrypoint will disable strict host checking (less secure). -
Checksum mismatch on restore
Means the assembled archive’s SHA-256 differs frommanifest.json
.
Fix by republishing a clean snapshot (run withSYNC_AUTH_TOKEN
so the container uploads a fresh manifest and parts), or remove release/branch assets and let the container recreate them. -
No changes to commit
Normal when the computed SHA-256 equals the remote manifest; nothing is pushed.
Adds a context-menu entry to open files with IDA on Windows.
- Never commit tokens or private keys. Use Docker secrets, env injection in CI, or a secrets manager.
- Your CA private key is sensitive; restrict filesystem permissions and repo access accordingly.