상세 컨텐츠

본문 제목

[n8n] Git을 활용한 워크플로우 자동 백업 시스템

카테고리 없음

by k-omad 2026. 3. 16. 20:00

본문

728x90
반응형

 여러 PC에서 n8n을 사용하다 보면 불편함을 직면하게 됩니다. 바로 워크플로우를 보관하고 이동하는 문제 입니다.

워크플로우를 수정할 때마다 일일이 파일로 내보내기를 하고, 이를 USB나 개인 클라우드 드라이브로 옮기는 일은 매우 번거롭습니다.

 

https://github.com/

 

GitHub · Change is constant. GitHub keeps you ahead.

Join the world's most widely adopted, AI-powered developer platform where millions of developers, businesses, and the largest open source community build software that advances humanity.

github.com

이러한 일을 안하기 위해 GitHub를 활용하기로 했습니다.

 

1단계: 환경 설정 및 보안

https://shok11.tistory.com/entry/Docker%EB%A5%BC-%ED%99%9C%EC%9A%A9%ED%95%9C-n8n-24%EC%8B%9C%EA%B0%84-%EC%9E%91%EB%8F%99

 

Docker를 활용한 n8n 24시간 작동

로컬에서 npx n8n 명령어로 n8n을 시작하셨던 분들이라면 공통적으로 겪는 고민이 있습니다. "터미널을 끄면 자동화도 멈춘다"는 점과, 워크플로우가 늘어날수록 관리가 힘들어진다는 것이죠.저

shok11.tistory.com

가장 먼저 n8n을 실행할 환경을 만들어야 합니다.

자세한 부분은 이전 포스팅을 참고 해주세요.

 

1. "docker-compose.yml"

services:
  n8n:
    image: n8nio/n8n:latest # 도커 허브의 공식 이미지 사용
    container_name: n8n-container
    restart: always # Mac Mini 등에서 24시간 가동을 위한 자동 재시작 설정
    ports:
      - "5678:5678" # 접속 통로(포트) 연결
    environment:
      - N8N_HOST=localhost
      - N8N_PORT=5678
      - N8N_PROTOCOL=http
      - NODE_ENV=production
      - WEBHOOK_URL=http://localhost:5678/ # 외부 접속 시 Mac의 IP나 도메인으로 변경 필요
      - TZ=Asia/Seoul # 시간대 설정 (스케줄러 정확도를 위해 필수)
    volumes:
      # 내 컴퓨터의 n8n_data 폴더에 워크플로우를 저장하라는 명령
      - ./n8n_data:/home/node/.n8n

이전과 같이 '.yml' 파일을 세팅합니다.

 

2. .env 파일

 n8n을 외부 서비스(GitHub,,등)와 연동하려면 반드시 인증 정보가 필요합니다. 우리는 아래 두 가지 정보를 사용합니다.

민감한 정보를 .yml에 직접 적어두면, 추후에 파일이 공유되거나 백업될 때 보안 정보가 그대로 노출되는 문제가 발생합니다. 이를 방지하기 위해 .env라는 별도의 파일을 생성하여 따로 저장합니다.

.yml 폴더에서는 "N8N_ENCRYPTION_KEY=${N8N_ENCRYPTION_KEY}"와 같은 호출 명령어를 사용 합니다.

 

1. GitHub PAT (Personal Access Token)

> GitHub 저장소에 접근하기 위한 비밀번호 입니다. (발급 방법은 아래에서 다룹니다.)

 

2. n8n Encryption Key

> '프로젝트 최상위 폴더' > 'n8n_data' > 'config' 파일 안에 "encryptionKey: 알수없는 엄청 큰 문자열" 형태로 존재하며, 'docker exec -it n8n-container' 명령어로 조회 가능합니다.

 

N8N_ENCRYPTION_KEY=알 수 없는 매우 긴 문자열

발급받은 토큰은 .env 폴더에 위와 같이 저장해 주세요.

 

3. .gitignore

 Git은 폴더 내에 있는 모든 파일의 변경 사항을 추적하고, 이를 GitHub로 전송하려는 성질을 가지고 있습니다. 조치를 취하지 않는다면, 분리해 둔 .env 파일과 시스템의 모든 정보가 담긴 폴더가 외부로 유출됩니다.

이를 통제하는 방법이 .gitignore 입니다. 이 파일 안에 업로드를 원치 않는 파일이나 폴더의 이름을 명시해두면 프로그램이 해당 폴더 및 파일을 추적하지 않습니다.

저는 아래와 같이 작성 하였습니다.

# 환경 변수 Environment Variables
# .*를 붙여 .env.local 같은 혹시 모르는 파생 파일을 차단합니다.
.env
.env.*

# n8n 내부 데이터 Data Folder
# n8n 시스템이 구동되면서 쌓이는 내부 데이터베이스 파일(sqlite)과 임시 파일을 차단합니다.
# Git은 빈폴더를 추적하지 않습니다. 도커가 연결할 폴더가 없어서 발생하는 에러를 막기 위해 .gitkeep은 !기호를 사용해 예외적으로 허용합니다.
n8n_data/
!n8n_data/.gitkeep # If you want to keep the folder structure but not content

# Docker & OS Files
# Mac 운영체제가 만드는 .DS_Store 파일과, Window 운영체제가 만드는 Thumbs.db파일을 차단합니다.
.DS_Store
Thumbs.db

# Any other unexpected log or temp files
# GitHub 내에서 쓸데없는 변경 이력을 차단합니다.
*.log
*.tmp

 

2단계: GitHub 저장소 준비

 업로드 준비를 맞췄으니, 백업 파일이 저장될 깃허브 저장소(클라우드)와 이에 접근할 수 있는 PAT 토큰 발급을 수행 해야 합니다.

 

1. GitHub Settings

- 저장소 만들기(Repository)

 깃허브에 로그인한 후 New repository를 클릭해 새로운 저장소를 만듭니다. 이때 내 워크플로우에 담긴 정보가 외부로 공유되는 것을 원치 않는다면, 비공개로 설정하여 생성해 주세요.

 

- 보안 토큰(PAT) 발급

 저장소를 생성한 후 화면 우측 상단의 내 프로필 아이콘을 클릭하고 "Settings > Developer settings > Personal access tokens > Tokens (classic)" 메뉴로 이동합니다.

"repo" 항목의 전체 권한을 추가합니다.

 

+ 이후 발급된 "ghp_"로 시작하는 토큰을 복사해서 ".env" 파일에 저장해 둡니다.

 

2. Docker의 구조적 한계

 이전 포스팅에서 Docker는 '독립된 가상의 실행 환경'임을 설명해 드렸습니다. 이는 보안과 안정성을 비약적으로 올려줍니다. 하지만 이러한 격리성 때문에 치명적인 문제가 발생합니다. n8n 시스템이 아무리 백업 파일을 잘 만들어내더라도, 그 파일은 컨테이너라는 가상 공간에 갇혀 있게 됩니다. 즉 PC 시스템은 그 파일의 존재를 인식할 수 없으며, Git 역시 백업할 파일이 없다고 판단하게 됩니다.

이러한 한계를 극복하기 위해 컨테이너 내부에 Git을 설치하려 했지만, apk: not found 패키지 관리자를 찾을 수 없다는  에러가 발생 했습니다. 이는 n8n의 공식 이미지인 "n8nio/n8n:latest"가 용량 최적화와 보안을 위해 패키지 설치 기능을 제거한 최소화 이미지이기 때문입니다.

시스템의 안정성을 해치면서 Git을 욱여넣는 대신, Docker는 파일만 내뱉게 하고 PC를 통해서 Git에 업로드 하는 방식을 선택 했습니다. 

 

3. Local - Git 연결

 먼저 GitHub와 내PC를 연결 하겠습니다. 프로젝트 폴더에서 아래 명령어를 순서대로 실행합니다.

# .git이라는 숨김 폴더를 생성합니다.
# 이 순간부터 해당 폴더는 Git의 데이터베이스로 사용됩니다.
git init

# GitHub 클라우드 서버와 통신 채널 연결
git remote add origin https://[GitHub ID]:[복사한 PAT 토큰]@github.com/[GitHub ID]/[Repository Name].git

# 원격 저장소의 주소가 시스템에 정확히 등록되었는지 출력하여 확인
git remote -v

 

4. Local - Docker(n8n) 연결

이제는 완벽하게 단절된 두 시스템(내PC - Docker) 사이에 실시간으로 데이터를 주고 받을 수 있는 통로를 뚫어주겠습니다.

 

Export 명령어

먼저 프로젝트 폴더 안에 backups 폴더를 생성 합니다.

 

이후에 docker-compose.yml 파일의 하단 volumes 섹션에 아래와 같은 코드를 추가해 줍니다.

volumes:
      - ./n8n_data:/home/node/.n8n
      - ./backups:/home/node/backups # <- 이 줄을 추가합니다.

docker-compose up -d 명령어를 실행해서 시스템에 적용 시키면, Git 프로그램이 폴더를 인식하고 변경 사항을 기록할 준비를 마칩니다.

 

n8n 내부에서 만든 워크플로우는 기본적으로 파일 형태가 아닌, 도커 내부의 데이터베이스인 SQLite에 코드 형태로 저장되어 있습니다.

이 데이터를 활용하기 위해서는 데이터를 .json 형태로 변환하는 과정이 선행되어야 합니다.

 

docker exec -it n8n-container n8n export:workflow --backup --output=/home/node/backups/

 

위 명령어를 수행하면, 내부 데이터베이스에 있는 모든 워크플로우를 n8n이 .json 포맷의 문서 파일로 변환하여, 방금 만든 backups 폴더에 내보냅니다.

 

이제 모든 사전 작업이 종료 되었습니다. GitHub에 업로드만 하면 됩니다.

 

3단계: Git 버전 관리 시스템과 클라우드 동기화

 여러 PC에서 작업을 하거나 다른 팀원과 협업할 때, 데이터가 꼬이거나 서로 덮어쓰는 충돌 현상을 예방하기 위해서는 아래의 원칙을 준수해야 합니다.

1. 작업 시작 전

- git pull origin master : 새로운 워크플로우가 있다면 내 컴퓨터에 덮어씁니다. (최신 동기화)



2. 작업 후

- docker exec -i n8n-container n8n export:workflow --backup --output=/home/node/backups/  : 최신 워크 플로우를 내 컴퓨터의 backups 폴더에 추출합니다.

- git add . : 변경 사항들을 전송 대기열에 올립니다.

- git status : 변경 내역을 확인합니다.

- git commit -m "오늘의 작업 내용" : 작업을 확정 짓고, 날짜와 작업 내용에 이름표를 붙여 기록합니다.

- git pull origin master : 내가 작업하는 동안 새로운 파일이 올라왔을지 모르니 미리 병합합니다.

- git push origin master : 동기화가 완벽히 끝난 내 컴퓨터의 데이터를 최종적으로 깃허브 서버에 올려 백업을 마칩니다.

 

 

4단계: 백업 자동화 스크립트

 업무가 종료되면, 일일이 Git 명령어를 타이핑하여 버전을 관리하는 일은 매우 번거롭습니다. 이를 해결하기 위해 파일 추적부터 깃허브 전송까지 한 번에 처리해 주는 자동화 스크립트를 작성 하겠습니다.

 

1. Git 클라우드 동기화 원리

스크립트를 작성하기 전, 우리가 컴퓨터에게 시킬 작업의 순서를 이해하면 좋습니다.

  1. [추출] docker exec... : 도커 안으로 들어가 최신 워크플로우를 내 PC(backups 폴더)로 추출.
  2. [감지] git status : 어제 백업한 내용과 비교하여 변경된 사항이 있는지 기계적으로 검사.
  3. [밀봉] git add & git commit : 변경된 파일들을 모아 현재 시간으로 선언.
  4. [병합] git pull : 다른 PC에서 올라온 파일이 있을 수 있으니 미리 병합.
  5. [전송] git push : 동기화가 완벽히 끝난 내 컴퓨터의 데이터를 깃허브 서버에 올려 최종 백업.

 

2. 자동화 스크립트 작성

# 설정
$N8N_CONTAINER_NAME = "n8n-container"
$BACKUP_DIR = "./backups"
$DATE = Get-Date -Format "yyyy-MM-dd HH:mm:ss"

Write-Host "[$DATE] Starting n8n workflow backup..." -ForegroundColor Cyan

# 1. n8n 컨테이너에서 워크플로우 추출 (덮어쓰기)
docker exec -i $N8N_CONTAINER_NAME n8n export:workflow --backup --output=/home/node/backups/

if ($LASTEXITCODE -eq 0) {
    Write-Host "✅ 워크플로우 추출 성공!" -ForegroundColor Green
} else {
    Write-Host "❌ 워크플로우 추출 실패!" -ForegroundColor Red
    exit 1
}

# 2. Git status 확인 (변경사항이 있는지)
$gitStatus = git status --porcelain $BACKUP_DIR

if ([string]::IsNullOrWhiteSpace($gitStatus)) {
    Write-Host "✅ 백업된 워크플로우에 변경사항이 없습니다. 커밋을 건너뜁니다." -ForegroundColor Yellow
    exit 0
}

# 3. Git 커밋 (로컬 변경사항 밀봉)
git add $BACKUP_DIR/*.json
git commit -m "Auto-backup n8n workflows: $DATE"

# 4. Git Pull (원격 저장소와 동기화)
Write-Host "🔄 원격 저장소(GitHub)의 최신 상태를 로컬로 병합(Pull)합니다..." -ForegroundColor Cyan
# --no-edit 옵션은 자동화 중 텍스트 편집기 창이 열려 시스템이 멈추는 것을 방지합니다.
git pull origin master --no-edit

# 5. Git Push (최종 클라우드 전송)
Write-Host "⬆️ 로컬의 백업 파일을 원격 저장소로 전송(Push)합니다..." -ForegroundColor Cyan
git push origin master

if ($LASTEXITCODE -eq 0) {
    Write-Host "✅ Git Push 성공!" -ForegroundColor Green
} else {
    Write-Host "❌ Git Push 실패" -ForegroundColor Red
}

Windows 환경: "backups.ps1"

 

#!/bin/bash

# 설정
N8N_CONTAINER_NAME="n8n-container"
BACKUP_DIR="./backups"
DATE=$(date +'%Y-%m-%d %H:%M:%S')

echo "[$DATE] Starting n8n workflow backup..."

# 1. n8n 컨테이너에서 워크플로우 추출 (덮어쓰기)
docker exec -i $N8N_CONTAINER_NAME n8n export:workflow --backup --output=/home/node/backups/

if [ $? -eq 0 ]; then
  echo "✅ 워크플로우 추출 성공!"
else
  echo "❌ 워크플로우 추출 실패!"
  exit 1
fi

# 2. Git status 확인 (변경사항이 있는지 검수)
git_status=$(git status --porcelain $BACKUP_DIR)

if [ -z "$git_status" ]; then
  echo "✅ 백업된 워크플로우에 변경사항이 없습니다. 커밋을 건너뜁니다."
  exit 0
fi

# 3. Git 커밋 (로컬 변경사항 밀봉)
git add $BACKUP_DIR/*.json
git commit -m "Auto-backup n8n workflows: $DATE"

# 4. Git Pull (원격 저장소와 동기화)
echo "🔄 원격 저장소(GitHub)의 최신 상태를 로컬로 병합(Pull)합니다..."
# --no-edit 옵션은 터미널 편집기(nano, vim 등)가 열려 스크립트가 멈추는 것을 방지합니다.
git pull origin master --no-edit

# 5. Git Push (최종 클라우드 전송)
echo "⬆️ 로컬의 백업 파일을 원격 저장소로 전송(Push)합니다..."
git push origin master

if [ $? -eq 0 ]; then
  echo "✅ Git Push 성공!"
else
  echo "❌ Git Push 실패"
fi

Mac 및 Linux 환경: "backups.sh"

 

3. 스크립트 실행

이제 모든 과정이 끝났습니다! 백업을 테스트 해보려면 아래 명령어를 실행하세요.

  • Windows 사용자: 터미널에 .\backup.ps1 입력
  • Mac/Linux 사용자: 터미널에 ./backup.sh 입력

단 한 줄의 명령어로 도커 진입 ➔ 파일 추출 ➔ 변경 감지 ➔ 클라우드 업로드까지 완벽하게 진행되는 것을 터미널 로그로 확인하실 수 있습니다.

 

[추가 팁 : 완전 무인 백업 시스템] 이 스크립트를 윈도우의 '작업 스케줄러'나 Mac/Linux의 '크론탭(Crontab)'에 등록해 두면, 매일 밤 12시 등 내가 지정한 시간에 컴퓨터가 스스로 백업을 수행할 수 있습니다.

728x90
반응형