반응형

시놀로지 NAS(DSM)의 Docker에 Stash를 설치하고, 전용 Cloudflare WARP 프록시와 R18.dev PostgreSQL DB를 붙여 R18dev_SQL 스크레이퍼로 메타데이터를 가져오는 구성이다.

Claude를 통해 설치 절차를 도움받았고, 중간중간 트러블슈팅 과정도 함께 작성하였다.

 

* 본 문서의 Docker는 NAS(Synology) 환경에서 구동되고 있으며 Docker 디렉토리가 Volume2에 설치되어 있다.


1. 구성 개요

            stash-net (bridge)
 ┌─────────────────────────────────────────────┐
 │                                             │
 │  stash ──HTTP(S)──▶ stash-socks ──▶ 인터넷 │
 │    │                 (WARP)                 │
 │    └──psql──▶ r18-postgres                  │
 │                    ▲                        │
 │  r18-tools ────────┘ (덤프 갱신/스크레이퍼 설치, 1회성) │
 └─────────────────────────────────────────────┘

 

 

서비스 이미지 역할
stash-socks ghcr.io/mon-ius/docker-warp-socks:latest Stash 전용 WARP 프록시 (9091, HTTP/SOCKS5 겸용). 다른 용도의 warp-socks 컨테이너와 구분하기 위해 이름을 따로 씀
r18-postgres postgres:17-alpine R18.dev 덤프를 적재한 DB (r18)
stash stash-r18:latest (로컬 빌드) stashapp/stash:latest + py3-psycopg2, py3-pysocks
r18-tools postgres:17-alpine profiles: [tools] — up 으로는 안 뜨고 run 으로만 실행

 

파일 구조

/volume2/docker/stash/
├── docker-compose.yml
├── r18-update-cron.sh        # 작업 스케줄러용 정기 갱신 스크립트
├── stash/
│   └── Dockerfile            # Stash 이미지 확장
├── r18-tools/
│   └── r18.sh                # update / install-scraper
│
│   ── 아래는 실행 중 생성/사용되는 데이터 ──
├── config/                   # Stash 설정 (/root/.stash)
│   └── scrapers/R18dev_SQL/  # 스크레이퍼 설치 위치
├── metadata/  cache/  blobs/  generated/
├── r18-db/                   # PostgreSQL 데이터
├── r18-dumps/                # 받은 덤프 (r18-latest.sql.gz)
└── logs/                     # r18-update.log

미디어(e.g. aaa.mp4)는 /volume4/media → 컨테이너 /data (읽기 전용). 

 

2. 사전 준비

2-1. 권한

DSM에서는 일반 계정이 /var/run/docker.sock 에 접근할 수 없다. 모든 docker 명령은 sudo 로 실행한다.

permission denied while trying to connect to the Docker daemon socket

→ sudo 를 빼먹은 것.

 

2-2. 파일 배치

stash-r18.zip 을 /volume2/docker/stash/ 에 올리고 압축 해제. zip 안에 stash-r18/ 상위 폴더가 있으므로 내용물만 꺼낸다. (DSM에 unzip 이 없을 수 있어 7z 사용)

(7z사용이 어렵다면 winSCP와 같은 툴로 접근해서 ftp처럼 경로에 올리면 된다.)

cd /volume2/docker/stash
sudo 7z x stash-r18.zip -o/tmp/stash-r18 -y
sudo cp -r /tmp/stash-r18/stash-r18/. .
sudo rm -rf /tmp/stash-r18

 

docker-compose.yml, stash/Dockerfile, r18-tools/r18.sh, r18-update-cron.sh 가 모두 있는지 확인.

 

unable to prepare context: path "./stash" not found

→ stash/ 폴더(Dockerfile)를 빼먹은 것.

 

2-3. bind mount 폴더 생성

시놀로지 Docker는 없는 bind mount 경로를 자동 생성하지 않는다.

cd /volume2/docker/stash
sudo mkdir -p config/scrapers metadata cache blobs generated r18-db r18-dumps logs
Bind mount failed: '/volume2/docker/stash/r18-db' does not exist

→ 이 단계를 빼먹은 것.

 

2-4. 기존 stash 컨테이너가 있을 때

이름 충돌을 피하려면 기존 컨테이너가 어떻게 만들어졌는지 먼저 확인한다.

sudo docker inspect stash --format '{{ index .Config.Labels "com.docker.compose.project" }} / {{ index .Config.Labels "com.docker.compose.project.working_dir" }}'

 

결과 조치
stash / /volume2/docker/stash 같은 프로젝트. 그대로 up 하면 교체됨
비어 있음 / 다른 프로젝트 sudo docker stop stash && sudo docker rm stash 후 진행 (설정·DB는 bind mount라 유지됨). Container Manager의 다른 프로젝트였다면 그쪽도 정리

3. 설치

3-1. 기동

cd /volume2/docker/stash
sudo docker compose up -d --build --remove-orphans
sudo docker compose ps

stash-socks, r18-postgres 가 healthy 가 된 뒤 stash 가 뜬다. Stash UI: http://<NAS IP>:9999

 

WARP 동작 확인 (warp=on 이 보이면 정상):

sudo docker exec stash-socks curl -sx socks5h://127.0.0.1:9091 https://www.cloudflare.com/cdn-cgi/trace | grep warp

 

3-2. R18.dev DB 적재

덤프가 수 GB라 오래 걸린다. SSH가 끊겨도 계속되도록 스크립트로 실행하는 것을 권장.

cd /volume2/docker/stash
sudo -v                                   # 비밀번호 먼저 입력 (백그라운드에서 프롬프트에 막히지 않게)
sudo nohup bash r18-update-cron.sh >/dev/null 2>&1 &
tail -f logs/r18-update.log               # Ctrl+C 로 보기만 종료, 작업은 계속됨

 

정상 로그:

[r18] 덤프 확인: https://r18.dev/dumps/latest
[r18] 새 덤프 다운로드 완료 (x.xG)
[r18] 임시 DB(r18_new)에 적재 중…
[r18] r18 DB 교체
[r18] 완료 — derived_video N건

 

확인:

sudo docker exec r18-postgres psql -U postgres -d r18 -c "SELECT count(*) FROM derived_video;"

(2026-10 기준 약 191만 건)

 

3-3. 스크레이퍼 설치

sudo docker compose run --rm r18-tools install-scraper

 

install-scraper 가 하는 일:

  1. javstash/R18dev_SQL 저장소의 scrapers/R18dev_SQL/ 을 config/scrapers/R18dev_SQL/ 에 복사
  2. R18dev_SQL.py 수정
    • host="localhost" → host="r18-postgres"
    • password → R18_DB_PASSWORD (기본 postgres)
    • LANG='EN' (일본어: -e SCRAPER_LANG=JA 로 실행)
  3. 안전 실행 래퍼 R18dev_SQL_wrap.py 생성 + yml 이 래퍼를 호출하도록 수정
    • 원본은 결과가 없으면 아무것도 출력하지 않고 죽어서 Stash 가 could not unmarshal json from script output: EOF 를 냄
    • 래퍼는 이 경우 null / [] 을 출력해 '결과 없음' 으로 처리하고, 원인을 Stash 로그에 남김

설치 후 Stash: 설정 › Metadata Providers › Scrapers › Reload scrapers

스크레이퍼를 Stash UI(Available Scrapers)에서 다시 받으면 위 수정이 사라진다. 그럴 땐 install-scraper 를 다시 실행.

3-4. 스크레이퍼 동작 확인

sudo docker exec -i stash sh -c 'cd /root/.stash/scrapers/R18dev_SQL && echo "{\"code\":\"SSIS-001\"}" | python3 R18dev_SQL_wrap.py sceneByFragment' 2>/dev/null

 

"title": "After Abstaining ...", "performers": [{"name": "Donald Trump", ... 처럼 영문 JSON 이 나오면 정상.

 

4. 정기 덤프 갱신 (DSM 작업 스케줄러)

r18-update-cron.sh 동작:

  • 서버 덤프가 바뀌지 않았으면 다운로드·적재 없이 수 초 만에 종료 → 매일 실행 권장
  • r18_new 에 적재 → derived_video 검증 → 통과 시에만 r18 교체 (실패해도 기존 DB 유지)
  • flock 으로 중복 실행 방지, PATH 보정, docker compose run -T (TTY 없음)
  • 로그: logs/r18-update.log (최근 2000줄 유지)

등록

제어판 › 작업 스케줄러 › 생성 › 예약된 작업 › 사용자 정의 스크립트

탭 설정
일반 작업: R18 덤프 갱신 / 사용자: root
스케줄 매일, 04:00 등 한가한 시간
작업 설정 bash /volume2/docker/stash/r18-update-cron.sh
작업 설정 (선택) 실행 세부 정보 메일 → "비정상 종료 시에만"

 

등록 후 목록에서 선택 → 실행 으로 테스트.

강제 재적재:

cd /volume2/docker/stash
sudo FORCE=1 docker compose run --rm r18-tools update
교체 순간에는 덤프 + r18 +r18_new 가 동시에 존재하므로 /volume2 에 DB 크기 2배 이상 여유 공간이 필요하다.

5. Stash 에서 사용

5-1. 한 장면씩

장면 편집 › Scrape with… › JAVStash-R18dev_SQL. 파일명에 품번(ABCD-001 등)만 있으면 된다. 제목이 비어 있으면 Stash 가 파일명을 제목으로 넘긴다.

5-2. 일괄 수집·저장 (Identify)

Identify 는 위치가 두 군데이고 둘 다 숨겨져 있다.

위치 보이는 조건
설정 › Tasks › Library › Identify… 설정 화면 상단 Advanced Mode 를 켜야 보임. 전체 또는 경로 지정
Scenes 목록 › 우측 상단 ⋯ › Identify… 장면을 1개 이상 선택해야 보임

권장 옵션:

항목 설정
Sources JAVStash-R18dev_SQL 만 남김
Title / Details / Date / Code / Director Overwrite (기존 값 보존하려면 Ignore)
Performers / Tags Merge + Create missing
Studio Overwrite + Create missing
Set cover images 켬
Skip matches that have more than one result 켬
Set organised flag 필요 시

처음엔 장면 10개 정도로 시험 후 전체 실행.

결과를 눈으로 보며 저장하려면 Scenes 보기 방식을 Tagger 로 바꿔 소스를 R18dev_SQL 로 지정.


6. 문제 해결

증상 원인 / 조치
permission denied ... docker.sock sudo 누락
path "./stash" not found stash/Dockerfile 누락 → 2-2
Bind mount failed ... does not exist 폴더 미생성 → 2-3
could not unmarshal json from script output: EOF ① r18 DB 없음 → 3-2 ② 래퍼 미설치 → 3-3 다시 실행
database "r18" does not exist 덤프 적재 전이거나 실패 → logs/r18-update.log 확인 후 3-2
스크랩은 되는데 '결과 없음' Stash 로그(Debug)에서 확인: DB 에서 해당 작품을 찾지 못함 = R18.dev 에 없음 / 품번을 추출하지 못함 = 파일명·제목에 품번 없음
배우 이름이 일본어로 표시 아래 6-1

 

6-1. 배우 이름이 일본어로 나올 때

  1. 스크레이퍼 출력 확인 (3-4). 출력이 일본어면 LANG 이 JA → 수정:
   sudo sed -i "s/^LANG=.*/LANG='EN' # JA or EN/" config/scrapers/R18dev_SQL/R18dev_SQL.py

 

  1. 출력은 영문인데 Stash 에 일본어로 보이면 기존 배우와 매칭된 것. 예전에 LANG='JA' 로 스크랩하면 배우가 name=ドナルド・トランプ, aliases=Donald Trump로 생성되므로, 영문 이름이 별칭으로 매칭되어 일본어 이름이 표시된다. → Performers 에서 Name 을 영문으로, 일본어 이름을 Aliases 로 옮긴다.
  2. DB 에 영문 이름 자체가 없는지 확인:
   sudo docker exec r18-postgres psql -U postgres -d r18 -c "
   SELECT A.id, A.name_kanji, A.name_romaji, MT.target_en
   FROM derived_video_actress VA
   LEFT JOIN derived_actress A ON VA.actress_id = A.id
   LEFT JOIN machine_translation MT ON A.name_kanji = MT.source_ja
   WHERE VA.content_id = 'ssis00001';"

name_romaji, target_en 둘 다 비어 있으면 R18.dev 데이터에 영문명이 없는 것 (스크레이퍼는 일본어로 대체).


7. 유지보수

작업 명령
Stash 업데이트 sudo docker compose build --pull stash && sudo docker compose up -d (커스텀 이미지라 pull 만으로는 안 됨)
프록시·DB 이미지 업데이트 sudo docker compose pull stash-socks r18-postgres && sudo docker compose up -d
스크레이퍼 재설치 sudo docker compose run --rm r18-tools install-scraper
덤프 갱신 로그 tail -n 50 /volume2/docker/stash/logs/r18-update.log
전체 상태 sudo docker compose ps
컨테이너 로그 sudo docker compose logs -f stash

 

설정 메모

  • 프록시는 http://stash-socks:9091 로 지정 (warp-socks v8 은 같은 포트에서 HTTP 도 받음). socks5h:// 로 쓰면 파이썬 requests 에 PySocks 가 필요 — 이미지에 py3-pysocks 를 넣어 두었으므로 바꿔도 동작은 함.
  • NO_PROXY 에 내부 컨테이너와 사설 대역이 들어 있어 DB·LAN 통신은 프록시를 타지 않음.
  • 다른 기기에서 이 프록시를 쓰려면 stash-socks 의 ports 주석을 해제 (9092:9091, 기존 warp-socks 의 9091 과 겹치지 않게).
  • DB 비밀번호를 바꾸려면 docker-compose.yml 옆에 .env 를 만들고 R18_DB_PASSWORD=... 지정. DB 최초 생성 전에 정해야 하며, 바꾼 뒤 install-scraper 재실행.

참고

더보기

docker-compose.yml:

# Stash + Cloudflare WARP 프록시 + R18.dev PostgreSQL
# 배치 위치 예: /volume2/docker/stash/  (이 파일, stash/, r18-tools/ 를 같은 폴더에)
#
#   최초 기동 :  docker compose up -d --build
#   DB 덤프   :  docker compose run --rm r18-tools update
#   스크레이퍼:  docker compose run --rm r18-tools install-scraper

x-proxy-env: &proxy-env
  # warp-socks v8 은 9091 한 포트에서 HTTP/SOCKS5 를 같이 제공.
  # http:// 로 지정해야 스크레이퍼(파이썬 requests)도 별도 의존성 없이 프록시를 탄다.
  HTTP_PROXY: http://stash-socks:9091
  HTTPS_PROXY: http://stash-socks:9091
  http_proxy: http://stash-socks:9091
  https_proxy: http://stash-socks:9091
  NO_PROXY: &no-proxy localhost,127.0.0.1,stash-socks,r18-postgres,192.168.0.0/16,10.0.0.0/8,172.16.0.0/12
  no_proxy: *no-proxy

services:
  stash-socks:
    image: ghcr.io/mon-ius/docker-warp-socks:latest
    container_name: stash-socks
    restart: unless-stopped
    # 다른 기기에서도 이 프록시를 쓰려면 아래 주석 해제 (호스트 포트가 다른 warp-socks 컨테이너와 겹치지 않게 조정)
    # ports:
    #   - "9092:9091"   # 기존 warp-socks(9091)와 겹치지 않게
    healthcheck:
      test: ["CMD", "curl", "-x", "socks5h://127.0.0.1:9091", "-fsSL", "https://www.cloudflare.com/cdn-cgi/trace"]
      interval: 30s
      timeout: 10s
      retries: 5
      start_period: 15s
    networks:
      - stash-net

  r18-postgres:
    image: postgres:17-alpine
    container_name: r18-postgres
    restart: unless-stopped
    shm_size: 256mb            # 덤프 import 중 인덱스 생성 시 shared memory 부족 방지
    environment:
      TZ: Asia/Seoul
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: ${R18_DB_PASSWORD:-postgres}
      POSTGRES_DB: postgres
    volumes:
      - /volume2/docker/stash/r18-db:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres"]
      interval: 10s
      timeout: 5s
      retries: 10
    networks:
      - stash-net

  stash:
    build: ./stash                 # stashapp/stash:latest + psycopg2/pysocks
    image: stash-r18:latest
    container_name: stash
    restart: unless-stopped
    ports:
      - "9999:9999"
    environment:
      <<: *proxy-env
      TZ: Asia/Seoul
      STASH_STASH: /data
      STASH_GENERATED: /generated
      STASH_METADATA: /metadata
      STASH_CACHE: /cache
      STASH_BLOBS: /blobs
    volumes:
      - /volume2/docker/stash/config:/root/.stash
      - /volume2/docker/stash/metadata:/metadata
      - /volume2/docker/stash/cache:/cache
      - /volume2/docker/stash/blobs:/blobs
      - /volume2/docker/stash/generated:/generated
      - /volume2/MEDIA:/data:ro
    depends_on:
      stash-socks:
        condition: service_healthy
      r18-postgres:
        condition: service_healthy
    networks:
      - stash-net

  # 1회성 작업용 (up 으로는 뜨지 않음): docker compose run --rm r18-tools <update|install-scraper>
  r18-tools:
    image: postgres:17-alpine
    profiles: ["tools"]
    entrypoint: ["sh", "/r18.sh"]
    command: ["update"]
    environment:
      <<: *proxy-env
      PGHOST: r18-postgres
      PGUSER: postgres
      PGPASSWORD: ${R18_DB_PASSWORD:-postgres}
      FORCE: ${FORCE:-0}
    volumes:
      - ./r18-tools/r18.sh:/r18.sh:ro
      - /volume2/docker/stash/r18-dumps:/dumps
      - /volume2/docker/stash/config/scrapers:/scrapers
    depends_on:
      stash-socks:
        condition: service_healthy
      r18-postgres:
        condition: service_healthy
    networks:
      - stash-net

networks:
  stash-net:
    driver: bridge
반응형

내용 참고 : https://luckygg.tistory.com/55?category=684086


GigE Interface의 Vision을 사용한다면 Maker에서 권장하는 NIC가 있는데 대부분 인텔의 NIC를 추천하는 경우가 많다.


GigE Vision 사용시 끊김, 또는 지연 발생시 아래와 같은 설정을 통해 최적화를 해주는게 좋다.


  • 점보 프레임 또는 패킷(Jumbo Frame / Packet) : 설정값(최대치)- 9014Byte



  • 수신 버퍼(Receive Buffers) : 설정값(최대치) - 2048


  • 인터럽트 조절 속도(Interrupt Moderation Rate) : 설정값(최대치) - Extreme


반응형

https://iknowwhatyoudownload.com/en/peer/

위 주소로 접속하면 접속한 기기의 외부IP 기준으로 토렌트 다운로드 기록을 보여준다.



물론 100% 정확한 결과는 아니다.


대부분의 일반 인터넷 가입자는 유동IP(할당되는 IP가 고정이 아니라 모뎀이나 공유기에 상황에 따라 매번 다른 IP부여)이기 때문에 현재 IP를 다른 사람이 사용했을수도 있다.

반응형

정식 펌웨어(3.0.0.4.384_45149) 기준

좌측메뉴의 고급설정 → WAN → ISP의 특수요건입니다. → MAC 어드레스


반응형

GoodbyeDPI : 수동적 DPI(Deep Packet Inspection; 심층 패킷 분석) 차단 및 능동적 DPI 우회 프로그램.


GUI버전 다운로드링크 : https://github.com/Include-sys/GUI-for-GoodbyeDPI/releases


Mirror :

GUI_For_GoodbyeDPI_32Bit.zip

GUI_For_GoodbyeDPI_64Bit.zip



1. GOODBYEDPI 다운로드

자신의 사용 윈도우 환경에 맞게 32비트 또는 64비트 첨부파일 다운로드 하여 압축해제

(확인 방법은 제어판\시스템 및 보안\시스템)


2. 압축을 푼뒤 [ GoodByeDPI GUI ] 파일 실행

압축을 푼뒤 [ GoodByeDPI GUI ] 파일 실행

3. GoodbyeDPI GUI 실행하고 Start 클릭!



반응형

현재 거주중인 곳에 KT의 하이브리드(?) 셋탑박스가 설치되어 있다.


평상시에는 Skylife 위성안테나를 통해 실시간 tv를 시청하고 기상이 안좋아 신호품질이 안좋을때 자동으로 kt iptv로 전환된다.


물론 vod서비스도 kt iptv 즉 네트워크를 통해 이용한다.


셋탑박스로  WAN이 연결되고 셋탑박스 LAN 포트에서 나오는 선이 공유기로 연결되서 무선랜을 사용할 수 있었다.


그런데 셋탑박스 전원을 꺼버리면 LAN포트가 죽으면서 무선랜과 각방 LAN포트를 사용할수 없게 되는거다.


대기전력도 그리 적을거 같진 않은데 이놈을 꺼버리고 싶었다.


그래서 공유기를 최상위에 두고 하위에 셋탑박스를 설치해보기로 했다.


좀 검색해보니 olleh skylife 셋탑박스는 별도의 사설ip로 서비스를 이용하는것 같다는 글을 찾아 볼 수 있었다.


그래서 최상위에 두어야만 작동한다는 내용.



그래도 해결방법은 있다.


공유기의 iptv 설정에서 해당 포트를 활성화해주면 된다.



'Network' 카테고리의 다른 글

ASUS 공유기 MAC주소 변경  (0) 2019.03.02
GoodbyeDPI 사용 HTTPS 차단 우회하기  (0) 2019.02.24
Angry IP scanner - 아이피, 포트 스캐너 (IP, Port scanner)  (1) 2015.05.05
IDC케이블 분해/조립하기  (0) 2013.06.26
Bluetooth  (0) 2013.03.12

+ Recent posts