RAN CN 테스트베드 구축/Sionna RT-OAI (AI-RAN)

WSL2 환경에서 Sionna RT 연결을 위한 OAI RF 네트워크 스택 설치하기

gksyb4235 2026. 6. 24. 23:42

OAI 5G SA RF Simulator 환경설정


가장 먼저 Sionna RT 모듈과 연결할 실제 OpenAirInterface5g를 설치하고 UE, 기지국, Core Network를 도커 형태로 띄운다.

이전에 https://gksyb4235.tistory.com/23 에서 수행했던 것과 거의 유사하지만,

gNB, UE, FlexRIC까지 전부 도커 형태로 관리하도록 환경을 구성했다.

또한 기존의 OAI 폴더에 Sionna에서 진행한 패치를 적용하여 Sionna 공식 튜토리얼대로 Sionna RT와 OAI를 연동한다.

 

현재 서버에 설치한 Kubernetes 기반의 OAI B210 설정 파일과 Free5GC, 그리고 여러 오픈소스 도구를 쓰면 더 강력한 테스트베드를 구축할 수 있지만, Free5GC의 경우 wsl2에서 Linux kernel 세팅이 불가능하고, wsl2 환경에서 너무 무거운 툴들을 돌리게 되면 가장 중요한 Digital Twin 기반의 AI-RAN 작업에 집중하기 힘들 수 있어서 기본적인 OAI RF 환경을 활용하였다.

 

전체 아키텍처는 다음과 같다.

┌──────────────────────────────────────────────────────────────────┐
│              Docker Network: demo-oai-public-net                 │
│                    Subnet: 192.168.70.128/26                     │
│                                                                  │
│  [CN5G]   — 공식 이미지 그대로 사용                                │
│  mysql        192.168.70.131  ← Subscriber DB                    │
│  oai-amf      192.168.70.132  ← Access & Mobility Mgmt           │
│  oai-smf      192.168.70.133  ← Session Mgmt                     │
│  oai-upf      192.168.70.134  ← User Plane (GTP-U)               │
│  oai-ext-dn   192.168.70.135  ← External Data Network (iperf3)   │
│                                                                  │
│  [RAN]   — sionna-rk CUDA 커스텀 이미지                           │
│  oai-gnb      192.168.70.140  ← gNB (rfsim + CIR ZMQ 에뮬레이터)  │
│  oai-nr-ue1   192.168.70.150  → PDU IP: 12.1.1.x                 │
│  oai-nr-ue2   192.168.70.151  → PDU IP: 12.1.1.x                 │
│  oai-nr-ue3   192.168.70.152  → PDU IP: 12.1.1.x                 │
│                                                                  │
│  [O-RAN]   — sionna-rk FlexRIC Image                             │
│  nearRT-RIC   192.168.70.160  ← E2 인터페이스 수신                │
│  xapp-kpm     192.168.70.161  ← KPM SM xApp                      │
│  xapp-mac     192.168.70.162  ← MAC/RLC/PDCP/GTP xApp            │
│  xapp-zmq     192.168.70.163  ← KPI ZMQ 스트리밍 xApp ★신규      │
└──────────────────────────────────────────────────────────────────┘

 

Sionna RT를 연동하기 전의 OAI에서의 신호 흐름은 다음과 같다.

UE ←─ RF Simulator(TCP) ─→ gNB ←─ N2(NGAP/SCTP) ─→ AMF
                                ←─ N3(GTP-U)     ─→ UPF ─→ ext-dn(인터넷)
                                ←─ E2(SCTP)      ─→ nearRT-RIC ─→ xApp

 

이를 다음과 같이 연동해야 한다.

Sionna RT (경희대 씬 ray tracing)
    ↓ CIR 계산
    ↓ ZMQ REQ → port 5556
libcir_zmq.so (gNB 컨테이너 내부)
    ↓
libchn_emu.so → CUDA 컨볼루션 → IQ 샘플에 채널 특성 적용
    ↓
UE ←── rfsim (TCP) ──→ gNB ←── N2 ──→ AMF
                             ←── N3 ──→ UPF → ext-dn
                             ←── E2 ──→ nearRT-RIC → xapp-zmq
                                             ↓ ZMQ PUB → port 5557
                                        KPICollector (Python)
                                             ↓ 피드백
                                        Sionna RT 씬 업데이트

 

구체적인 환경설정 방법은 아래와 같다.

 

 

# 사전 작업 : 이미지 빌드


OpenAirInterface에서 받을 수 있는 이미지는 oaisoftwarealliance/oai-gnb:develop (689MB)이다.

Sionna RT와 연동하기 전에는 위 이미지를 화룡해 최신 oai 이미지를 빌드해 5G 환경을 구성했다.

Sionna RT와 연동하기 위해 사용해야 하는 이미지는 oai-gnb-cuda:sionna-rk (22.4GB)라는 커스텀 이미지이다.

 

크기 차이가 크게 나는 이유는 oai-gnb-cuda:sionna-rk에는 CUDA 13, TensorRT 11, UHD 드라이버가 포함됐기 때문이다.

현재는 rfsim만 사용하므로 UHD는 사용되지 않고, TensorRT도 neural receiver 플러그인을 따로 로드하지 않으면 활성화되지 않기 때문에 위 부분은 제외하고 빌드를 수행해도 무방하다.

여기서는 나중에 USRP B210으로 실제 RF 실험을 할 때를 대비해 22.4GB의 전체 이미지를 빌드하여 사용한다. 

기존 oai 이미지와의 비교하면 다음과 같다.

 

플러그인 공식 이미지 sionna-rk 패치 이미지
libchn_emu.so (CUDA 채널 에뮬레이터)
libcir_zmq.so (ZMQ CIR 수신기)
libcir_file.so (파일 기반 CIR 로더)
libldpc_cuda.so (GPU 가속 LDPC)

 

이 플러그인들이 없으면 Sionna RT의 CIR을 OAI에 주입할 방법이 없다. 

공식 이미지로는 telnet chanmod modify noise_power_dB 명령으로 노이즈 파워 하나만 간접 조정할 수 있는데, 
이 방법은 실제 채널의 탭별 지연과 이득 정보를 전혀 반영하지 못한다. 

게다가 setmodel 명령 자체가 공식 이미지에서는 비활성화(disabled)되어 있어 채널 모델 변경도 수행할 수 없다.

# 이미지 빌드 방법

# openairinterface5g 소스를 2025.w34 태그로 체크아웃
git clone --branch 2025.w34 \
    https://gitlab.eurecom.fr/oai/openairinterface5g.git ~/openairinterface5g

# sionna-rk 패치 적용 (TensorRT 11 API 호환 수정 포함)
cd ~/openairinterface5g
git apply ~/sionna-oai-flexric-smo/patches/openairinterface5g.patch

# CUDA 이미지 빌드 (~60분)
bash ~/sionna-oai-flexric-smo/scripts/build_images.sh ~/openairinterface5g

 

VIDIA가 제공하는 원본 sionna-rk 패치는 OAI 2025.w34 기준이다. 

최신 openairinterface5g는 2026.wxx로 더 최신이라 패치가 바로 적용되지 않아 2025.w34로 체크아웃 후 적용한다. 

또한 빌드 이미지에 포함된 TensorRT가 11.x인데, neural receiver 플러그인 코드가 TRT 10.x API(createExecutionContextWithoutDeviceMemory, getDeviceMemorySize)를 쓰고 있어 컴파일 에러가 난다.

#if NV_TENSORRT_MAJOR >= 11 조건부 분기로 수정했다.

 

 

 

# 1. oai 5G저장소 클론 (5G 코어는 oai 기존 이미지 사용)


# OAI CN5G-fed 클론 (docker-compose + 설정 파일 포함)
git clone https://gitlab.eurecom.fr/oai/cn5g/oai-cn5g-fed.git ~/oai-cn5g
cd ~/oai-cn5g/docker-compose

 

 

# 2: 설정 파일 수정


# 2-1. gNB 설정 — gnb.sa.band78.106prb.rfsim.yaml
# 원본에서 2군데를 수정한다.

# ❶ NETWORK_INTERFACES — gNB 컨테이너 IP로 변경 (원본은 192.168.70.153)
    NETWORK_INTERFACES:
      GNB_IPV4_ADDRESS_FOR_NG_AMF: 192.168.70.140  # ← 수정
      GNB_IPV4_ADDRESS_FOR_NGU: 192.168.70.140     # ← 수정
      GNB_PORT_FOR_S1U: 2152

# ❷ e2_agent 섹션 추가 (원본에 없음) — 파일 맨 끝에 추가
e2_agent:
  near_ric_ip_addr: "192.168.70.160"   # nearRT-RIC 컨테이너 IP
  sm_dir: "/usr/local/lib/flexric/"    # SM 라이브러리 경로 (volume으로 주입)


이 부분을 수정하는 이유는 GNB_IPV4_ADDRESS_FOR_NG_AMF(gNB가 AMF에게 알려주는 자신의 IP)와 실제 gNB 컨테이너의 IP가 일치해야 AMF →gNB 방향 통신(Paging 등)이 가능하게 때문이다. 또한 e2_agent 설정으로 gNB가 부팅 시 nearRT-RIC에 E2 Setup Request를 보내도록 설정한다.

 

# 2-2. UE 설정 — ran-conf/nrue.uicc.1~3.yaml

uicc0:
  dnn: oai
  nssai_sst: 1       # 모든 UE를 sst:1로 통일

rfsimulator:
  - serveraddr: "192.168.70.140"   # gNB 컨테이너 IP
    options: chanmod               # ★ chanmod 옵션 유지


이 부분을 수정하는 이유는 UE RF Simulator는 TCP 클라이언트로 동작하는데, gNB가 서버 역할을 하므로 serveraddr를 gNB IP를 가리키도록 해야 한다. 또한 CN5G의 mini_nonrf_config.yaml에 등록된 slice(sst:1)와 nssai_sst가 일치해야 PDU Session 수립 가능하기 때문이다.

 

options: chanmod를 유지하는 이유는 해당 옵션이 rfsim 내부의 채널 모델링 코드를 활성화하는데, CIR ZMQ 플러그인(libcir_zmq.so)이 이 코드 경로를 통해 채널을 적용하기 때문이다. 없으면 ZMQ로 CIR을 보내도 무시된다.

 

# 2-3. FlexRIC 설정 — 
# flexric.conf (신규 생성)
mkdir -p ~/oai-cn5g/docker-compose/conf/flexric
cp ~/openairinterface5g/ci-scripts/yaml_files/5g_rfsimulator_flexric/conf/flexric.conf \
   ~/oai-cn5g/docker-compose/conf/flexric/flexric.conf

# 내용 수정:
[NEAR-RIC]
NEAR_RIC_IP = 192.168.70.160   # nearRT-RIC 컨테이너 IP (원본은 192.168.70.150)

[XAPP]
DB_DIR = /tmp/

 

FlexRIC의 conf 파일은 openairinterface5g 폴더의 ci-scripts에서 복사하여 가져온다.
nearRT-RIC 바이너리가 시작 시 이 flexric.conf 파일에서 자신의 Listen IP를 읽어온다.

이때 컨테이너 IP와 일치하지 않으면 즉시 종료된다.

 

 

# 3. Docker Compose 파일 작성 (신규 생성)


# 3-1. docker-compose-gnb-rfsim.yaml
services:
  oai-gnb:
    image: oai-gnb-cuda:sionna-rk   # ★ 공식 → sionna-rk 이미지
    container_name: oai-gnb
    cap_drop:
      - ALL
    cap_add:
      - SYS_NICE    # 실시간 스케줄링 우선순위 조정
      - NET_ADMIN   # 네트워크 인터페이스 설정
      - NET_RAW     # raw 소켓 (SCTP 등)
    environment:
      USE_ADDITIONAL_OPTIONS: >-
        -E
        --rfsim
        --gNBs.[0].min_rxtxtime 6
        --telnetsrv
        --loader.chn_emu.shlibpath /usr/local/lib   # ★ CUDA 채널 에뮬레이터 로드
        --loader.cir_zmq.shlibpath /usr/local/lib   # ★ ZMQ CIR 수신기 로드
        --cir-zmq-num-taps 48                        # ★ CIR 탭 수 (Sionna RT와 맞춤)
        --log_config.global_log_options level,nocolor,time
    ports:
      - "5556:5555"   # ★ CIR ZMQ 포트 호스트 노출 (Sionna RT Python에서 접근)
    volumes:
      - ./ran-conf/gnb.sa.band78.106prb.rfsim.yaml:/opt/oai-gnb/etc/gnb.yaml
      - flexric_libs:/usr/local/lib/flexric/      # FlexRIC SM 라이브러리 주입
    networks:
      public_net:
        ipv4_address: 192.168.70.140
    healthcheck:
      test: /bin/bash -c "pgrep nr-softmodem"
      start_period: 15s
      start_interval: 1s
      interval: 10s
      timeout: 5s
      retries: 10

networks:
  public_net:
    external: true
    name: demo-oai-public-net

volumes:
  flexric_libs:
    external: true
    name: flexric_sm_libs    # FlexRIC 이미지에서 추출한 SM .so 파일들

 

--loader.chn_emu.shlibpath와 --loader.cir_zmq.shlibpath는 OAI의 shared library loader가 해당 경로에서 .so 파일을 찾도록 지정하는 옵션이다. 이 두 줄이 없으면 gNB가 CIR ZMQ 플러그인을 로드하지 않아 Sionna RT에서 ZMQ로 CIR을 보내도 연결 자체가 안 된다.

--cir-zmq-num-taps 48은 ZMQ로 수신하는 CIR의 탭 수를 지정한다. Sionna RT Python 쪽에서 get_config()로 조회하면 이 값을 확인할 수 있고, CIR 메시지를 만들 때 탭 배열 크기를 맞춰야 한다.

port 5556:5555는 컨테이너 안의 ZMQ REP 소켓(5555)을 호스트의 5556으로 포워딩한 것이다. 

Docker 네트워크 안에서는 192.168.70.140:5555로 직접 접근하고, 호스트 Python에서는 localhost:5556으로 접근한다.

 

여기서 flexric_libs volume의 경우 gNB 이미지에 FlexRIC SM 라이브러리(.so)가 없어서 FlexRIC 이미지에서 추출해서 별도 volume으로 주입하였다. (-E 옵션: E2 Agent를 활성화하는 플래그. 이게 없으면 e2_agent 설정이 있어도 무시됨)

# 2-2. docker-compose-ue-rfsim.yaml
# UE1~3 서비스 정의. 각 UE의 핵심 옵션은 아래와 같다

services:
  oai-nr-ue1:
    image: oai-nr-ue-cuda:sionna-rk   # ★ 공식 → sionna-rk 이미지

USE_ADDITIONAL_OPTIONS: >-
  -E                                      # E2 Agent
  --rfsim                                 # RF Simulator 모드 (TCP 클라이언트)
  -r 106                                  # PRB 수 (gNB와 반드시 일치)
  --numerology 1                          # SCS 30kHz (n78 밴드)
  --band 78                               # 5G NR n78 (3.3~3.8GHz)
  -C 3319680000                           # 중심주파수 Hz (gNB 로그에서 확인)
  --ssb 516                               # SSB 위치 (gNB 로그에서 확인)
  --uicc0.imsi 208950000000036            # IMSI
  --uicc0.key 0C0A34601D4F07677303652C0462535B
  --uicc0.opc 63bfa50ee6523365ff14c1f45f88737d
  --rfsimulator.[0].serveraddr 192.168.70.140  # gNB IP
  --telnetsrv
  --telnetsrv.listenport 9095             # UE마다 다른 포트 (9095/9096/9097)

 

UE도 sionna-rk 이미지를 쓰는 이유는, 향후 UE 측에서도 libchr_zmq.so를 통해 업링크 채널에 CIR을 적용하는 실험을 할 수 있기 때문이다. 현재는 gNB 측 다운링크 채널에만 적용하고 있다.

 

나머지  옵션 중 -C와 --ssb 값은 gNB 시작 후 로그에서 직접 확인할 수 있다.
([PHY] A Command line parameters for OAI UE: -C 3319680000 -r 106 --numerology 1 --ssb 516 -E)

 

# 2-3. docker-compose-flexric.yaml
services:
  nearRT-RIC:
    image: oai-flexric:sionna-rk   # ★ 공식 → sionna-rk 이미지
    container_name: nearRT-RIC
    command: /usr/local/bin/nearRT-RIC
    volumes:
      - ./conf/flexric/flexric.conf:/usr/local/etc/flexric/flexric.conf
    networks:
      public_net:
        ipv4_address: 192.168.70.160

  xapp-kpm-moni:          # O-RAN KPM SM 기반 xApp (UE별 DRB 처리량, PRB 등)
    image: oai-flexric:sionna-rk
    command: /usr/local/flexric/xApp/c/monitor/xapp_kpm_moni
    ...
    ipv4_address: 192.168.70.161

  xapp-mac-moni:          # MAC/RLC/PDCP/GTP 레이어 상세 KPI xApp
    image: oai-flexric:sionna-rk
    command: /usr/local/flexric/xApp/c/monitor/xapp_gtp_mac_rlc_pdcp_moni
    ...
    ipv4_address: 192.168.70.162
    
  xapp-zmq-stats:
    image: oai-flexric:sionna-rk
    command: python3 /xapp/zmq_stats_server.py --port 5555 --interval 0.05
    volumes:
      - ../../sionna_rt/xapp/zmq_stats_server.py:/xapp/zmq_stats_server.py
    ports:
      - "5557:5555"   # KPI ZMQ PUB 포트 호스트 노출


FlexRIC도 sionna-rk 이미지를 쓰는 이유는 gNB의 E2 Agent와 SM(Service Model) 라이브러리 버전이 맞아야 하기 때문이다.

gNB를 2025.w34 + sionna-rk 패치로 빌드했으므로, FlexRIC도 같은 소스에서 빌드한 이미지를 써야 E2 연결이 안정적이다.

xapp-zmq-stats는 기존에 없던 xApp이다. 

기존 xapp-kpm-moni와 xapp-mac-moni는 C 바이너리로 터미널에 출력만 하는 반면, zmq_stats_server.py는 FlexRIC Python SDK(xapp_sdk)로 MAC 통계를 수신해서 ZMQ PUB 소켓으로 스트리밍한다. 이 덕분에 호스트의 KPICollector(Python)가 MCS, BLER, PRB를 실시간으로 수집해서 Sionna RT 피드백 루프에 활용할 수 있다.

 

 

 

# 4. FlexRIC SM 라이브러리 Volume 준비 (최초 1회)


# gNB 이미지에 FlexRIC SM 라이브러리가 없으므로
# FlexRIC 이미지에서 추출해서 별도 volume으로 준비

docker volume create flexric_sm_libs

docker run --rm \
  -v flexric_sm_libs:/target \
  oaisoftwarealliance/oai-flexric:develop \
  cp -r /usr/local/lib/flexric/. /target/


# 복사하는 항목들
libgtp_sm.so    ← GTP 통계
libkpm_sm.so    ← KPM (Key Performance Measurement) - O-RAN 표준
libmac_sm.so    ← MAC 레이어 통계
libpdcp_sm.so   ← PDCP 레이어 통계
librc_sm.so     ← RAN Control
librlc_sm.so    ← RLC 레이어 통계
libslice_sm.so  ← 슬라이싱 제어
libtc_sm.so     ← Traffic Control

 

 

# 최종 전체 시스템 실행 결과


cd ~/oai-cn5g/docker-compose

# ── 1. CN5G ──────────────────────────────────────────────────
docker compose -f docker-compose-core.yaml up -d

# 로그 확인
docker compose -f docker-compose-core.yaml logs -f
docker logs oai-amf 2>&1 | grep -E "Registration|PDU|IMSI|Session"
docker logs oai-smf 2>&1 | grep -E "PDU|address|allocated|12\.1\.1"

 

# ── 2. FlexRIC (gNB보다 먼저 — gNB가 E2 Setup Request를 보낼 준비) ──
docker compose -f docker-compose-flexric.yaml up -d nearRT-RIC

docker logs nearRT-RIC   # 정상이면 포트 36421 listen 로그 출력

 

# ── 3. gNB ────────────────────────────────────────────────────
ocker compose -f docker-compose-gnb.yaml up -d

# gNB → AMF 연결 + E2 연결 + CIR ZMQ 확인
docker logs oai-gnb 2>&1 | grep -E "NGSetupResponse|E2 SETUP RESPONSE|CIR ZMQ|cir_zmq"

# 기대 출력:
# [NGAP] A Received NGSetupResponse from AMF
# [E2-AGENT]: E2 SETUP RESPONSE rx
# [CIR ZMQ] Initialized on port 5555 with num_taps=48

 

 

# ── 4. UE ─────────────────────────────────────────────────────
docker compose -f docker-compose-ue.yaml pull
docker compose -f docker-compose-ue.yaml up -d

# 전체 실시간
docker logs -f oai-nr-ue1 2>&1
docker logs -f oai-nr-ue2 2>&1
docker logs -f oai-nr-ue3 2>&1

# UE IP 할당 확인 (12.1.1.x 나오면 성공)
docker exec oai-nr-ue1 ip addr show oaitun_ue1
docker exec oai-nr-ue2 ip addr show oaitun_ue1
docker exec oai-nr-ue3 ip addr show oaitun_ue1

 

UE 1에 대한 Log는 다음과 같다.

 

이 시점에서 AMF의 로그를 확인하면 총 3개의 UE가 모두 인증되어 Connected됨을 확인할 수 있다.

 

# ── 5. xApp ───────────────────────────────────────────────────
docker compose -f docker-compose-flexric.yaml up -d xapp-kpm-moni
docker compose -f docker-compose-flexric.yaml up -d xapp-mac-moni

# xapp-kpm-moni 로그 (KPM SM — UE별 처리량/PRB/지연)
docker logs -f xapp-kpm-moni 2>&1

# xapp-mac-moni 로그 (MAC/RLC/PDCP/GTP — 상세 레이어 KPI)
docker logs -f xapp-mac-moni 2>&1

# Python ZMQ stats xApp (Sionna RT 피드백 루프에 필수)
docker compose -f docker-compose-flexric.yaml up -d xapp-zmq-stats
docker logs -f xapp-zmq-stats
# 기대 출력: Published #1: 3 UEs at TS ...

 

 

# 종료는 역순으로
cd ~/oai-cn5g/docker-compose

docker compose -f docker-compose-ue.yaml down
docker compose -f docker-compose-gnb.yaml down
docker compose -f docker-compose-flexric.yaml down
docker compose -f docker-compose-core.yaml down

 

 

 

 

Iperf3로 Traffic 생성


효율적인 실험을 위해 iperf3 폴더를 생성하고, 여러 개의 UE의 Traffic을 원클릭으로 생성할 수 있는 스크립트를 생성했다.

iperf3의 폴더 구조는 다음과 같이 설정했다.

~/iperf3/
├── CSV 파일 (트래픽 시나리오 데이터)
│   ├── Video_Conferencing_10.csv   ← UE1용
│   ├── Metaverse_10.csv            ← UE2용
│   ├── Live_Streaming_10.csv       ← UE3용
│
├── Python 스크립트
    ├── run_multi_ue_traffic.py         ← 메인 (UL+DL 동시)

 

이 파이썬 파일의 실행 흐름은 다음과 같다.

1. oai-nr-ue1~3의 oaitun_ue1 IP 자동 감지
2. oai-ext-dn에 iperf3 서버 6개 자동 실행 (UL×3, DL×3)
3. CSV 매 행을 1초 간격으로 읽으면서
   UE1~3 UL/DL iperf3를 스레드로 동시 실행

 

 

이후 kpm_monitoring xApp을 동작시킨 결과, Iperf3로 생성한 트래픽이 잘 수집됨을 확인할 수 있다.

 

 

 

## Appendix : xApp 커스터마이징 방법


최초 1회 세팅

# FlexRIC 소스 클론
git clone https://gitlab.eurecom.fr/mosaic5g/flexric.git ~/flexric

# 빌드 환경 세팅
cd ~/flexric
mkdir build && cd build
cmake ..
make -j$(nproc) xapp_kpm_moni


반복 워크플로우

# 1. 소스 수정
vim ~/flexric/examples/xApp/c/monitor/xapp_kpm_moni.c

# 2. 빌드
cd ~/flexric/build && make -j$(nproc) xapp_kpm_moni

# 3. 컨테이너에 복사 후 재시작
docker cp ~/flexric/build/examples/xApp/c/monitor/xapp_kpm_moni \
    xapp-kpm-moni:/usr/local/flexric/xApp/c/monitor/xapp_kpm_moni
docker restart xapp-kpm-moni


주의할 점: FlexRIC 소스 버전이 도커 이미지 버전과 맞아야 함.

버전 불일치하면 SM 라이브러리(.so)랑 ABI가 안 맞아서 실행 시 에러.

클론할 때 이미지 빌드 기준 커밋을 맞춰주는 게 안전하다.

# 이미지의 FlexRIC 커밋 확인
docker run --rm oaisoftwarealliance/oai-flexric:develop \
    cat /etc/flexric-version 2>/dev/null || \
    git -C /flexric log --oneline -1 2>/dev/null