미니 PC를 활용해서, 강력한 워크플로우 자동화 도구 'n8n 서버' 직접 구축하기 (단계별 안내)

소개

안녕하세요, GPTers 여러분! 단테입니다.

오늘은 미니PC를 활용해서 강력한 워크플로우 자동화 도구인 n8n 서버를 직접 구축하는 과정을 단계별로 공유해드리려고 합니다.

10만원 대 미니PC 한 대로, 월 수십만 원의 가치를 하는 나만의 자동화 서버(n8n)를 구축하는 모든 과정을 A to Z 로 정리해봤습니다.

서버 구축은 전문가만 하는 어려운 일이라고 생각해서 망설이고 계신다면, 이 가이드를 따라하시면 누구나 쉽게 나만의 서버를 구축할 수 있어요! 💪

가이드 활용법

본 가이드 문서만으로도 서버 설치 진행이 가능합니다.

아래의 유튜브 채널 영상을 함께 보시면 보다 이해가 쉽습니다.

(영상 바로가기) 유튜브 영상 링크


진행 방법

🎯 프로젝트 개요

목표: 미니PC에 Ubuntu 서버를 설치하고, Docker를 통해 n8n을 구축하여 어디서든 접속 가능한 자동화 서버 만들기

예상 시간: 2-3시간

필요한 것들: 미니PC, USB, 인터넷 연결, 약간의 인내심 😊

📋 1단계: 미니PC 선택 및 구매

추천 사양

CPU: Intel N100 이상 (또는 AMD 동급) RAM: 16GB 이상 권장 (8GB도 가능) Storage: SSD 256GB 이상 포트: USB 3.0, HDMI, 이더넷

구매 팁

  • 베어본PC도 좋지만, 완제품 미니PC가 초보자에게는 더 편리

  • Aliexpress 15-25만원대 제품들이 가성비 좋음

  • 브랜드: GMKtec, Beelink, ACEPC 등

📋 2단계: 서버 구축 핵심 개념 이해

서버 구축 프로세스

중국어와 중국어 단어가있는 흐름도

n8n 서버 네트워크 구조

의료 절차의 과정을 보여주는 흐름도

가이드에 나오는 주요 개념정리

1. 네트워크 개념

개념

한줄 설명

상세 설명

예시

Public IP (공인IP)

인터넷에서 사용하는 실제 주소

ISP에서 할당받은 전 세계 유일한 IP 주소. 외부에서 내 집 공유기를 찾을 때 사용

203.123.45.67

Private IP (사설IP)

집 내부에서만 사용하는 주소

공유기가 집 안 기기들에게 할당하는 로컬 주소. 외부에서 직접 접근 불가

192.168.1.100

DuckDNS

무료 도메인 서비스

숫자로 된 IP 주소를 기억하기 쉬운 도메인명으로 변환해주는 서비스

myserver.duckdns.org203.123.45.67

2. 핵심 서비스

서비스

한줄 설명

역할

왜 필요한가?

Ubuntu

리눅스 운영체제

서버용 무료 운영체제. Windows 대신 사용

안정적이고 보안이 좋으며 서버에 최적화됨

Caddy

웹서버 프로그램

외부 요청을 내부 서비스로 전달하는 리버스 프록시

하나의 서버로 여러 웹사이트를 운영할 수 있게 해줌

Docker

가상화 프로그램

프로그램을 컨테이너라는 박스에 담아서 실행

프로그램 설치/관리가 쉽고 충돌 방지

Node.js

자바스크립트 실행환경

브라우저가 아닌 서버에서 JavaScript를 실행

n8n과 많은 웹도구들이 Node.js로 만들어짐

3. 보안 도구

도구

한줄 설명

기능

사용 예시

UFW

우분투 방화벽

특정 포트만 열고 나머지는 차단하는 방화벽

sudo ufw allow 22 (SSH 포트 열기)

Fail2ban

공격 차단 도구

여러 번 로그인 실패하는 IP를 자동으로 차단

해커의 무차별 공격 방어

SSH

원격 접속 프로토콜

다른 컴퓨터에 안전하게 원격 접속하는 방법

노트북에서 미니PC에 터미널로 접속

4. 주요 명령어

명령어

용도

사용법

실제 예시

ssh

원격 접속

ssh 사용자명@IP주소

ssh [email protected]

ssh-keygen

SSH 키 생성

비밀번호 대신 키파일로 로그인하기 위한 키 생성

ssh-keygen -t rsa -b 2048

ssh-copy-id

키 복사

생성한 공개키를 서버에 복사

ssh-copy-id [email protected]

systemctl

서비스 관리

프로그램 시작/중지/상태확인

sudo systemctl start ssh

5. Docker Compose 명령어

명령어

용도

설명

실제 예시

docker compose up

스택 시작

docker-compose.yml에 정의된 모든 서비스 실행

docker compose up -d

docker compose down

스택 중지

실행 중인 모든 컨테이너 중지 및 제거

docker compose down

docker compose ps

상태 확인

현재 프로젝트의 컨테이너 상태 보기

docker compose ps

docker compose logs

로그 확인

모든 서비스의 로그를 실시간으로 보기

docker compose logs -f

docker compose restart

서비스 재시작

특정 서비스만 재시작

docker compose restart n8n

docker compose pull

이미지 업데이트

최신 이미지로 업데이트

docker compose pull

docker compose exec

컨테이너 내부 접속

실행 중인 컨테이너에 명령어 실행

docker compose exec postgres bash

6. systemctl 주요 사용법

명령어

기능

설명

systemctl start [서비스명]

서비스 시작

프로그램을 즉시 실행

systemctl stop [서비스명]

서비스 중지

실행 중인 프로그램을 종료

systemctl restart [서비스명]

서비스 재시작

프로그램을 껐다가 다시 켬

systemctl enable [서비스명]

자동 시작 설정

컴퓨터 부팅 시 자동으로 실행되도록 설정

systemctl status [서비스명]

상태 확인

프로그램이 정상 작동하는지 확인

7. 접속 포트

포트 번호

용도

설명

22

SSH

원격 터미널 접속용

80

HTTP

일반 웹사이트 접속용

443

HTTPS

보안 웹사이트 접속용 (SSL 인증서 적용)

5678

n8n

n8n 웹 인터페이스 접속용

8080

VS Code

VS Code 웹 에디터 접속용

📋 3단계: 윈도우 제품키 백업 (중요!)

미니PC가 윈도우와 함께 온다면 반드시 제품키를 백업하세요!

미니PC에 마우스, 키보드, 인터넷 랜선, 전원어댑터, 모니터HDMI 를 연결하고, 전원을 켜서 Windows 설정을 완료하세요.

그 다음 Powershell을 켜고 아래 명령어를 입력하여 키를 안전한 장소에 옮겨 적어주세요.

*# PowerShell을 관리자 권한으로 실행 후*
wmic path softwarelicensingservice get OA3xOriginalProductKey

이 키를 안전한 곳에 저장해두세요. 나중에 윈도우로 돌아가야 할 때 필요합니다.

📋 4단계: Ubuntu 서버 부팅 USB 준비

필요한 것

  • USB 8GB 이상

USB 만들기

  • Ubuntu Server Image 다운로드

  • USB 포맷 하기

    • Mac 유저는 ‘디스크유틸리티’ 이용하여 MSDOS FAT32로 포맷

    • Windows 유저는 ‘탐색기’에서 USB드라이브 선택후, 오른쪽 마우스 클릭 하여 팝업메뉴에서 ‘포맷’ 선택하여 FAT32로 빠른포맷 진행

  • USB 부팅디스크 만들기

    • https://etcher.balena.io/

    • ‘Flash from file’에서 Ubuntu Server ISO 이미지파일을 선택

    • ‘Select target’에서 USB 드라이드 선택

    • ‘Flash’ 버튼 클릭 하여 부팅디스크 생성

📋 5단계: Ubuntu 서버 설치

BIOS 설정

  1. 미니PC 부팅 시 F7 또는 Del 키로 BIOS 진입 (기본 부팅순서가 USB로 되어 있는 제품이면 자동 진입됨)

  2. Boot Order에서 USB를 첫 번째로 설정

  3. Secure Boot 비활성화

Ubuntu 설치 과정

  • 부팅 메뉴에서 가장 위의 ‘Try or Install Ubuntu’ 를 선택합니다.

    *# 설치 중 중요한 설정들*
    언어: English (한글 입력 문제 방지)
    키보드: Korean
    네트워크: 유선 연결 권장
    스토리지: 전체 디스크 사용
    사용자명: 영문으로 설정 (예: admin)
    OpenSSH Server: 반드시 설치 체크!
    
  • 네트워크 도구를 설치하고 공유기 프라이빗 네트워크의 접속 주소를 확인합니다.

    sudo apt install net-tools
    
    ifconfig 
    
    ip addr
    
  • (선택) 유선랜으로 접속하는 것을 권장하지만 와이파이 접속을 원하는 분은 아래 절차대로 진행

    sudo apt install network-manager
    
    nmcli dev wifi list
    
    nmcli dev wifi connect "SSID" password "YOUR_PASSWORD"
    
    ifconfig
    

📋 6단계: 공유기 네트워크 설정 및 포트포워딩

공유기 포트포워딩 설정

  • 대부분의 공유기에서 192.168.1.1 접속가능 (동영상은 192.168.219.1 로 접속함)

  • 미니PC Private IP 주소를 확인해야함 (예 : 192.168.1.100)

  • Private IP를 동적할당에서 고정할당으로 변경해야 함.

    보라색 배경과 한국어 텍스트가있는 페이지

  • 포트포워딩 규칙 추가

    한국 TV 가이드 - 스크린 샷
    - 서비스명: SSH
    - 외부포트: 22 (보안상 22 대신 2222 사용하는것이 더 좋음. 단 접속시 ssh 사용자명@IP주소 -p 2222 로 접속해야함)
    - 내부포트: 22
    - Private IP(내부 IP): 미니PC IP (예: 192.168.1.100)
    
    - 서비스명: HTTP
    - 외부포트: 80
    - 내부포트: 80
    - Private IP(내부 IP): 동일
    
    - 서비스명: HTTPS
    - 외부포트: 443
    - 내부포트: 443
    - Private IP(내부 IP): 동일
    

📋 7단계: SSH 접속 및 보안 설정

Ubuntu 설치 및 초기 업데이트

sudo apt update

sudo apt upgrade -y

SSH 설정과 UFW로 포트(22, 80, 443) 열기

# ssh터미널 서버 활성상태 확인
sudo systemctl status ssh

# ssh터미널 서버 활성화
sudo systemctl start ssh

# 방화벽 활성상태 확인
sudo ufw enable

# 방화벽 포트 열기 (ssh : 22, http: 80, https: 443)
sudo ufw allow ssh
sudo ufw allow http
sudo ufw allow https

# 방화벽 상태 확인
sudo ufw status

노트북에서 미니PC로 터미널 접속

  • 같은 공유기의 WIFI 네트워크로 개인노트북을 이용해 접속합니다.

  • Mac 유저는 ‘터미널’ 윈도우즈 유저는 ‘Powershell’ 창을 열어서 접속을 시도합니다.

    ssh [사용자명]@[프라이빗네트워크주소]
    
    ex) ssh [email protected]
    
    # 사용자명과 암호는 우분투OS 설치할때 정한 것입니다.
    # 명령어 입력후 암호 입력합니다.
    
  • (선택) 암호가 아닌 인증키 기반으로 ssh 접속을 하고 싶다면, ssh 인증키를 생성해서 설정해야합니다.

    # 공개키와 비밀키 쌍 생성
    ssh-keygen -t rsa -b 2048 -f ~/.ssh/id_minipc
    (엔터 2번)
    
    # 출력된 공개키 내용을 미니PC 서버에 저장
    ssh-copy-id -i ~/.ssh/id_minipc.pub [사용자명]@[프라이빗네트워크주소]
    (엔터, 압호입력)
    
    # 다시 서버 접속
    ssh -i ~/.ssh/id_minipc [사용자명]@[프라이빗네트워크주소
    

8단계: Node.js 및 바이브 코딩 Tool 설치

  • node.js 최신버전 설치

    sudo apt update
    
    sudo apt install curl ca-certificates gnupg -y
    
    curl -fsSL <https://deb.nodesource.com/setup_22.x> | sudo -E bash -
    
    sudo apt install nodejs
    
    node -v
    
    npm -v
    
  • gemini cli 와 claude code 설치

    # Claude Code CLI
    sudo npm install -g @anthropic-ai/claude-code
    
    # 또는 Gemini CLI
    sudo npm install -g @google/gemini-cli
    gemini auth login
    

9단계: DuckDNS 도메인 준비

  • Private IP 말고 Public IP를 확인합니다. (아래 명령어 또는 https://ifconfig.me/ 에서 확인)

    curl ifconfig.me 
    
  • (아래는 예시입니다. 여러분의 고유주소를 만드세요)

    # VScode 서버 도메인 : dantelabs-code.duckdns.org
    # n8n 서버 도메인 : dantelabs-n8n.duckdns.org
    
  • DuckDNS(https://www.duckdns.org/)에 가입하고, 2개의 도메인 준비를 합니다.

    Duck DNS- 오리 DNS 서버 설정 방법

10단계: VS Code 서버(code-server) 노출 via Caddy

  • code-server 설치 및 ~/.config/code-server/config.yaml 설정 (localhost 바인딩, 비밀번호 인증)

    curl -fsSL <https://code-server.dev/install.sh> | sh
    
    sudo systemctl enable --now code-server@[사용자명]
    ex) sudo systemctl enable --now code-server@dante
    
    sudo systemctl status code-server@dante
    
    cat > /home/dante/.config/code-server/config.yaml (엔터)
    ##################################
    bind-addr: 127.0.0.1:8080
    auth: password
    password: [YOUR_PASSWORD]
    cert: false
    ##################################
    (Ctrl + C)
    
    sudo systemctl restart code-server@dante
    
    sudo systemctl status code-server@dante
    
  • Caddy 설치

    sudo apt update
    sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https curl gnupg lsb-release
    
    curl -1sLf '<https://dl.cloudsmith.io/public/caddy/stable/gpg.key>' | sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg
    
    echo "deb [signed-by=/usr/share/keyrings/caddy-stable-archive-keyring.gpg] \\
    <https://dl.cloudsmith.io/public/caddy/stable/deb/ubuntu/> $(lsb_release -cs) main" | \\
    sudo tee /etc/apt/sources.list.d/caddy-stable.list
    
    sudo apt update
    sudo apt install -y caddy
    
  • caddy 서버 실행

    sudo systemctl enable --now caddy
    
    sudo systemctl status caddy
    
    caddy version
    
  • caddy 설정 파일 수정 : 여러분의 도메인 주소로 변경하셔야 합니다.

    sudo vi /etc/caddy/Caddyfile (엔터)
    
    dantelabs-code.duckdns.org {
      reverse_proxy localhost:8080
    }
    
    dantelabs-n8n.duckdns.org {
    	reverse_proxy localhost:5678
    }
    
    
  • Caddy 리로드 후 xxxxx-code.duckdns.org 에서 접속 테스트

    sudo systemctl restart caddy
    

    브라우저에서 xxxxx-code.duckdns.org 를 입력

    검은 배경이있는 컴퓨터 화면의 스크린 샷

10. VS Code 환경 준비

  • VS Code 접속 → 터미널 대신 사용

  • 폴더 및 파일 탐색 :홈 디렉토리를 [File → Open Folder] 에서 /home/[사용자명] 폴더를 엽니다.

    Mac OS X OS X OS X OS X OS X OS
  • 필수 확장프로그램 설치 : Docker, Python, Python-Debugger, YAML, ESLint, Prettier

    Adobe Slack 앱의 스크린 샷

🐳 11단계: Docker 설치

Docker 설치 스크립트

curl -fsSL <https://get.docker.com> | sh

sudo systemctl status docker

sudo usermod -aG docker $USER

newgrp docker

*# 설치 확인*
docker --version
docker-compose --version

📋 12단계: Docker Compose 기반 n8n Queue mode 스택 구축

컨테이너 정의 문서 작성

  • n8n 프로젝트 생성 : n8n 폴더를 만들고, File → Open Folder → n8n폴더 선택

  • .env 파일 작성 (도메인, DB, 암호화 키, 비밀번호 등)

    • 코드

      # --------------------------------
      # Postgres 설정
      # --------------------------------
      POSTGRES_DB=n8ndb
      POSTGRES_USER=n8nuser
      POSTGRES_PASSWORD=supersecurepassword
      
      # --------------------------------
      # n8n 시간대 설정
      # --------------------------------
      GENERIC_TIMEZONE=Asia/Seoul
      TZ=Asia/Seoul
      
      # --------------------------------
      # n8n 설정
      # --------------------------------
      # 자격증명 암호화 키(openssl rand -base64 48 명령어 이용)
      N8N_ENCRYPTION_KEY=verylongrandomstringkey
      
      # 프록시 뒤에서 외부 접근 도메인
      DOMAIN=yourdomain-n8n.duckdns.org
      
      
  • docker-compose.yml에 PostgreSQL, Redis, n8n 메인 및 워커 정의

    • 코드

      services:
        postgres:
          image: postgres:15-alpine
          environment:
            POSTGRES_DB: ${POSTGRES_DB}
            POSTGRES_USER: ${POSTGRES_USER}
            POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
          volumes:
            - pgdata:/var/lib/postgresql/data
          restart: unless-stopped
      
        redis:
          image: redis:7-alpine
          command: ["redis-server", "--save", "", "--appendonly", "no"]
          restart: unless-stopped
      
        n8n:
          image: docker.n8n.io/n8nio/n8n:latest
          depends_on:
            - postgres
            - redis
          environment:
            # DB(Postgres)
            DB_TYPE: postgresdb
            DB_POSTGRESDB_HOST: postgres
            DB_POSTGRESDB_PORT: 5432
            DB_POSTGRESDB_DATABASE: ${POSTGRES_DB}
            DB_POSTGRESDB_USER: ${POSTGRES_USER}
            DB_POSTGRESDB_PASSWORD: ${POSTGRES_PASSWORD}
            GENERIC_TIMEZONE: ${GENERIC_TIMEZONE}
            TZ: ${TZ}
      
            # 큐모드 + Redis
            EXECUTIONS_MODE: queue
            QUEUE_BULL_REDIS_HOST: redis
            QUEUE_BULL_REDIS_PORT: 6379
      
            # 보안/기본설정
            N8N_ENCRYPTION_KEY: ${N8N_ENCRYPTION_KEY}
            N8N_PORT: 5678
            # 프록시 뒤에서 올바른 웹훅 URL을 위해 WEBHOOK_URL 지정
            WEBHOOK_URL: <https://$>{DOMAIN}
      
            # Proxy 설정 (Caddy 뒤에서 실행)
            N8N_PROXY_HOST: "0.0.0.0::"
            N8N_PROTOCOL: https
            
            # Task runners 활성화
            N8N_RUNNERS_ENABLED: "true"
            
            # Manual executions을 workers로 오프로드
            OFFLOAD_MANUAL_EXECUTIONS_TO_WORKERS: "true"
            
            # 파일 권한 자동 적용
            N8N_ENFORCE_SETTINGS_FILE_PERMISSIONS: "true"
      
          ports:
            - "127.0.0.1:5678:5678"   # 로컬에서만 노출, Caddy가 외부 공개
          volumes:
            - n8n_data:/home/node/.n8n
          restart: unless-stopped
      
        worker:
          image: docker.n8n.io/n8nio/n8n:latest
          depends_on:
            - postgres
            - redis
          environment:
            DB_TYPE: postgresdb
            DB_POSTGRESDB_HOST: postgres
            DB_POSTGRESDB_PORT: 5432
            DB_POSTGRESDB_DATABASE: ${POSTGRES_DB}
            DB_POSTGRESDB_USER: ${POSTGRES_USER}
            DB_POSTGRESDB_PASSWORD: ${POSTGRES_PASSWORD}
            GENERIC_TIMEZONE: ${GENERIC_TIMEZONE}
            TZ: ${TZ}
      
            EXECUTIONS_MODE: queue
            QUEUE_BULL_REDIS_HOST: redis
            QUEUE_BULL_REDIS_PORT: 6379
      
            N8N_ENCRYPTION_KEY: ${N8N_ENCRYPTION_KEY}
            
            # Task runners 활성화
            N8N_RUNNERS_ENABLED: "true"
          command: ["worker"]
          restart: unless-stopped
      
      volumes:
        pgdata:
        n8n_data:
      

n8n 실행

  • 컨테이너 정상 실행 및 상태 확인

    docker compose up -d
    
    docker compose ps
    
    docker compose logs -f
    

📋 13단계: n8n 첫 접속 & 초기 설정

  • 브라우저 접속 → 관리자 계정 생성

  • 기본 워크플로우 / Webhook 노드 테스트 (HTTPS 기반 외부 콜)

📋 14단계: 업데이트 및 유지보수

자동 업데이트 및 백업 설정

  • n8n 프로젝트 폴더 내에 update-n8n.sh 파일 생성

    • 코드

      #!/usr/bin/env bash
      set -euo pipefail
      
      cd "$(dirname "$0")"
      
      COMPOSE_FILE="./docker-compose.yml"
      SERVICES=("n8n" "worker")                       # 함께 갱신할 서비스들
      IMAGE_FQN="docker.n8n.io/n8nio/n8n:latest"      # 필요 시 특정 버전으로 고정
      
      # 네임드 볼륨 백업 설정
      N8N_VOLUME="n8n_data"
      BACKUP_DIR="./backups"
      LOG_FILE="./n8n-autoupdate.log"
      
      # (선택) Postgres 백업
      PG_BACKUP="false"
      PG_SERVICE="postgres"
      PG_DB="${POSTGRES_DB:-n8n}"
      PG_USER="${POSTGRES_USER:-n8n}"
      PG_PW="${POSTGRES_PASSWORD:-password}"
      
      timestamp() { date +"%Y-%m-%d_%H-%M-%S"; }
      log() { echo "[$(timestamp)] $*" | tee -a "$LOG_FILE"; }
      
      # Docker 접근 권한 확인(미리 친절한 에러 제공)
      if ! docker info >/dev/null 2>&1; then
        echo "[오류] Docker 데몬에 접근할 수 없습니다. 사용자 계정을 docker 그룹에 추가하거나 sudo로 실행하세요."
        id
        groups
        exit 1
      fi
      
      mkdir -p "$BACKUP_DIR"
      touch "$LOG_FILE"
      
      log "=== n8n 자동 업데이트 시작 ==="
      
      # 현재 실행 중 n8n 컨테이너 이미지 ID(다이제스트 유사)
      RUNNING_ID=$(docker compose -f "$COMPOSE_FILE" ps -q "n8n" || true)
      RUNNING_DIGEST=""
      if [[ -n "${RUNNING_ID:-}" ]]; then
        RUNNING_DIGEST=$(docker inspect --format='{{.Image}}' "$RUNNING_ID" || true)
      fi
      
      # 최신 이미지 받기
      log "최신 이미지 가져오는 중: $IMAGE_FQN"
      if ! docker pull "$IMAGE_FQN" | tee -a "$LOG_FILE"; then
        log "[오류] 이미지 pull 실패"
        exit 1
      fi
      
      LATEST_DIGEST=$(docker image inspect "$IMAGE_FQN" --format='{{.Id}}' || true)
      
      # 최신 여부 판별
      if [[ -n "$RUNNING_DIGEST" && -n "$LATEST_DIGEST" && "$RUNNING_DIGEST" == "$LATEST_DIGEST" ]]; then
        log "이미 최신 버전입니다. 업데이트가 필요하지 않습니다."
        log "=== n8n 자동 업데이트 종료(변경 없음) ==="
        exit 0
      fi
      
      # 1) n8n 데이터 볼륨 백업(tar.gz)
      BK_NAME_VOL="n8n_data_$(timestamp).tgz"
      log "네임드 볼륨 백업 진행: '$N8N_VOLUME' -> $BACKUP_DIR/$BK_NAME_VOL"
      if ! docker run --rm -v "${N8N_VOLUME}":/src -v "$(pwd)":/dst alpine \\
        sh -c "cd /src && tar czf /dst/$BACKUP_DIR/$BK_NAME_VOL ."; then
        log "[경고] n8n 볼륨 백업 실패(업데이트는 계속 진행)"
      fi
      
      # 2) (선택) Postgres 덤프
      if [[ "$PG_BACKUP" == "true" ]]; then
        BK_NAME_PG="pg_dump_$(timestamp).sql.gz"
        log "Postgres 백업 진행: $BACKUP_DIR/$BK_NAME_PG"
        if ! PGPASSWORD="$PG_PW" docker compose -f "$COMPOSE_FILE" exec -T "$PG_SERVICE" \\
          sh -lc "pg_dump -U '$PG_USER' -d '$PG_DB' | gzip -c" > "$BACKUP_DIR/$BK_NAME_PG"; then
          log "[경고] Post
      
      
    • 실행가능한 스크립트로 권한 조정

      chmod a+x update-n8n.sh
      
    • crontab 에 스케줄링

      터미널에서 크론탭 편집기를 엽니다.

      crontab -e
      

      아래 줄을 추가합니다.

      0 0 * * * /home/dante/n8n/update-n8n.sh
      

      💡 이 설정의 의미

      • 분: 0

      • 시: 0 (자정)

      • 일: *

      • 월: *

      • 요일: *

        즉, 매일 00:00에 스크립트를 실행합니다.

보안 강화

  • 1차 보안 : SSH 키 인증 (위에 절차 설명)

  • 2차 보안 : UFW 기본 방화벽 (위에 설정 완료)

  • 3차 보안 : Fail2ban 운용 (공식메뉴얼 : https://github.com/fail2ban/fail2ban)

    • Fail2ban은 리눅스 서버에서 무차별 대입 공격(Brute Force Attack) 등 자동화된 로그인 시도를 방어하는 보안 솔루션입니다. 주로 SSH 또는 웹서비스 로그인 시도 등을 감지해 일정 횟수 이상 실패하면 해당 IP를 방화벽(iptables)으로 일정 시간 자동 차단합니다.

    • 코드

      # 설치
      sudo apt install fail2ban
      # 시작 및 활성화
      sudo systemctl start fail2ban
      sudo systemctl enable fail2ban
      # 상태 확인
      sudo systemctl status fail2ban
      # 보안설정
      sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
      
      # /etc/fail2ban/jail.local 파일을 VSCode에서 편집 (아래는 예시)
      ##########################################
      [DEFAULT]
      ignoreip = 127.0.0.1/8
      bantime = 30m         # 차단 시간
      findtime = 10m        # 검사 기간
      maxretry = 5          # 실패 허용 횟수
      
      [sshd]
      enabled = true
      port = 22             # SSH 포트(변경 시 수정)
      ##########################################
      
      # 재시작
      sudo systemctl restart fail2ban
      

🤔 문제해결 FAQ

Q: SSH 접속이 안 돼요!

A: 방화벽 설정과 포트번호를 다시 확인해보세요.

Q: n8n에 접속했는데 로그인 화면이 안 나와요!

A: Docker 로그를 확인해보시고, 환경변수 설정을 다시 점검해보세요.

Q: 외부에서 접속이 안 돼요!

A: 공유기 포트포워딩 설정과 방화벽 규칙을 확인해보세요.

결과와 배운 점

저는 개인적으로 서버구축시에는 nginx라는 서버를 사용했는데,

초보자분들께 맞추기위해 caddy라는 프록시 서버를 처음 사용했습니다.

설정이 무척 간편했고, 보편화하기 좋은 도구라는 생각이 들었습니다.

도움 받은 글

  1. n8n 공식 문서와 Docs Chat 기능을 활용했습니다.

https://docs.n8n.io/

마무리

이제 여러분만의 n8n 자동화 서버가 완성되었습니다.

혹시 구축 과정에서 막히는 부분이 있으시면 댓글로 남겨주세요.

GPTers 커뮤니티에서 함께 해결해나가요! 💪

4

뉴스레터 무료 구독

👉 이 게시글도 읽어보세요