# Offline (air-gapped / 폐쇄망) install

The deployment target has **no internet**. All Python dependencies must be
carried across the air gap as pre-downloaded wheels. The build/staging machine
(which has internet) does the downloading; the target only installs.

## Prerequisites

- Same OS + CPU architecture + **Python 3.13** on build and target machines
  (wheels are platform- and version-specific).
- The repository itself transferred to the target.

## 1. On the build machine (has internet)

```bash
# Runtime only:
pip download -r requirements.txt -d wheelhouse/

# Or runtime + test tooling:
pip download -r requirements-dev.txt -d wheelhouse/
```

This fills `wheelhouse/` with every wheel (including transitive deps).

## 2. Transfer

Copy both the repository and the `wheelhouse/` directory to the target via the
approved air-gap transfer process (e.g. removable media).

## 3. On the target machine (no internet)

```bash
python -m venv .venv
. .venv/bin/activate          # Windows: .venv\Scripts\activate
pip install --no-index --find-links wheelhouse/ -r requirements.txt
```

`--no-index` guarantees pip never reaches out to the internet; `--find-links`
points it at the local wheelhouse.

## 4. Verify offline

```bash
# Confirm no network access is attempted and imports resolve:
python -c "import numpy, cv2, PIL; print('deps ok')"
python -m pytest -q          # if test deps were installed
```

## Notes

- The operator GUI (`web/operator-gui/`) is fully self-contained: all
  scripts/styles are local and the Pretendard font is bundled
  (`assets/fonts/PretendardVariable.woff2`). No CDN fetch at runtime.
- External **search** APIs (Google / Naver / Cloud Vision) are an allowed
  runtime exception and require outbound access to those providers ONLY. They
  are optional; missing credentials disable the provider (see the startup
  provider-readiness log).
- `COPYRIGHTER_AUTH_TOKEN` should be set in `.env` for any multi-operator or
  networked deployment so the data routes require a shared token.
