본문으로 건너뛰기

Docker Compose로 배포

현재 네트워크에 맞는 이미지 소스를 선택하고 전체 Compose 설정을 사용하여 Linux 호스트 또는 Linux 기반 NAS에서 fn-knock를 실행합니다.

원본 Docker Hub 페이지 열기

이미지 소스

이미지 소스이미지권장 네트워크
공식 미러hub.fnknock.cn/kcilnk/fn-knock:latest중국 본토 네트워크. latest는 30분마다 동기화
Docker Hubkcilnk/fn-knock:latestDocker Hub 연결이 안정적인 네트워크

아래 예시는 공식 미러를 사용합니다. 소스를 전환하려면 pull 명령과 .envFN_KNOCK_IMAGE를 해당 주소로 바꿉니다. 버전을 고정하려면 latest를 게시된 고정 태그로 변경합니다.

네트워크 모드

네트워크 모드권장설명
HOST 네트워크권장 및 기본값호스트 네트워크를 직접 사용하여 실제 인터페이스와 IPv6를 인식합니다
브리지 네트워크선택 사항격리된 듀얼 스택 bridge와 포트 매핑을 사용하지만 DDNS가 호스트 인터페이스나 IPv6를 찾지 못할 수 있습니다

DDNS의 “인터페이스에서 가져오기”를 사용하거나 호스트 IPv6가 필요하면 HOST 네트워크를 사용합니다. 호스트 인터페이스 감지보다 네트워크 격리가 더 중요할 때만 브리지를 선택합니다.

한 번에 설치

대상 Linux 호스트의 root 터미널에 아래 전체 스크립트를 붙여넣습니다. 기본적으로 권장 HOST 네트워크를 사용하고 전체 Compose 설정을 작성하여 fn-knock를 시작합니다.

bash
sh <<'FN_KNOCK_INSTALL'
set -eu

if [ "$(id -u)" -ne 0 ]; then
  echo "Please run this installer in a root terminal." >&2
  exit 1
fi

command -v docker >/dev/null 2>&1 || { echo "Docker is not installed." >&2; exit 1; }
docker compose version >/dev/null 2>&1 || { echo "Docker Compose is not available." >&2; exit 1; }

install_dir=/opt/fn-knock-docker
mkdir -p "$install_dir"
cd "$install_dir"

if [ -e .env ] || [ -e docker-compose.yml ]; then
  echo "Existing .env or docker-compose.yml found; installation stopped." >&2
  exit 1
fi

cat > .env <<'FN_KNOCK_ENV'
FN_KNOCK_IMAGE=hub.fnknock.cn/kcilnk/fn-knock:latest
TZ=Asia/Shanghai
ADMIN_VIEW_PORT=7991
BACKEND_PORT=7998
AUTH_PORT=7997
GO_BACKEND_PORT=7996
GO_REPROXY_PORT=7999
DOCKER_ADMIN_TRUSTED_PROXY_CIDRS=
DOCKER_DISCOVER_LAN_IP=
FN_KNOCK_ENV

cat > docker-compose.yml <<'FN_KNOCK_COMPOSE'
services:
  fn-knock:
    image: ${FN_KNOCK_IMAGE}
    restart: unless-stopped
    network_mode: host
    environment:
      TZ: ${TZ:-Asia/Shanghai}
      FN_KNOCK_RUNTIME_TARGET: docker
      FN_KNOCK_DATA_DIR: /var/lib/fn-knock
      FN_KNOCK_GATEWAY_CONFIG_DIR: /usr/local/etc/fn-knock
      ADMIN_VIEW_PORT: ${ADMIN_VIEW_PORT:-7991}
      BACKEND_PORT: ${BACKEND_PORT:-7998}
      AUTH_PORT: ${AUTH_PORT:-7997}
      GO_BACKEND_PORT: ${GO_BACKEND_PORT:-7996}
      GO_REPROXY_PORT: ${GO_REPROXY_PORT:-7999}
      DOCKER_ADMIN_TRUSTED_PROXY_CIDRS: ${DOCKER_ADMIN_TRUSTED_PROXY_CIDRS:-}
      DOCKER_DISCOVER_LAN_IP: ${DOCKER_DISCOVER_LAN_IP:-}
      ADMIN_VIEW_HOST: 0.0.0.0
      BACKEND_HOST: 127.0.0.1
    volumes:
      - fn_knock_data:/var/lib/fn-knock
      - fn_knock_gateway:/usr/local/etc/fn-knock
    healthcheck:
      test:
        [
          "CMD-SHELL",
          "curl -fsS http://127.0.0.1:${ADMIN_VIEW_PORT:-7991}/api/admin/healthz || exit 1",
        ]
      interval: 10s
      timeout: 5s
      retries: 12
      start_period: 20s

volumes:
  fn_knock_data:
  fn_knock_gateway:
FN_KNOCK_COMPOSE

docker compose pull
docker compose up -d
docker compose ps
FN_KNOCK_INSTALL

설치 디렉터리는 /opt/fn-knock-docker입니다. .env 또는 docker-compose.yml이 이미 있으면 스크립트가 덮어쓰지 않고 중지합니다.

전체 설치 단계

01 Docker 환경 확인

Linux 호스트, Docker Engine, Docker Compose가 필요합니다.

bash
docker version
docker compose version

아래 단계는 HOST 네트워크를 기본으로 사용합니다. 이 모드는 ports나 사용자 지정 bridge를 선언하지 않으며 서비스가 호스트 포트에서 직접 수신합니다.

02 디렉터리 준비 및 이미지 가져오기

bash
mkdir -p /opt/fn-knock-docker
cd /opt/fn-knock-docker
docker pull hub.fnknock.cn/kcilnk/fn-knock:latest

03 .env 만들기

다음 내용을 /opt/fn-knock-docker/.env로 저장합니다.

dotenv
FN_KNOCK_IMAGE=hub.fnknock.cn/kcilnk/fn-knock:latest
TZ=Asia/Shanghai
ADMIN_VIEW_PORT=7991
BACKEND_PORT=7998
AUTH_PORT=7997
GO_BACKEND_PORT=7996
GO_REPROXY_PORT=7999
DOCKER_ADMIN_TRUSTED_PROXY_CIDRS=
DOCKER_DISCOVER_LAN_IP=

주요 설정:

설정기본값설명
FN_KNOCK_IMAGEhub.fnknock.cn/kcilnk/fn-knock:latest기본적으로 latest 사용. 필요하면 Docker Hub 이미지 또는 고정 버전 태그로 변경
ADMIN_VIEW_PORT / GO_REPROXY_PORT7991 / 7999관리 패널과 공개 게이트웨이의 호스트 포트
FN_KNOCK_DOCKER_IPV4_SUBNET172.30.0.0/16브리지 모드 전용. 충돌하면 다른 사설 CIDR로 변경
FN_KNOCK_DOCKER_IPV6_SUBNETfd42:fb33:7f7a:100::/64브리지 모드 전용. Docker bridge IPv6 ULA /64
DOCKER_ADMIN_TRUSTED_PROXY_CIDRS비움7991이 신뢰할 수 있는 리버스 프록시 뒤에 있을 때만 프록시 송신 IP 또는 CIDR 설정
DOCKER_DISCOVER_LAN_IP비움타사 리버스 프록시가 호스트 LAN 주소를 자동 감지하지 못할 때만 설정

04 docker-compose.yml 만들기

권장 설정은 하나의 fn-knock 컨테이너와 HOST 네트워크를 사용하여 호스트의 실제 인터페이스와 IPv6에 직접 접근합니다.

yaml
services:
  fn-knock:
    image: ${FN_KNOCK_IMAGE}
    restart: unless-stopped
    network_mode: host
    environment:
      TZ: ${TZ:-Asia/Shanghai}
      FN_KNOCK_RUNTIME_TARGET: docker
      FN_KNOCK_DATA_DIR: /var/lib/fn-knock
      FN_KNOCK_GATEWAY_CONFIG_DIR: /usr/local/etc/fn-knock
      ADMIN_VIEW_PORT: ${ADMIN_VIEW_PORT:-7991}
      BACKEND_PORT: ${BACKEND_PORT:-7998}
      AUTH_PORT: ${AUTH_PORT:-7997}
      GO_BACKEND_PORT: ${GO_BACKEND_PORT:-7996}
      GO_REPROXY_PORT: ${GO_REPROXY_PORT:-7999}
      DOCKER_ADMIN_TRUSTED_PROXY_CIDRS: ${DOCKER_ADMIN_TRUSTED_PROXY_CIDRS:-}
      DOCKER_DISCOVER_LAN_IP: ${DOCKER_DISCOVER_LAN_IP:-}
      ADMIN_VIEW_HOST: 0.0.0.0
      BACKEND_HOST: 127.0.0.1
    volumes:
      - fn_knock_data:/var/lib/fn-knock
      - fn_knock_gateway:/usr/local/etc/fn-knock
    healthcheck:
      test:
        [
          "CMD-SHELL",
          "curl -fsS http://127.0.0.1:${ADMIN_VIEW_PORT:-7991}/api/admin/healthz || exit 1",
        ]
      interval: 10s
      timeout: 5s
      retries: 12
      start_period: 20s

volumes:
  fn_knock_data:
  fn_knock_gateway:

선택 사항: 브리지 네트워크로 전환

브리지에서는 DDNS가 호스트 인터페이스나 IPv6를 찾지 못할 수 있습니다. “인터페이스에서 가져오기”에 의존하지 않는지 확인한 다음 .env를 다음으로 교체합니다.

dotenv
FN_KNOCK_IMAGE=hub.fnknock.cn/kcilnk/fn-knock:latest
TZ=Asia/Shanghai
ADMIN_VIEW_PORT=7991
BACKEND_PORT=7998
AUTH_PORT=7997
GO_BACKEND_PORT=7996
GO_REPROXY_PORT=7999
FN_KNOCK_DOCKER_IPV4_SUBNET=172.30.0.0/16
FN_KNOCK_DOCKER_IPV6_SUBNET=fd42:fb33:7f7a:100::/64
DOCKER_ADMIN_TRUSTED_PROXY_CIDRS=
DOCKER_DISCOVER_LAN_IP=

그리고 docker-compose.yml을 다음으로 교체합니다.

yaml
services:
  fn-knock:
    image: ${FN_KNOCK_IMAGE}
    restart: unless-stopped
    environment:
      TZ: ${TZ:-Asia/Shanghai}
      FN_KNOCK_RUNTIME_TARGET: docker
      FN_KNOCK_DATA_DIR: /var/lib/fn-knock
      FN_KNOCK_GATEWAY_CONFIG_DIR: /usr/local/etc/fn-knock
      ADMIN_VIEW_PORT: ${ADMIN_VIEW_PORT:-7991}
      BACKEND_PORT: ${BACKEND_PORT:-7998}
      AUTH_PORT: ${AUTH_PORT:-7997}
      GO_BACKEND_PORT: ${GO_BACKEND_PORT:-7996}
      GO_REPROXY_PORT: ${GO_REPROXY_PORT:-7999}
      DOCKER_ADMIN_TRUSTED_PROXY_CIDRS: ${DOCKER_ADMIN_TRUSTED_PROXY_CIDRS:-}
      DOCKER_DISCOVER_LAN_IP: ${DOCKER_DISCOVER_LAN_IP:-}
      ADMIN_VIEW_HOST: 0.0.0.0
      BACKEND_HOST: 127.0.0.1
    ports:
      - "${ADMIN_VIEW_PORT:-7991}:${ADMIN_VIEW_PORT:-7991}"
      - "${GO_REPROXY_PORT:-7999}:${GO_REPROXY_PORT:-7999}"
    networks:
      - fn_knock_net
    volumes:
      - fn_knock_data:/var/lib/fn-knock
      - fn_knock_gateway:/usr/local/etc/fn-knock
    healthcheck:
      test:
        [
          "CMD-SHELL",
          "curl -fsS http://127.0.0.1:${ADMIN_VIEW_PORT:-7991}/api/admin/healthz || exit 1",
        ]
      interval: 10s
      timeout: 5s
      retries: 12
      start_period: 20s

volumes:
  fn_knock_data:
  fn_knock_gateway:

networks:
  fn_knock_net:
    enable_ipv6: true
    ipam:
      config:
        - subnet: ${FN_KNOCK_DOCKER_IPV4_SUBNET:-172.30.0.0/16}
        - subnet: ${FN_KNOCK_DOCKER_IPV6_SUBNET:-fd42:fb33:7f7a:100::/64}

05 시작 및 상태 확인

bash
docker compose up -d
docker compose ps
docker compose logs -f fn-knock

마지막 명령은 로그를 계속 표시합니다. 종료하려면 Ctrl+C를 누릅니다.

첫 접속 및 설정

기본 HOST 모드는 호스트 네트워크 네임스페이스를 직접 사용합니다. 관리 패널은 7991, 게이트웨이는 7999에서 수신하며 나머지 서비스는 내부 또는 호스트 loopback에 유지됩니다.

포트서비스공개 범위용도
7991관리 패널HOST 네트워크첫 접속 시 Docker 관리 패널 비밀번호 설정
7999게이트웨이 / 프록시 진입점HOST 네트워크외부 클라이언트가 프록시 서비스에 접근할 때 사용
7998Rust 백엔드호스트 loopback / 내부일반적으로 기본값 유지
7997인증 프런트엔드호스트 loopback / 내부일반적으로 기본값 유지
7996Go 게이트웨이 관리호스트 loopback / 내부일반적으로 기본값 유지
  1. http://<호스트IP>:7991을 열고 Docker 관리 패널 비밀번호를 설정한 뒤 로그인합니다.
  2. 관리 패널에서 리버스 프록시, 서브도메인, 인증서, 인증을 설정합니다.
  3. 외부 애플리케이션 트래픽을 포트 7999의 게이트웨이로 보냅니다.
  4. 7991이 신뢰할 수 있는 리버스 프록시 뒤에 있다면 .env에서 DOCKER_ADMIN_TRUSTED_PROXY_CIDRS를 설정합니다.
  5. 타사 리버스 프록시가 호스트 LAN 주소를 자동 감지하지 못할 때만 DOCKER_DISCOVER_LAN_IP를 설정합니다.

최신 이미지로 업데이트

.env에서 latest를 유지한 다음 이미지를 다시 가져와 컨테이너를 재생성합니다. 영구 볼륨은 삭제되지 않습니다.

bash
cd /opt/fn-knock-docker
docker compose pull
docker compose up -d
docker compose ps

Watchtower로 자동 업데이트

.env에서 latest를 사용한다면 같은 Docker 호스트에서 Watchtower를 실행할 수 있습니다. 기본적으로 실행 중인 모든 컨테이너를 24시간마다 확인합니다. 이미지 태그의 다이제스트가 변경되면 새 이미지를 가져오고 기존 설정으로 컨테이너를 다시 생성합니다. fn-knock의 마운트된 볼륨은 유지되지만 업데이트 중에는 잠시 재시작됩니다. 고정 버전 태그가 다른 태그로 자동 변경되지는 않습니다.

bash
docker run -d \
  --name watchtower \
  --restart unless-stopped \
  -v /var/run/docker.sock:/var/run/docker.sock \
  nickfedor/watchtower --cleanup

--cleanup은 컨테이너 업데이트가 성공한 후 교체된 이전 이미지를 삭제합니다. 이 옵션을 추가하지 않으면 Watchtower는 기본적으로 이전 이미지를 정리하지 않으므로 저장소와 태그가 <none>으로 표시되는 댕글링 이미지가 남을 수 있습니다. 이 옵션은 fn-knock의 이름 있는 데이터 볼륨을 삭제하지 않습니다.

Watchtower가 시작되었는지 확인하고 검사 기록을 봅니다.

bash
docker ps --filter name=watchtower
docker logs watchtower

이 기본 설정은 호스트에서 실행 중인 모든 컨테이너를 관리하며 Docker Socket을 통해 Docker를 관리할 수 있는 높은 권한을 얻습니다. 신뢰할 수 있는 호스트에서만 사용하고 활성화하기 전에 fn-knock 데이터를 백업하십시오. 자동 업데이트하면 안 되는 다른 컨테이너가 있다면 Watchtower 공식 문서에 따라 컨테이너 이름, 레이블 또는 Scope로 업데이트 범위를 제한하십시오.

관리 패널 비밀번호 재설정

비밀번호를 잊었다면 Docker 호스트에 로그인하여 다음 명령을 실행합니다.

bash
cd /opt/fn-knock-docker && docker compose exec -T fn-knock fn-knock-reset-panel-password

다음에 포트 7991에 접속하면 최초 비밀번호 설정 화면으로 돌아갑니다. 이 명령은 관리 패널 비밀번호, 로그인 세션, 로그인 실패 후 백오프 상태만 지웁니다. 애플리케이션 설정, 프록시 규칙, 인증서, 허용 목록, 로그 또는 데이터 볼륨은 삭제하지 않습니다.

계속 읽기

QQ 커뮤니티: 1081609274