Offline and Air-Gapped Installation¶
OpenEA Community can run without Internet access after the required container images have been built and staged. The supported runtime does not depend on public CDNs, Google Fonts, external JavaScript, or other browser-hosted Internet resources.
There are two supported installation patterns:
- Temporarily connected installation — allow Internet access for the first image build and image pulls, then disconnect the host.
- Fully air-gapped installation — build and collect the required images on a connected preparation host, transfer them to the isolated host, and start OpenEA with
--no-build.
What requires Internet access during a normal first build¶
A new Docker host normally needs network access for several separate downloads:
| Build/install action | Why network access may be required |
|---|---|
| Obtain the OpenEA source | Git clone or release download, unless the source is transferred another way |
Pull python:3.10-slim |
Base image used to build the OpenEA application image |
Pull postgres:16-alpine |
PostgreSQL runtime image |
pip install during the OpenEA image build |
Python packages are resolved/downloaded from PyPI unless already cached/mirrored |
| Frontend asset vendoring during the OpenEA image build | Pinned Tabler, HTMX, Lucide, Cytoscape.js, Swagger UI, and ReDoc files are downloaded and copied into the OpenEA image |
Docker Engine and the Docker Compose plugin must already be installed on the target host. Installing Docker or operating-system packages is outside the OpenEA installation procedure and may itself require Internet access or separately staged packages.
Once the OpenEA application image and PostgreSQL image are present, normal OpenEA operation does not require Internet access.
Temporarily connected installation¶
If the OpenEA host can be connected during installation, use the normal procedure:
docker compose up -d --build
Wait for the build and initial image pulls to finish, then verify the application before disconnecting the host:
docker compose ps
curl http://localhost:8000/health
curl http://localhost:8000/health/ready
You can also verify that the OpenEA browser assets were copied into the built image:
docker compose exec web python scripts/vendor_frontend_assets.py --check
After those steps complete successfully, Internet access can be removed. Refreshing the browser, signing in, using Impact Analysis, switching themes, and opening /docs or /redoc should continue to work because their browser assets are served locally by OpenEA.
Rebuilds can require connectivity again
A later docker compose build can require network access again if Docker/Python caches are unavailable. If the machine must remain isolated permanently, use the air-gapped image-transfer process below for upgrades as well.
Fully air-gapped installation¶
Use a connected preparation host to build the exact OpenEA image that will run on the isolated machine.
Preparation-host requirements¶
The preparation host should use a Docker-compatible platform matching the isolated target, especially the same CPU architecture (for example, amd64 to amd64).
Start with the same OpenEA Community 1.5.2 source that will be transferred to the target.
1. Build the OpenEA image while connected¶
From the repository root:
cp .env.example .env
docker compose build web
The Compose configuration tags the resulting application image as:
openea-community:1.5.2
unless OPENEA_IMAGE is overridden in .env.
The build downloads Python dependencies and the pinned browser assets and stores them inside the OpenEA image.
2. Pull the PostgreSQL image¶
docker pull postgres:16-alpine
Verify both required images exist:
docker image inspect openea-community:1.5.2 >/dev/null
docker image inspect postgres:16-alpine >/dev/null
3. Export the images¶
docker save \
openea-community:1.5.2 \
postgres:16-alpine \
-o openea-community-1.5.2-images.tar
Generate a checksum:
sha256sum openea-community-1.5.2-images.tar \
> openea-community-1.5.2-images.tar.sha256
Transfer these items through your approved offline-media process:
- the OpenEA Community 1.5.2 repository/release directory
openea-community-1.5.2-images.taropenea-community-1.5.2-images.tar.sha256
4. Verify the transfer on the isolated host¶
sha256sum -c openea-community-1.5.2-images.tar.sha256
5. Load the images¶
docker load -i openea-community-1.5.2-images.tar
Verify:
docker image inspect openea-community:1.5.2 >/dev/null
docker image inspect postgres:16-alpine >/dev/null
6. Configure OpenEA¶
From the transferred repository directory:
cp .env.example .env
Set at least a strong SECRET_KEY and POSTGRES_PASSWORD. Keep:
OPENEA_IMAGE=openea-community:1.5.2
unless you intentionally used a different image tag on the preparation host.
7. Start without building¶
docker compose up -d --no-build
--no-build is important on an air-gapped host. It tells Compose to use the transferred OpenEA image instead of trying to rebuild it.
8. Verify the isolated deployment¶
docker compose ps
curl http://localhost:8000/health
curl http://localhost:8000/health/ready
docker compose exec web alembic current
docker compose exec web python scripts/vendor_frontend_assets.py --check
For Community 1.5.2, the expected migration head is:
0017_phase15 (head)
Then open:
http://localhost:8000/setup
The first-run setup page should retain the full OpenEA styling even when the host has no Internet route.
What OpenEA does not contact at runtime¶
The browser UI does not need to contact jsDelivr or another CDN for:
- Tabler CSS/JavaScript
- HTMX
- Lucide icons
- Cytoscape.js
- Swagger UI
- ReDoc
ReDoc is configured not to load Google Fonts, and Swagger UI's external specification validator is disabled. OpenEA's Content Security Policy restricts normal application pages to locally served scripts/styles and locally served/data images.
With optional login reCAPTCHA disabled, OpenEA can still communicate with external systems only if an administrator intentionally builds an integration around the REST API or places OpenEA behind external infrastructure. Those are deployment choices rather than baseline runtime requirements.
Keep login reCAPTCHA disabled offline¶
Google reCAPTCHA is optional and disabled by default. A fully offline or air-gapped OpenEA installation should leave Management → Settings → Enable reCAPTCHA on login turned off and should leave RECAPTCHA_SITE_KEY and RECAPTCHA_SECRET_KEY blank.
When disabled, the login page does not load Google's reCAPTCHA JavaScript and the OpenEA backend does not call Google's verification service. The local browser assets described above remain sufficient for normal OpenEA operation.
If you transfer a database from an Internet-connected environment where reCAPTCHA was enabled, disable the setting before moving that database into an isolated environment. If the setting remains enabled but the Google keys or network are unavailable, OpenEA intentionally fails interactive login closed.
Preparing future upgrades for an air-gapped host¶
For each future OpenEA release:
- Build the new OpenEA image on a connected preparation host.
- Pull any changed PostgreSQL image required by that release.
- Export the required images with
docker save. - Transfer and checksum-verify the images and release files.
- Back up the existing PostgreSQL data.
- Load the new images on the isolated host.
- Follow that release's upgrade notes.
- Start with
docker compose up -d --no-build.
Do not rebuild on the isolated host unless all required base images, Python packages, and frontend assets have been separately staged for that build process.