n8n을 API 서버처럼 쓰기 - Docker Compose로 Webhook API 만들기
n8n을 처음 접하면 보통 "Zapier 같은 거"라고 생각한다. 틀린 말은 아닌데, 그게 다가 아니다.
n8n은 이벤트 처리 런타임���자 경량 API 컴포저���. 코드 없이 Webhook을 열고, 외부 API를 호출하고, 응답을 가공해서 돌려줄 수 있다. 직접 해보면 감이 온다.
이 글에서 만드는 것
Docker Compose로 로컬에 n8n을 띄우고, 아래 워크플로우를 만든다:
클라이언트
↓ (Basic Auth + JSON 요청)
Webhook 노드
↓
HTTP Request (httpbin.org로 전달)
↓
Edit Fields (응답 가공)
↓
Respond to Webhook (클라이언트에게 응답)
최종 결과: curl로 호출하면 응답이 오는 API
1. Docker Compose로 n8n 실행하기
n8n은 Docker 이미지로 제공된다. 별도 DB 없이 SQLite만으로도 충분히 돌아간다.
docker-compose.yml
services:
n8n:
image: n8nio/n8n:latest
ports:
- "5678:5678"
environment:
TZ: Asia/Seoul
N8N_HOST: localhost
N8N_PORT: 5678
N8N_PROTOCOL: http
WEBHOOK_URL: http://localhost:5678
N8N_ENCRYPTION_KEY: your-secret-key
volumes:
- ./n8n_data:/home/node/.n8n왜 Postgres 없이 SQLite로?
- 로컬 테스트용이라면 SQLite로 충분
- 워크플로우 데이터가
n8n_data볼륨에 저장됨 - 나중에 프로덕션으로 옮길 때 DB 교체하면 됨
실행
docker compose up -dhttp://localhost:5678 접속하면 n8n 대시보드가 뜬다.

계정 생성하고 로그인하면 이런 대시보드가 보인다. 여기서 워크플로우를 만들고 관리한다.
2. 완성된 워크플로우 미리보기
이번에 만들 워크플로우는 이렇게 생겼다:

노드 4개짜리 간단한 구조:
- Webhook - 외부 요청을 받는 진입점
- HTTP Request - 받은 데이터를 httpbin.org로 전달
- Edit Fields (Set) - 응답을 가공
- Respond to Webhook - 클라이언트에게 응답 반환
하나씩 설정해보자.
3. Webhook 노드 설정
Webhook 노드는 트리거이면서 동시에 API 엔드포인트���. 이게 n8n이 "자동화 도구"를 넘어서는 지점이다.

주요 설정
| 항목 | 값 | 설명 |
|---|---|---|
| HTTP Method | POST | 데이터를 받을 거니까 POST |
| Path | webhook | 엔드포인트 경로 |
| Authentication | Basic Auth | 간단한 인증 |
| Respond | Using 'Respond to Webhook' Node | 가공 후 응답 |
Respond 설정이 중요하다.
Immediately: Webhook이 받자마자 바로 응답Using 'Respond to Webhook' Node: 뒤에서 가공한 후 응답
우리는 httpbin 응답을 가공해서 돌려줄 거니까 후자를 선택한다.
4. Basic Auth 인증 테스트
인증을 노드 단위로 건다는 게 포인트다. 별도 인증 서버 없이 Webhook 자체에 Basic Auth를 걸 수 있다.

- 왼쪽: 인증 없이 호출 →
401 Unauthorized - 오른쪽:
-u test:test로 인증 후 호출 → 정상 응답
# 인증 없이 (실패)
curl -X POST http://localhost:5678/webhook-test/webhook
# 인증 있이 (성공)
curl -X POST http://localhost:5678/webhook-test/webhook \
-u test:test \
-H "Content-Type: application/json" \
-d '{"event": "test"}'5. HTTP Request 노드 - 외부 API 호출
Webhook으로 받은 body를 그대로 외부 API에 전달한다. 테스트용으로 httpbin.org를 쓴다.

핵심 설정
| 항목 | 값 |
|---|---|
| Method | POST |
| URL | https://httpbin.org/post |
| Body Content Type | JSON |
| Body | ={{ $json.body }} |
={{ $json.body }}가 핵심이다.
이 표현식이 "이전 노드의 JSON에서 body 필드를 가져와라"는 의미다. n8n에서 노드 간 데이터 전달은 이런 식으로 한다.
n8n 표현식 문법: ={{ }} vs {{ }}
헷갈리기 쉬운 부분이라 정리해둔다.
| 문법 | 용도 | 예시 |
|---|---|---|
={{ expression }} | 필드 값 전체��� 표현식일 때 | ={{ $json.body }} |
{{ expression }} | 문자열 안에 표현식을 삽입할 때 | Hello, {{ $json.name }}! |
예시:
// 필드 값 전체가 동적일 때
Body: ={{ $json.body }}
// 문자열 중간에 값 삽입
Message: "User {{ $json.userId }} logged in at {{ $json.timestamp }}"
// URL에 파라미터 삽입
URL: https://api.example.com/users/{{ $json.id }}= 기호가 있으면 "이 필드는 표현식이다"라고 n8n에 알려주는 거다. 없으면 문자열 템플릿으로 처리된다.
스크린샷을 보면 Webhook에서 받은 데이터가 HTTP Request 노드로 잘 전달된 걸 확인할 수 있다.
6. Edit Fields (Set) 노드 - 응답 가공
HTTP Request의 응답을 그대로 돌려줘도 되지만, 보통은 가공이 필요하다.

설정 예시
| 필드 | 값 | 설명 |
|---|---|---|
tracked | true | 고정값 |
echo | ={{ $json.json }} | httpbin이 돌려준 JSON |
응답 스키마를 명시적으로 정의하는 거다. 클라이언트가 받을 JSON 구조:
{
"tracked": true,
"echo": { ... }
}7. Respond to Webhook 노드
마지막 노드다. Edit Fields에서 가공한 데이터를 클라이언트에게 응답으로 보낸다.

설정
| 항목 | 값 |
|---|---|
| Respond With | All Incoming Items |
별거 없다. 이전 노드에서 만든 데이터를 그대로 응답으로 보내면 된다.
주의할 점: 이 노드는 "Execute Step" 버튼으로 테스트가 안 된다. Webhook이 실제 HTTP 요청을 받아야 전체 플로우가 실행되기 때문이다.
8. 전체 워크플로우 테스트
모든 노드 설정이 끝나면 워크플로우를 실행해보자.

각 노드에 초록색 체크가 뜨면 성공이다. 왼쪽에서 오른쪽으로 데이터가 흘러가는 걸 확인할 수 있다:
- Webhook이 요청을 받음
- HTTP Request가 httpbin에 전달
- Edit Fields가 응답을 가공
- Respond to Webhook이 클라이언트에게 반환
9. curl로 최종 테스트
실제로 curl로 호출해서 응답을 확인해보자.

curl -X POST http://localhost:5678/webhook-test/webhook \
-u test:test \
-H "Content-Type: application/json" \
-d '{"userId": "user123", "event": "page_view"}'응답:
{
"tracked": true,
"echo": {
"userId": "user123",
"event": "page_view"
}
}끝. n8n으로 API 하나를 만들었다.
프로덕션 URL
테스트가 끝나면 워크플로우를 Active 상태로 바꾼다. 그러면 URL이 바뀐다:
테스트: http://localhost:5678/webhook-test/webhook
운영: http://localhost:5678/webhook/webhook
webhook-test → webhook
정리
n8n을 "워크플로우 자동화 도구"로만 보면 절반만 보는 거다.
n8n의 또 다른 얼굴:
- Webhook으로 API 엔드포인트를 열 수 있다
- 노드 단위로 인증을 걸 수 있다
- 코드 없이 외부 API를 호출하고 응답을 가공할 수 있다
- Docker로 셀프호스팅하면 데이터가 외부로 나가지 않는다
복잡한 API 서버를 만들 건 아니다. 근데 "이벤트 받아서 어딘가로 전달하고 응답 가공해서 돌려주는" 정도의 라우터가 필요하다면, n8n이 생각보다 좋은 선택이다.
Comments
잘못된 부분이 있을 수 있습니다 ! 자유롭게 댓글을 달아주세요 :)