본문으로 건너뛰기

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 명령과 .env의 FN_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}

정적 매핑 콘텐츠 디렉터리를 읽기 전용으로 마운트 ​

정적 파일 및 디렉터리 응답은 컨테이너 내부 절대 경로를 사용하므로 마운트하지 않은 호스트 경로를 직접 읽을 수 없습니다. 사이트마다 독립된 최소 디렉터리를 준비하고 fn-knock 서비스의 volumes에 읽기 전용 마운트를 추가합니다.

yaml
services:
  fn-knock:
    volumes:
      - /srv/public-site:/srv/public-site:ro

Compose를 수정한 뒤 docker compose up -d를 실행하여 컨테이너를 다시 만들고, 관리 화면의 서버 경로 옆에서 찾아보기를 누릅니다. 경로 브라우저는 컨테이너 파일 시스템을 읽으므로 컨테이너 안에 마운트된 내용만 보여야 합니다. /srv/public-site로 들어가 현재 폴더 사용을 누른 뒤 매핑을 저장합니다. 호스트의 /, /etc, fn-knock 데이터 볼륨 또는 키와 시스템 설정이 포함된 디렉터리를 마운트하지 말고 :ro도 생략하지 마십시오.

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