# Hướng dẫn Docker Lab

> Dựng lab giao thức công nghiệp (simulator OPC UA + MQTT) cạnh stack Xisom để kiểm thử tích hợp adapter datasource.

Hướng dẫn này dựng lên **`docker-industrial-lab`** — một sandbox simulator OPC UA + MQTT
cục bộ đi kèm trong repository này — cạnh stack Xisom của bạn, để bạn có thể thực hành
adapter datasource MQTT và OPC UA từ đầu đến cuối mà không cần một mạng nhà máy thật.

**Nó nằm ở đâu**

Lab là một phần của repository này tại `docker-industrial-lab/` — nó không phải một
repo riêng để clone. Nó có `docker-compose.yml` riêng, một `.env` được sinh ra, và một
`Makefile` với các target `up` / `down` / `smoke`.

## Bạn sẽ dựng những gì

- **Simulator OPC UA** (`lab-opcua`) — một server đã bảo mật phơi bày các tag nhà máy,
  các setpoint có thể ghi (để kiểm thử ghi đầu ra của AIBOARD), và các tag mẫu để kiểm
  thử quy mô.
- **Broker MQTT** (`lab-mosquitto`, Eclipse Mosquitto) — bảo mật theo mặc định (TLS +
  username/password, hoặc mutual-TLS), có một profile dự phòng ẩn danh.
- **MQTT publisher + sniffer** — mô phỏng một thiết bị publish dữ liệu nhà máy, và xác
  nhận sink đầu ra của AIBOARD thực sự ghi ra cái gì.
- **Stack Xisom của bạn** (suy luận + backend + frontend) — gắn vào mạng Docker của lab
  qua overlay tùy chọn `docker-compose.lab.yml` ở gốc repo, hoặc được truy cập qua host
  loopback mà không cần nó.

## Các bước

1. **Bootstrap secret và khởi chạy lab.** Stack được bảo mật theo mặc định; một script
   chạy một lần sinh ra một CA riêng, chứng chỉ client, và thông tin xác thực
   broker/OPC UA ở lần chạy đầu tiên:

   ```bash
   cd docker-industrial-lab
   ./scripts/bootstrap-secrets.sh   # or: make certs
   docker compose up -d             # or: make up
   docker compose ps                # expect every service "healthy" within ~30s
   ```

   
**Đừng tự tay sao chép .env.example**

   `bootstrap-secrets.sh` sinh ra `.env` thật (mật khẩu ngẫu nhiên +
   `COMPOSE_PROFILES=secure`). Tự sao chép `.env.example` sang `.env` sẽ bỏ qua bước
   sinh PKI — dịch vụ `certs-guard` sau đó sẽ lỗi ngay cho đến khi bạn chạy script.
   

2. **Chạy smoke test** để xác nhận stack đã bảo mật từ đầu đến cuối:

   ```bash
   ./scripts/smoke-test.sh   # or: make smoke
   ```

3. **Gắn stack Xisom của bạn vào mạng lab** (từ gốc repo, lên một cấp):

   ```bash
   cd ..
   docker compose -f docker-compose.yml -f docker-compose.lab.yml up -d
   ```

   Việc này gắn service `backend` vào mạng Docker `industrial-lab` của lab để nó tới
   được các simulator qua container DNS (`opcua`, `mosquitto`) — không cần cổng host
   nào. Các URL host-loopback (`host.docker.internal:...`) cũng hoạt động mà không cần
   overlay này.

4. **Thêm các datasource trong dashboard Xisom** — một đầu vào OPC UA tại
   `opc.tcp://opcua:4840/factory/line1` (hoặc `host.docker.internal` nếu không dùng
   overlay), và/hoặc một đầu vào MQTT tại `mqtt://mosquitto:8884` (TLS +
   username/password). Thông tin xác thực nằm trong `docker-industrial-lab/.env` đã
   được sinh ra.

## Kiểm tra

- `docker compose ps` (bên trong `docker-industrial-lab/`) hiện mọi service `healthy`.
- Trong dashboard Xisom, bật và **Start** datasource, rồi mở
  [Inference Stats](/vi/operate/monitoring/) — bạn sẽ thấy thông lượng trực tiếp từ các
  tag mô phỏng.
- Xác nhận một lần ghi đầu ra của AIBOARD thực sự đi tới đâu:
  `docker logs lab-opcua | grep WRITE` hoặc `docker logs lab-mqtt-sniffer`.

## Các knob env mẫu (kiểm thử tải/quy mô)

*(v1.28.0, chỉ dành cho lab — không ảnh hưởng đến runtime sản phẩm.)* Cả hai simulator
đều phơi bày thêm các knob env trong `docker-industrial-lab/.env` để đẩy số lượng tag và
tốc độ cao hơn demo nhà máy mặc định, hữu ích để thực hành adapter của AIBOARD dưới tải:

| Biến env | Mặc định | Mục đích |
|---|---|---|
| `SAMPLE_TAG_COUNT` | `100` | Các tag mẫu bổ sung trên cả hai giao thức — MQTT `aiboard/sample_mqtt/topic_1..N`, OPC UA `ns=2;s=SampleOpcua_Tag_1..N`. `0` để tắt. |
| `SAMPLE_RATE_HZ` | chưa đặt (tốc độ cũ) | Tốc độ lấy mẫu toàn vòng lặp tính bằng Hz cho cả hai simulator, ví dụ `10`/`20`/`50`. Ghi đè `PUBLISH_INTERVAL` (MQTT) và mặc định 1 Hz của OPC UA. |
| `SAMPLE_WALK_STEP` | `4.0` | Kích thước bước Gaussian mỗi mẫu của random walk hồi quy về trung bình (lớn hơn = nhảy nhiều hơn). |
| `SAMPLE_WALK_CENTER` | `50.0` | Giá trị mà walk hồi quy về. |
| `SAMPLE_WALK_REVERSION` | `0.05` | Cường độ kéo về tâm, `0`–`1` (0 = random walk thuần túy). |
| `SAMPLE_MQTT_QOS` | `0` | QoS chỉ cho các topic MQTT mẫu — kiểm thử adapter ở `0`/`1`/`2`. Các topic nhà máy luôn giữ QoS 0. |
| `SAMPLE_MQTT_RETAIN` | `false` | Cờ retain chỉ cho các topic MQTT mẫu. |

Ở `SAMPLE_RATE_HZ` cao kết hợp với `SAMPLE_TAG_COUNT` lớn (ví dụ 50 Hz × 100 tag ≈ 5k
lần ghi/giây mỗi giao thức), một vòng lặp simulator có thể vượt quá ngân sách của nó và
tốc độ thực tế giảm xuống dưới mục tiêu — hãy giảm một knob nếu bạn cần đảm bảo thông
lượng cứng.

## Dọn dẹp

```bash
cd docker-industrial-lab
make down   # docker compose --profile secure --profile insecure --profile dashboard down -v
```

Việc này xóa các container và volume nhưng giữ lại PKI đã sinh (`certs/`,
`mosquitto/secrets/`) để một lần `up` trong tương lai không cần bootstrap lại. Xoay vòng
thông tin xác thực bằng `./scripts/bootstrap-secrets.sh --force`.

## Nếu có gì đó trục trặc

Các service không đạt `healthy`, hoặc không có lưu lượng trong dashboard — xem runbook
[Khắc phục sự cố](/vi/troubleshooting/), và cụ thể là
[Đầu vào MQTT dừng hoặc lỗi](/vi/troubleshooting/mqtt-input-stops/) cho các nguyên nhân
phía broker.
