Air-Gapped Installation
This is the procedure for installing on an air-gapped server with no internet access. The flow has three stages.
① 인터넷 되는 PC ② USB 등 이동 매체 ③ 폐쇄망 서버
번들 내려받기 → 반출 → 로드 → 설정 → 기동
무결성·서명 검증 (검증 자동 재확인)
Server specifications, ports, and firewall requirements are identical to the "Prerequisites" section of the Installation document. Review that section first.
0. Preparing the Air-Gapped Server
If Docker is not present, the one-line installation script downloads and installs it from the internet — that path does not work on an air-gapped network. Install Docker in advance.
docker --version
docker compose version # v2.22 이상
You can install it from your distribution's offline repository or from RPM/DEB packages. If you also want signature verification, bring in the cosign binary as well (optional — without it, only verification is skipped).
1. Downloading Where Internet Is Available
There are four files to download.
| File | Contents |
|---|---|
plantpulse-studio-images-<version>.tar.gz | Bundle of 5 container images (approx. 2.8 GB) |
…tar.gz.sha256 | Checksum for integrity verification |
…tar.gz.sig | Cosign signature for provenance verification |
plantpulse-studio-docker.tar.gz | Operations package — bin/ script · compose · .env.example · cosign.pub |
BASE=https://product.kopens.io/plantpulse-studio
VER=2026.08 # 또는: VER=$(curl -fsSL $BASE/latest.txt)
# 번들은 수 GB — 전송이 끊기면 -C - 가 이어받습니다
curl -fLO -C - --retry 5 $BASE/plantpulse-studio-images-$VER.tar.gz
curl -fLO $BASE/plantpulse-studio-images-$VER.tar.gz.sha256
curl -fLO $BASE/plantpulse-studio-images-$VER.tar.gz.sig
curl -fLO $BASE/plantpulse-studio-docker.tar.gz
latest.txtlatest.txt is a single-line file containing only the name of the latest version (e.g., 2026.08). It is not a copy of the bundle, so the file you download does not change when a new version is released.
Once a version is published, it is never removed. Even after 2026.09 is released, plantpulse-studio-images-2026.08.tar.gz remains in place, so you can always use that same address to re-download or roll back to the version you were using.
If you have scripted your installation procedure, it is safer to hard-code the version rather than use latest.txt.
All 5 images are included: Studio server · web · session runtime · builder sidecar · PostgreSQL. There are no additional images to download on the air-gapped network.
Integrity and Provenance Verification (Before Export)
First, extract the operations package and retrieve the public key (cosign.pub).
mkdir -p pkg && tar xzf plantpulse-studio-docker.tar.gz -C pkg --strip-components=1
# ① 무결성 — 전송 중 파일이 깨지지 않았는가
sha256sum -c plantpulse-studio-images-$VER.tar.gz.sha256
# ② 출처 — KOPENS 가 서명한 번들이 맞는가
cosign verify-blob --key pkg/cosign.pub --insecure-ignore-tlog=true \
--signature plantpulse-studio-images-$VER.tar.gz.sig \
plantpulse-studio-images-$VER.tar.gz
--insecure-ignore-tlog Is UsedInternal registry policy does not permit use of the public transparency log (Rekor). This option skips only the lookup against the public log; the signature itself is still cryptographically verified in full.
It may be a CDN cache. Append ?v=$(date +%s) to the URL and download again.
2. Exporting to Removable Media
Copy the following four files as-is to a USB drive or similar. Do not omit .sha256 and .sig —
the import-side script uses them for automatic re-verification.
plantpulse-studio-images-2026.08.tar.gz
plantpulse-studio-images-2026.08.tar.gz.sha256
plantpulse-studio-images-2026.08.tar.gz.sig
plantpulse-studio-docker.tar.gz
3. Importing on the Air-Gapped Server
3-1. Placing the Operations Package
sudo mkdir -p /opt/kopens/plantpulse-studio-docker
sudo tar xzf /media/usb/plantpulse-studio-docker.tar.gz \
-C /opt/kopens/plantpulse-studio-docker --strip-components=1
cd /opt/kopens/plantpulse-studio-docker
mkdir -p dist
sudo cp /media/usb/plantpulse-studio-images-2026.08.tar.gz* dist/
3-2. Loading the Images
sudo bash bin/load.sh dist/plantpulse-studio-images-2026.08.tar.gz
If .sha256 and .sig are present in the same folder, load.sh verifies them automatically and aborts the import on any mismatch.
✅ 서명 검증 통과
▶ 로드 중: dist/plantpulse-studio-images-2026.08.tar.gz
✅ 로드 완료 — cp .env.example .env 설정 후 bin/start.sh
If you see ⚠ 서명 검증 생략(.sig/cosign.pub/cosign 중 부재), it means one of the three files is missing. Whether to proceed without verification is a decision for your security policy — at minimum, we recommend passing the .sha256 integrity check.
3-3. Writing the Configuration File
cp .env.example .env
vi .env
chmod 600 .env
These are the items that must be adjusted for an air-gapped environment.
| Item | Value | Reason |
|---|---|---|
REGISTRY | Leave empty (REGISTRY=) | If a value is set, the stack attempts a registry pull on every startup, causing delays and warnings |
TAG | Version of the imported bundle (2026.07) | Must match the tag of the loaded images |
PG_PASSWORD | A sufficiently long random string | When using the bundled PostgreSQL |
PLATFORM_API_TARGET | Field Platform address | Target for real data and authentication delegation |
STUDIO_LOCAL_USERS | admin:<password> | Initial login account |
PP_LANG / PP_TZ | ko / Asia/Seoul | Korean-language sites |
Place AI and Platform keys in .env as described in Secret Management.
If you use an external PostgreSQL, follow the "Choosing a Database" section of the Installation document as written.
3-4. Startup
bash bin/start.sh
ℹ️ REGISTRY 비어있음(로컬/에어갭) — pull 생략, 로컬 이미지 사용
⏳ 헬스 대기...
✅ PlantPulse Studio 시작됨 → http://192.168.x.x/
4. Verifying the Installation
bash bin/status.sh
bash bin/smoke-install.sh
smoke-install.sh checks health, web response, an actual login, the session runtime image, and container status in a single pass. If everything passes, the system is genuinely ready for use.
Open http://<server-ip>/ in a browser and log in with the STUDIO_LOCAL_USERS account.
The remaining steps are the same as "First Login" in the Installation document.
5. Updating an Air-Gapped Environment
Import and load the new version bundle the same way, then restart.
cd /opt/kopens/plantpulse-studio-docker
bash bin/backup.sh # ① 먼저 백업
sudo cp /media/usb/plantpulse-studio-images-2026.08.tar.gz* dist/
sudo bash bin/load.sh dist/plantpulse-studio-images-2026.08.tar.gz # ② 새 이미지 로드
sed -i 's/^TAG=.*/TAG=2026.08/' .env # ③ 태그 변경
bash bin/restart.sh # ④ 재기동
To also update the operations scripts (bin/), extract the new plantpulse-studio-docker.tar.gz into a temporary folder and overwrite only the files other than .env and dist/.
.env or dist/.env holds the Platform address, accounts, and API keys; dist/ holds local backups.
Overwriting them wholesale will either prevent the stack from starting or destroy your backups.
6. Backup and Restore on an Air-Gapped Network
The backup and restore scripts work without internet access — the postgres:18-alpine image required when using an external PostgreSQL is included in the import bundle.
bash bin/backup.sh # 백업
DRYRUN=1 bash bin/restore.sh # 복구 리허설(비파괴)
See Backup and Restore for details.
Next Steps
- Secret Management — the principle of keeping keys in
.envonly - Domains and Reverse Proxy — serving over an internal domain with HTTPS
- Backup and Restore
- Troubleshooting