惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Forbes - Security
Forbes - Security
L
Lohrmann on Cybersecurity
Simon Willison's Weblog
Simon Willison's Weblog
P
Proofpoint News Feed
P
Privacy International News Feed
The Hacker News
The Hacker News
AWS News Blog
AWS News Blog
S
Securelist
P
Proofpoint News Feed
Recent Announcements
Recent Announcements
GbyAI
GbyAI
B
Blog RSS Feed
A
About on SuperTechFans
C
CXSECURITY Database RSS Feed - CXSecurity.com
Y
Y Combinator Blog
Microsoft Azure Blog
Microsoft Azure Blog
H
Hackread – Cybersecurity News, Data Breaches, AI and More
Cyberwarzone
Cyberwarzone
I
Intezer
T
Tor Project blog
T
The Blog of Author Tim Ferriss
The GitHub Blog
The GitHub Blog
云风的 BLOG
云风的 BLOG
Recorded Future
Recorded Future
aimingoo的专栏
aimingoo的专栏
Cisco Talos Blog
Cisco Talos Blog
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
W
WeLiveSecurity
D
DataBreaches.Net
U
Unit 42
Project Zero
Project Zero
Martin Fowler
Martin Fowler
V
V2EX
The Last Watchdog
The Last Watchdog
Security Archives - TechRepublic
Security Archives - TechRepublic
C
Cisco Blogs
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
V2EX - 技术
V2EX - 技术
Hacker News - Newest:
Hacker News - Newest: "LLM"
T
Threat Research - Cisco Blogs
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
T
Tenable Blog
F
Full Disclosure
T
The Exploit Database - CXSecurity.com
H
Heimdal Security Blog
Latest news
Latest news
Webroot Blog
Webroot Blog

DEV Community

Authentication Security Deep Dive: From Brute Force to Salted Hashing (With Java Examples) Why AI Systems Don’t Fail — They Drift Spilling beans for how i learn for exam😁"Reinforcement Learning Cheat Sheet" I Replaced Chrome with Safari for AI Browser Automation. Here's What Broke (and What Finally Worked) How Python Borrows Other People's Work The $40 Architecture: Processing 1 Billion API Requests with 99.99% Uptime Vibe Coding: A Workflow Guide (From Zero to SaaS) Most webhook security guides protect the wrong side. The scary part is delivery. Headless CMS for TanStack Start: Build a Blog with Cosmic EU Age Verification App "Hacked in 2 Minutes" — What Actually Happened Comfy Cloud’s delete function does not actually remove files Running AI Models on GPU Cloud Servers: A Beginner Guide Event-driven media intelligence with AWS Step Functions and Bedrock I scored 500 AI prompts across 8 quality dimensions — here's what broke How to Call Google Gemini API from Next.js (Free Tier, No Backend Needed) The Portal Protocol: Reclaiming Human Connection in the Age of AI How to Fix Your Team's Scattered Knowledge Problem With a Self-Hosted Forum Intro to tc Cloud Functors: A Graph-First Mental Model for the Modern Cloud Designing Multi-Tenant Backends With Both Ownership and Team Access I Built a Neumorphic CSS Library with 77+ Components — Here's What I Learned PostgreSQL Performance Optimization: Why Connection Pooling Is Critical at Scale Cómo construí un SaaS multi-rubro para gestionar expensas en Argentina con FastAPI + Vue 3 🚀 I Built an Ethical Hacking Scanner Tool – Open Source Project I Replaced /usage and /context in Claude Code With a Single Statusline A Pythonic Way to Handle Emails (IMAP/SMTP) with Auto-Discovery and AI-Ready Design I Collected 8.9 Million Polymarket Price Points — Here's What I Found About How Markets Really Move EcoTrack AI — Carbon Footprint Tracker & Dashboard Everyone's Using AI. No One Agrees How. 5 self-hosted ebook managers worth trying in 2026 Building Your First AI Agent with LangChain: From Chatbot to Autonomous Assistant Common SOC 2 Failures (Real World) Stop Vibe-Checking Your AI App: A Practical Guide to Evals How to Use SonarQube and SonarScanner Locally to Level Up Your Code Quality Your Next To-Do App Is Dead — I Replaced Mine with an OpenClaw AI Sign a Nostr event in 60 lines of Python using coincurve — no nostr-sdk, no nbxplorer, no rust toolchain ITGC Audit Explained Like You’re in Big 4 Patch Tuesday abril 2026: Microsoft parcha 163 vulnerabilidades y un zero-day en SharePoint Stop scraping everything: a better way to track competitor price changes Listing on MCPize + the Official MCP Registry while routing payments OUTSIDE the marketplace — how I kept 100% of my x402 revenue Building an AI-Powered Risk Intelligence System Using Serverless Architecture Why We Ripped Function Overloading Out of Our AI Toolchain Testing AI-Generated Code: How to Actually Know If It Works SaaS Churn Is Killing Your Business. Here Is What to Do About It (Without a Support Team) The Speed of AI Is No Longer Linear - And Self-Improving Models Are Why How to Implement RBAC for MCP Tools: A Practical Guide for Engineering Teams From Standard Quote to Persuasive Proposal: AI Automation for Arborists I built a CLI that scaffolds complete multi-tenant SaaS apps Axios CVE-2025–62718: The Silent SSRF Bug That Could Be Hiding in Your Node.js App Right Now The dashboard that ended our friendship Data Pipelines Explained Simply (and How to Build Them with Python) The Hidden Cost of AI Systems Nobody Talks About. undefined vs undeclared, and how typeof behaves Switching from file-based jobs to NATS/Kafka in Rust without changing code io_uring Adventures: Rust Servers That Love Syscalls Why Agentic AI is Killing the Traditional Database The POUR principles of web accessibility for developers and designers Quantum Neural Network 3D — A Deep Dive into Interactive WebGL Visualization How To Install Caveman In Codex On macOS And Windows Automation Pipeline Reliability: Why Your Workflow Breaks When Nobody Is Watching I Built an 'Open World' AI Coding Agent — It Works From ANY Folder From Freelancing to Product: A Tech Service Company's SaaS Transformation China's AI Giants: Adding Tencent Hunyuan & ByteDance Doubao to AI University (74 Providers) On the Vibe Coders and Their Lies clerk: Auto-Summarize Your Claude Code Sessions AI Weekly — 2026/04/10–04/17 | The Model Lockdown Is Here, but the Toolchain Is the Real Battleground AI 週報 — 2026/04/10–2026/04/17 模型封鎖潮來了,但工具鏈才是真戰場 Maybe this is how Open-Source apps are born... 🚀 Fine-Tune LLMs with LoRA and QLoRA: 2026 Guide tRPC v11 + Next.js App Router: End-to-End Type Safety Without the Boilerplate ShadCN UI in 2026: Why I Stopped Installing Component Libraries and Started Owning My Components SaaS Billing in React Server Components: Stripe + Supabase Without a Single `useEffect` Join our DEV Weekend Challenge — $1,000 in Prizes Across TEN winners! Submissions Due April 20 at 6:59 AM UTC. Implementing FSRS Spaced Repetition in Flutter + Supabase — Adding Memory Science to an AI Learning App "I Texted My Localhost From the Train — Claude Code Fixed the Bug Before I Got Home" I Built a Sales Prep AI and It Went Deeper Than Expected Design to Code #2: One JSON, Eleven Outputs Solving the 100M-Row Problem: A Summary Table Pattern for High-Volume Push Notification Logs Flutter Web With Wasm: What Actually Changes For Developers I Built 50 Royalty-Free Soundtracks for My Side Project in a Weekend Using AI Music Generation The Vibe Coding Security Checklist: 7 Things to Check Before You Ship Stop Letting Googlebot Guess Fix Your React App's SEO Right Desconstruindo o Streaming do LinkedIn: Como Criar um Engine de Extração de Vídeo de Alta Performance com HLS e FFmpeg (EDA Part-1) EDA (Exploratory Data Analysis) Explained With Real Life — Why Looking at Your Data Is the Most Important Step in Machine Learning Brand Relationship Management at Scale: Our 4-Touch Outreach System for 200+ Brands Why String.fromEnvironment() Might Return an Empty String in Dart JGuardrails 1.0.0 — Hardening Java LLM Apps Against Jailbreaks, Toxicity, and Prompt Injection Plan and Schedule a Full Week of Threads Content From One Claude Conversation Coding Cat Oran Ep3, Five Tables Changed Everything Updated: BFF Pattern I'm done watching freelancers get buried by 200 proposals. So I'm building the alternative. This is my first post BFS Algorithm in Java Step by Step Tutorial with Examples Tracking LLM Pricing Monthly: An Open Dataset for 22 AI Models How We Measure Content ROI on a Comparison Site: Revenue Attribution Without Perfect Data Introducing Nova AI Ops: The AI-Native Operating System for SRE Teams I built a free desktop video downloader for Windows — Grabbit How Talkie OCR Helps Vision-Impaired & Dyslexic Users Read the World Around Them VRCFaceTracking安装和iPhone面捕配置教程,有bug Even CrowdStrike Can't See Your Agents The Automation Gold Rush: What n8n Workflows and Claude Are Opening Up for Developers Right Now
Synology NAS에 OpenClaw 설치하기
ageofclick · 2026-05-20 · via DEV Community

들어가며

이번 글에서는 Synology NAS에 OpenClaw를 Docker Compose 기반으로 신규 설치하는 과정을 정리한다.

Synology DSM 환경은 일반적인 Ubuntu 서버와 다르다. NAS에 직접 Node.js/npm 기반으로 OpenClaw를 설치할 수도 있지만, 장기 운영 관점에서는 Docker Compose 기반 구성이 더 깔끔하다.

Docker Compose로 구성하면 다음 장점이 있다.

  • OpenClaw 실행 환경을 Synology host와 분리할 수 있음
  • gateway와 CLI 실행 환경을 일관되게 유지할 수 있음
  • 재부팅 후 자동 실행을 restart: unless-stopped로 처리할 수 있음
  • .openclaw 설정과 workspace를 volume으로 분리해 보존할 수 있음
  • GitHub CLI, ripgrep, jq 같은 코딩 작업용 도구를 이미지에 함께 포함할 수 있음
  • Synology 터미널의 TTY/리치 출력 문제를 우회하기 쉬움

최종 구성

최종 디렉터리 구조는 다음과 같이 잡는다.

/volume1/docker/openclaw
├── docker-compose.yml
├── Dockerfile
├── .env
└── .openclaw/
    ├── workspace/
    ├── logs/
    └── cron/

Enter fullscreen mode Exit fullscreen mode

컨테이너 내부에서는 OpenClaw 설정 경로를 다음처럼 사용한다.

/home/node/.openclaw
/home/node/.openclaw/workspace

Enter fullscreen mode Exit fullscreen mode

즉, NAS host의 실제 경로는 다음이지만,

/volume1/docker/openclaw/.openclaw

Enter fullscreen mode Exit fullscreen mode

컨테이너 내부에서는 다음 경로로 보이게 한다.

/home/node/.openclaw

Enter fullscreen mode Exit fullscreen mode

이 구조의 핵심은 다음과 같다.

  • OpenClaw 설정과 workspace는 NAS의 /volume1/docker/openclaw/.openclaw에 보존
  • 컨테이너는 언제든 삭제/재생성 가능
  • OpenClaw CLI는 host에 직접 설치하지 않고 openclaw-cli 컨테이너로 실행
  • OpenClaw gateway는 openclaw-gateway 컨테이너로 상시 실행

사전 준비

Synology NAS에는 DSM의 Container Manager가 설치되어 있어야 한다.

SSH 터미널에서 Docker와 Compose가 정상 동작하는지 확인한다.

sudo docker version
sudo docker compose version

Enter fullscreen mode Exit fullscreen mode

Synology에서는 일반 사용자 계정이 Docker daemon socket에 직접 접근하지 못하는 경우가 많다.

확인:

ls -al /var/run/docker.sock

Enter fullscreen mode Exit fullscreen mode

예시:

srw-rw---- 1 root root 0 docker.sock

Enter fullscreen mode Exit fullscreen mode

이 경우 일반 사용자로는 docker pull 같은 명령이 실패한다.

따라서 이 글에서는 모든 Docker 명령을 다음처럼 sudo 기준으로 실행한다.

sudo docker compose ...

Enter fullscreen mode Exit fullscreen mode


설치 디렉터리 생성

OpenClaw Compose 프로젝트용 디렉터리를 만든다.

sudo mkdir -p /volume1/docker/openclaw
cd /volume1/docker/openclaw

Enter fullscreen mode Exit fullscreen mode

OpenClaw 설정과 workspace를 저장할 .openclaw 디렉터리도 미리 만든다.

sudo mkdir -p /volume1/docker/openclaw/.openclaw
sudo mkdir -p /volume1/docker/openclaw/.openclaw/workspace
sudo mkdir -p /volume1/docker/openclaw/.openclaw/logs
sudo mkdir -p /volume1/docker/openclaw/.openclaw/cron

Enter fullscreen mode Exit fullscreen mode


권한 정리

OpenClaw Docker 이미지는 컨테이너 내부에서 node 사용자로 실행된다. 일반적으로 이 사용자의 UID는 1000이다.

따라서 host의 .openclaw 디렉터리를 컨테이너 내부 사용자가 쓸 수 있도록 권한을 맞춘다.

sudo chown -R 1000:1000 /volume1/docker/openclaw/.openclaw

Enter fullscreen mode Exit fullscreen mode

권한이 맞지 않으면 다음과 같은 에러가 발생할 수 있다.

EACCES: permission denied, open '/home/node/.openclaw/logs/config-health.json'

Enter fullscreen mode Exit fullscreen mode


커스텀 Dockerfile 작성

OpenClaw 기본 이미지만으로도 gateway 실행은 가능하다. 하지만 코딩 에이전트 용도로도 사용할 계획이라면 gh, ripgrep, jq를 함께 넣어두는 것이 편하다.

/volume1/docker/openclaw/Dockerfile

FROM ghcr.io/openclaw/openclaw:latest

USER root

RUN apt-get update \
  && apt-get install -y --no-install-recommends gh ripgrep jq \
  && rm -rf /var/lib/apt/lists/*

USER node

Enter fullscreen mode Exit fullscreen mode

각 도구의 용도는 다음과 같다.

  • gh: GitHub CLI
  • ripgrep: 빠른 코드 검색용 rg
  • jq: JSON 출력 확인 및 가공

.env 작성

/volume1/docker/openclaw/.env

OPENCLAW_CONFIG_DIR=/volume1/docker/openclaw/.openclaw
OPENCLAW_WORKSPACE_DIR=/volume1/docker/openclaw/.openclaw/workspace

OPENCLAW_GATEWAY_PORT=18789
OPENCLAW_TZ=Asia/Seoul

# GitHub CLI 또는 GitHub Copilot 연동이 필요할 경우 입력
GH_TOKEN=
GITHUB_TOKEN=
COPILOT_GITHUB_TOKEN=

Enter fullscreen mode Exit fullscreen mode

.env에는 GitHub token, Copilot token 같은 민감정보가 들어갈 수 있으므로 권한을 제한한다.

sudo chmod 600 /volume1/docker/openclaw/.env

Enter fullscreen mode Exit fullscreen mode


docker-compose.yml 작성

/volume1/docker/openclaw/docker-compose.yml

services:
  openclaw-gateway:
    build:
      context: .
      dockerfile: Dockerfile
    image: local/openclaw-gh:latest
    container_name: openclaw-gateway
    env_file:
      - .env
    environment:
      HOME: /home/node
      OPENCLAW_HOME: /home/node
      TERM: xterm-256color

      OPENCLAW_STATE_DIR: /home/node/.openclaw
      OPENCLAW_CONFIG_PATH: /home/node/.openclaw/openclaw.json
      OPENCLAW_CONFIG_DIR: /home/node/.openclaw
      OPENCLAW_WORKSPACE_DIR: /home/node/.openclaw/workspace

      OPENCLAW_GATEWAY_TOKEN: ${OPENCLAW_GATEWAY_TOKEN:-}
      OPENCLAW_ALLOW_INSECURE_PRIVATE_WS: ${OPENCLAW_ALLOW_INSECURE_PRIVATE_WS:-}
      OPENCLAW_DISABLE_BONJOUR: ${OPENCLAW_DISABLE_BONJOUR:-}

      GH_TOKEN: ${GH_TOKEN:-}
      GITHUB_TOKEN: ${GITHUB_TOKEN:-}
      COPILOT_GITHUB_TOKEN: ${COPILOT_GITHUB_TOKEN:-}

      TZ: ${OPENCLAW_TZ:-Asia/Seoul}
    volumes:
      - ${OPENCLAW_CONFIG_DIR}:/home/node/.openclaw
      - ${OPENCLAW_WORKSPACE_DIR}:/home/node/.openclaw/workspace
    ports:
      - "127.0.0.1:${OPENCLAW_GATEWAY_PORT:-18789}:18789"
    extra_hosts:
      - "host.docker.internal:host-gateway"
    cap_drop:
      - NET_RAW
      - NET_ADMIN
    security_opt:
      - no-new-privileges:true
    init: true
    restart: unless-stopped
    command:
      [
        "node",
        "dist/index.js",
        "gateway",
        "--bind",
        "lan",
        "--port",
        "18789"
      ]
    healthcheck:
      test:
        [
          "CMD",
          "node",
          "-e",
          "fetch('http://127.0.0.1:18789/healthz').then((r)=>process.exit(r.ok?0:1)).catch(()=>process.exit(1))"
        ]
      interval: 30s
      timeout: 5s
      retries: 5
      start_period: 20s

  openclaw-cli:
    image: local/openclaw-gh:latest
    network_mode: "service:openclaw-gateway"
    env_file:
      - .env
    environment:
      HOME: /home/node
      OPENCLAW_HOME: /home/node
      TERM: xterm-256color

      OPENCLAW_STATE_DIR: /home/node/.openclaw
      OPENCLAW_CONFIG_PATH: /home/node/.openclaw/openclaw.json
      OPENCLAW_CONFIG_DIR: /home/node/.openclaw
      OPENCLAW_WORKSPACE_DIR: /home/node/.openclaw/workspace

      OPENCLAW_GATEWAY_TOKEN: ${OPENCLAW_GATEWAY_TOKEN:-}
      OPENCLAW_ALLOW_INSECURE_PRIVATE_WS: ${OPENCLAW_ALLOW_INSECURE_PRIVATE_WS:-}

      GH_TOKEN: ${GH_TOKEN:-}
      GITHUB_TOKEN: ${GITHUB_TOKEN:-}
      COPILOT_GITHUB_TOKEN: ${COPILOT_GITHUB_TOKEN:-}

      BROWSER: echo
      TZ: ${OPENCLAW_TZ:-Asia/Seoul}
    volumes:
      - ${OPENCLAW_CONFIG_DIR}:/home/node/.openclaw
      - ${OPENCLAW_WORKSPACE_DIR}:/home/node/.openclaw/workspace
    cap_drop:
      - NET_RAW
      - NET_ADMIN
    security_opt:
      - no-new-privileges:true
    stdin_open: true
    tty: true
    init: true
    entrypoint: ["node", "dist/index.js"]
    depends_on:
      - openclaw-gateway

Enter fullscreen mode Exit fullscreen mode

여기서 중요한 점은 두 가지다.

첫째, .envOPENCLAW_CONFIG_DIROPENCLAW_WORKSPACE_DIRNAS host 경로다.

OPENCLAW_CONFIG_DIR=/volume1/docker/openclaw/.openclaw
OPENCLAW_WORKSPACE_DIR=/volume1/docker/openclaw/.openclaw/workspace

Enter fullscreen mode Exit fullscreen mode

둘째, compose의 environment 안에 있는 OPENCLAW_CONFIG_DIROPENCLAW_WORKSPACE_DIR컨테이너 내부 경로다.

OPENCLAW_CONFIG_DIR: /home/node/.openclaw
OPENCLAW_WORKSPACE_DIR: /home/node/.openclaw/workspace

Enter fullscreen mode Exit fullscreen mode

둘을 혼동하면 컨테이너 안에서 host 경로를 만들려고 하거나, permission error가 발생할 수 있다.


bridge 모드로 운영하는 이유

이 compose 파일은 Docker bridge 모드를 기준으로 한다.

ports:
  - "127.0.0.1:18789:18789"

Enter fullscreen mode Exit fullscreen mode

이 설정은 OpenClaw gateway를 NAS의 127.0.0.1:18789에만 노출한다.

즉, 같은 내부망에 있는 다른 기기에서 직접 http://NAS_IP:18789로 접근할 수 없고, SSH 터널을 통해서만 접근한다.

이 방식의 장점은 다음과 같다.

  • gateway를 외부 네트워크에 직접 노출하지 않음
  • 기존 SSH 터널 접속 방식과 잘 맞음
  • Synology 방화벽과 별개로 노출 범위를 줄일 수 있음

왜 gateway bind는 lan인가

처음에는 gateway를 loopback으로 두는 것이 더 안전해 보인다.

하지만 Docker bridge 모드에서는 컨테이너 내부의 loopback은 NAS host의 loopback이 아니라 컨테이너 자기 자신의 loopback이다.

따라서 host의 published port를 통해 컨테이너 gateway에 접근하려면, 컨테이너 내부 OpenClaw는 loopback이 아니라 lan으로 bind하는 것이 안전하다.

compose에서는 다음처럼 설정했다.

command:
  [
    "node",
    "dist/index.js",
    "gateway",
    "--bind",
    "lan",
    "--port",
    "18789"
  ]

Enter fullscreen mode Exit fullscreen mode

host 쪽 포트는 여전히 127.0.0.1:18789에만 열어두기 때문에 외부 노출 범위는 제한된다.


커스텀 이미지 빌드

Compose 프로젝트 폴더로 이동한다.

cd /volume1/docker/openclaw

Enter fullscreen mode Exit fullscreen mode

커스텀 이미지를 빌드한다.

sudo docker compose build

Enter fullscreen mode Exit fullscreen mode

캐시 없이 다시 빌드하려면 다음 명령을 사용한다.

sudo docker compose build --no-cache

Enter fullscreen mode Exit fullscreen mode


OpenClaw gateway 실행

gateway를 실행한다.

sudo docker compose up -d openclaw-gateway

Enter fullscreen mode Exit fullscreen mode

빌드와 실행을 한 번에 하려면 다음 명령을 사용한다.

sudo docker compose up -d --build openclaw-gateway

Enter fullscreen mode Exit fullscreen mode

상태 확인:

sudo docker compose ps

Enter fullscreen mode Exit fullscreen mode

로그 확인:

sudo docker compose logs -f openclaw-gateway

Enter fullscreen mode Exit fullscreen mode


health check

NAS host에서 gateway health check를 확인한다.

curl -fsS http://127.0.0.1:18789/healthz
curl -fsS http://127.0.0.1:18789/readyz

Enter fullscreen mode Exit fullscreen mode

정상이라면 HTTP 응답이 반환된다.


SSH 터널로 대시보드 접속

이 구성에서는 gateway가 NAS의 127.0.0.1:18789에만 노출되어 있으므로, 외부 기기에서는 SSH 터널을 통해 접속한다.

ssh -L 18789:127.0.0.1:18789 agent@<NAS_IP>

Enter fullscreen mode Exit fullscreen mode

그 다음 브라우저에서 접속한다.

http://127.0.0.1:18789

Enter fullscreen mode Exit fullscreen mode

이 방식은 브라우저의 localhost secure context 조건을 만족시키기 쉽고, OpenClaw gateway를 내부망에 직접 노출하지 않아도 된다.


OpenClaw CLI 실행 방식

Docker Compose 구조에서는 host에 openclaw CLI를 직접 설치하지 않는다. 대신 openclaw-cli 서비스를 통해 실행한다.

버전 확인:

sudo docker compose run -T --rm openclaw-cli --version

Enter fullscreen mode Exit fullscreen mode

상태 확인:

sudo docker compose run -T --rm openclaw-cli status --json

Enter fullscreen mode Exit fullscreen mode

doctor:

sudo docker compose run -T --rm openclaw-cli doctor

Enter fullscreen mode Exit fullscreen mode

모델 상태 확인:

sudo docker compose run -T --rm openclaw-cli models status --json

Enter fullscreen mode Exit fullscreen mode

cron 목록 확인:

sudo docker compose run -T --rm openclaw-cli cron list

Enter fullscreen mode Exit fullscreen mode


-T 옵션을 언제 쓰고 언제 빼야 하나

Docker Compose에서 -T는 pseudo-TTY 할당을 끄는 옵션이다.

Synology 터미널에서 리치 출력이 불안정하거나, JSON 출력만 확인할 때는 -T를 붙이는 편이 안정적이다.

예:

sudo docker compose run -T --rm openclaw-cli status --json
sudo docker compose run -T --rm openclaw-cli doctor

Enter fullscreen mode Exit fullscreen mode

하지만 로그인, wizard, device auth처럼 interactive TTY가 필요한 명령에는 -T를 붙이면 안 된다.

잘못된 예:

sudo docker compose run -T --rm openclaw-cli models auth login --provider github-copilot

Enter fullscreen mode Exit fullscreen mode

이 경우 다음 에러가 날 수 있다.

models auth login requires an interactive TTY

Enter fullscreen mode Exit fullscreen mode

올바른 예:

sudo docker compose run --rm openclaw-cli models auth login-github-copilot

Enter fullscreen mode Exit fullscreen mode

정리하면 다음과 같다.

상태 확인, doctor, JSON 출력 → -T 사용
로그인, wizard, device auth → -T 제거

Enter fullscreen mode Exit fullscreen mode


컨테이너 내부 shell 접속

CLI 컨테이너 shell:

sudo docker compose run --rm --entrypoint sh openclaw-cli

Enter fullscreen mode Exit fullscreen mode

실행 중인 gateway 컨테이너 shell:

sudo docker compose exec openclaw-gateway sh

Enter fullscreen mode Exit fullscreen mode

명령만 실행:

sudo docker compose run -T --rm --entrypoint sh openclaw-cli -lc 'pwd && ls -al'

Enter fullscreen mode Exit fullscreen mode

설치한 도구 확인:

sudo docker compose run -T --rm --entrypoint sh openclaw-cli -lc 'gh --version && rg --version && jq --version'

Enter fullscreen mode Exit fullscreen mode


GitHub CLI 토큰 설정

컨테이너 안에서 gh를 사용하려면 GitHub token을 .env에 넣는다.

GH_TOKEN=github_pat_xxxxxxxxxxxxxxxxx
GITHUB_TOKEN=github_pat_xxxxxxxxxxxxxxxxx

Enter fullscreen mode Exit fullscreen mode

.env 수정 후 gateway를 재시작한다.

sudo docker compose restart openclaw-gateway

Enter fullscreen mode Exit fullscreen mode

컨테이너 안에서 gh 인증 상태 확인:

sudo docker compose run -T --rm --entrypoint gh openclaw-cli auth status

Enter fullscreen mode Exit fullscreen mode

repo 접근 확인:

sudo docker compose run -T --rm --entrypoint gh openclaw-cli repo list

Enter fullscreen mode Exit fullscreen mode

.env에는 민감정보가 들어가므로 공개 저장소에 올리면 안 된다.


자주 쓰는 명령어

프로젝트 폴더 이동

cd /volume1/docker/openclaw

Enter fullscreen mode Exit fullscreen mode

이미지 빌드

sudo docker compose build

Enter fullscreen mode Exit fullscreen mode

캐시 없이 빌드

sudo docker compose build --no-cache

Enter fullscreen mode Exit fullscreen mode

gateway 실행

sudo docker compose up -d openclaw-gateway

Enter fullscreen mode Exit fullscreen mode

빌드 포함 실행

sudo docker compose up -d --build openclaw-gateway

Enter fullscreen mode Exit fullscreen mode

gateway 로그 확인

sudo docker compose logs -f openclaw-gateway

Enter fullscreen mode Exit fullscreen mode

gateway 재시작

sudo docker compose restart openclaw-gateway

Enter fullscreen mode Exit fullscreen mode

중지 및 컨테이너 제거

sudo docker compose down

Enter fullscreen mode Exit fullscreen mode

상태 JSON 확인

sudo docker compose run -T --rm openclaw-cli status --json

Enter fullscreen mode Exit fullscreen mode

doctor 실행

sudo docker compose run -T --rm openclaw-cli doctor

Enter fullscreen mode Exit fullscreen mode

shell 접속

sudo docker compose run --rm --entrypoint sh openclaw-cli

Enter fullscreen mode Exit fullscreen mode

설치 도구 확인

sudo docker compose run -T --rm --entrypoint sh openclaw-cli -lc 'gh --version && rg --version && jq --version'

Enter fullscreen mode Exit fullscreen mode

업데이트

sudo docker compose pull
sudo docker compose build --no-cache
sudo docker compose down
sudo docker compose up -d openclaw-gateway

Enter fullscreen mode Exit fullscreen mode


자주 만난 에러와 해결

1. no configuration file provided: not found

no configuration file provided: not found

Enter fullscreen mode Exit fullscreen mode

원인:

docker-compose.yml이 없는 디렉터리에서 docker compose 실행

Enter fullscreen mode Exit fullscreen mode

해결:

cd /volume1/docker/openclaw
sudo docker compose run -T --rm openclaw-cli doctor

Enter fullscreen mode Exit fullscreen mode

또는 compose 파일 경로를 직접 지정한다.

sudo docker compose \
  -f /volume1/docker/openclaw/docker-compose.yml \
  --env-file /volume1/docker/openclaw/.env \
  run -T --rm openclaw-cli doctor

Enter fullscreen mode Exit fullscreen mode


2. .openclaw EACCES

EACCES: permission denied, open '/home/node/.openclaw/logs/config-health.json'

Enter fullscreen mode Exit fullscreen mode

원인:

컨테이너 내부 node 사용자(uid 1000)가 host bind mount 폴더에 쓰기 불가

Enter fullscreen mode Exit fullscreen mode

해결:

sudo chown -R 1000:1000 /volume1/docker/openclaw/.openclaw

Enter fullscreen mode Exit fullscreen mode


3. Docker socket permission denied

permission denied while trying to connect to the Docker daemon socket

Enter fullscreen mode Exit fullscreen mode

원인:

agent 계정이 /var/run/docker.sock 접근 권한 없음

Enter fullscreen mode Exit fullscreen mode

해결:

sudo docker compose ...

Enter fullscreen mode Exit fullscreen mode

Synology에서는 Docker socket 권한을 넓히는 것보다 sudo 또는 DSM Container Manager UI를 쓰는 편이 안전하다.


4. models auth login requires an interactive TTY

models auth login requires an interactive TTY

Enter fullscreen mode Exit fullscreen mode

원인:

interactive login 명령에 -T 옵션을 붙임

Enter fullscreen mode Exit fullscreen mode

해결:

sudo docker compose run --rm openclaw-cli models auth login-github-copilot

Enter fullscreen mode Exit fullscreen mode

상태 확인이나 JSON 출력에는 -T를 쓰고, 로그인류 명령에는 -T를 빼면 된다.


DSM Container Manager에서 관리하기

SSH에서 Compose를 실행해도 되지만, DSM UI에서는 Container Manager의 Project로 관리할 수 있다.

흐름:

  1. /volume1/docker/openclaw 폴더 생성
  2. Dockerfile, .env, docker-compose.yml 작성
  3. DSM Container Manager → Project → Create
  4. 경로를 /volume1/docker/openclaw로 지정
  5. compose 내용을 확인하고 생성

이렇게 하면 DSM UI에서도 컨테이너 상태, 로그, 재시작을 확인할 수 있다.


마무리

Synology NAS에 OpenClaw를 Docker Compose로 신규 설치하면 host 환경에 직접 의존하지 않고 안정적으로 gateway와 CLI를 운영할 수 있다.

이번 구성에서 가장 중요한 포인트는 다음 네 가지다.

  1. .openclaw는 host에 보존하고 컨테이너에는 /home/node/.openclaw로 mount한다.
  2. OpenClaw 컨테이너는 uid 1000node 사용자로 실행되므로 host 폴더 권한을 맞춘다.
  3. bridge 모드에서는 gateway bind를 lan으로 두고, host에는 127.0.0.1:18789만 노출한다.
  4. CLI 명령은 openclaw-cli 컨테이너로 실행하고, 비대화형 명령에는 -T를 붙인다.

이 구조를 잡아두면 OpenClaw gateway 실행, CLI 상태 확인, Telegram 채널 설정, 모델 인증, cron 테스트까지 모두 Docker Compose 안에서 일관되게 관리할 수 있다.