NGINX Socket Reverse Proxy 구성
현대의 웹 애플리케이션은 단순한 요청-응답 패턴을 넘어, 실시간 데이터 통신을 요구하는 다양한 기능들을 필요로 합니다. 대표적으로 채팅 서비스, 실시간 알림, 스트리밍 등이 그 예입니다. 이러한 실시간 통신을 가능하게 하는 기술 중 하나가 Socket입니다. 본 문서에서는 Socket의 개념부터 시작하여, Python으로 구현한 TCP 및 Unix Domain Socket 서버, WebSocket 서버를 구성하고 이를 NGINX를 통해 Reverse Proxy하는 방법을 단계별로 설명합니다. 특히 NGINX를 활용한 Socket Proxy 구성은 고성능 애플리케이션 구조 설계에 매우 유용한 방식으로, 본 문서를 통해 Socket Proxy를 사용 할 수 있습니다.
목차
1. Socket이란?
2. 환경구성
3. TCP Socket Server 구현
4. NGINX Socket Reverse Proxy
5. Web Socket Server 구현
6. NGINX WebSocket Reverse Proxy
7. 결론
1. Socket이란?
Socket(소켓)은 클라이언트 및 서버에 상호작용에 사용되는 통로 역할을 합니다. 클라이언트와 서버가 특정한 포트를 통해 실시간으로 통신하여 데이터를 전달합니다.
TCP 소켓 : IP랑 포트로 통신하는 기본 네트워크 소켓 (인터넷용).
유닉스 도메인 소켓 (UDS) : 같은 서버 안에서 파일 경로로 통신하는 소켓 (빠르고 로컬 전용).
웹소켓 : HTTP 연결을 실시간 양방향 통신으로 바꾸는 프로토콜 (채팅, 실시간 방송등에 사용됨).
HTTP와 다른점 : HTTP는 요청-응답 기반의 단방향 통신을 지원하고있고 Socket은 연결을 유지하여 양방향 실시간 통신을 지원합니다. HTTP는 정적/동적 웹페이지, API로 사용하는 반면 Socket은 채팅, 실시간 알림, 스트리밍 등 실시간 통신에 사용됩니다.
2. 환경구성
- Ubuntu 22.04
- NGINX Plus R34 (OSS 도 Socket Reverse Proxy를 지원합니다.) / 1.27.4
- Python 3.10.12 (Socket Server)
- wscat 5.1.0
- netcat 1.218-4ubuntu1
3. Socket Server 구현
Python Socket 라이브러리를 이용하여 Socket 통신을 구현합니다.
각각 unix Socket 파일, TCP Socket 통신으로 구현합니다.
두 소켓 모두 Client가 보낸 메세지를 서버에서 그대로 응답하는 코드입니다.
# unix Domain 소켓 파일 Python 코드
# socket_file.py
import socket
import os
SOCKET_PATH = '/tmp/mysocket.sock' # 소켓 파일 경로
# 기존 소켓 파일이 있으면 삭제
if os.path.exists(SOCKET_PATH):
os.remove(SOCKET_PATH)
# 소켓 생성
with socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) as server_socket:
server_socket.bind(SOCKET_PATH) # 파일로 소켓을 바인딩
server_socket.listen()
print(f"서버가 {SOCKET_PATH}에서 대기 중...")
while True:
conn, _ = server_socket.accept()
with conn:
print(f"클라이언트 연결됨")
while True:
data = conn.recv(1024)
if not data:
break
print(f"받은 메시지: {data.decode()}")
response = "서버 응답: " + data.decode()
conn.sendall(response.encode())
# 3000번 포트 소켓 서버
# socket_tcp.py
import socket
HOST = '0.0.0.0'
PORT = 3000
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as server_socket:
server_socket.bind((HOST, PORT))
server_socket.listen()
print(f"서버가 {HOST}:{PORT}에서 대기 중...")
while True:
conn, addr = server_socket.accept()
with conn:
print(f"{addr} 클라이언트 연결됨")
while True:
data = conn.recv(1024)
if not data:
break
print(f"받은 메시지: {data.decode()}")
response = "서버 응답: " + data.decode()
conn.sendall(response.encode())
위의 서버를 구동합니다.
python3 socket_file.py
python3 socket_tcp.py
net cat을 통하여 TCP Socket 연결하여 결과를 확인합니다.


4. NGINX TCP Socket Reverse Proxy
NGINX에서 Socket Reverse Proxy를 진행합니다.
각각 unix socket와 TCP socket을 프록시합니다.
NGINX를 구성하기 전 Unix Domain Socket 파일에 접근 할 수 있도록 Socket 파일을 권한을 변경합니다.
chown 766 /tmp/mysocket.sock
NGINX에서 Stream 블럭을 이용하여 TCP Reverse Proxy를 구성합니다.
# /etc/nginx/conf.d/socket.conf
stream {
upstream tcp_backend {
server 127.0.0.1:3000;
}
server {
listen 9000;
proxy_pass tcp_backend;
}
upstream uds_backend {
server unix:/tmp/mysocket.sock; # unix domain socket을 사용하기 때문에 unix domain socket 프로토콜을 사용합니다.
}
server {
listen 9001;
proxy_pass uds_backend;
}
}
위와 같이 구성을 변경한 후 NGINX에 구성을 적용합니다.
net cat을 이용하여 소켓과 통신합니다.
nc [NGINX IP] [NGINX Proxy Port]


프록시 되는 것을 확인할 수 있습니다.
5. Web Socket Server 구현
Python의 websockets 라이브러리를 사용하여 WebSocket Server를 생성합니다.
클라이언트의 답변을 서버에서 그대로 반환해주는 WebSocket 코드입니다.
# websocket.py
import asyncio
import websockets
async def echo(websocket, path=None):
async for message in websocket:
print(f"클라이언트 메시지: {message}")
await websocket.send(f"서버 응답: {message}")
async def main():
# 서버 실행
server = await websockets.serve(echo, "0.0.0.0", 8765)
print("WebSocket 서버가 8765 포트에서 대기 중입니다...")
await asyncio.Future()
if __name__ == "__main__":
asyncio.run(main())
서버를 구동하고 wscat을 통하여 WebSocket Server에 요청을 보냅니다.

WebSocket과 통신 되는 것을 확인할 수 있습니다.
6. NGINX WebSocket Reverse Proxy
NGINX에서 http를 이용하여 WebSocket Rever Proxy를 사용할 수 있습니다.
WebSocket은 TCP Socket과 달리 HTTP, HTTPS에서 작동하도록 설계되어 있기 때문에 L7 Proxy를 사용합니다.
upstream websocket_backend {
server 127.0.0.1:8765;
}
server {
listen 81;
location /ws/ {
# WebSocket을 지원하는 업그레이드 요청 헤더 설정
# WebSocket은 HTTP/1.1을 필요로 하므로 버전을 1.1로 설정합니다.
proxy_http_version 1.1;
# 클라이언트의 Upgrade 헤더를 백엔드 서버로 전달합니다.
proxy_set_header Upgrade $http_upgrade;
# 연결을 WebSocket으로 업그레이드하도록 명시합니다.
proxy_set_header Connection 'upgrade';
# 원래 요청한 Host 값을 유지하여 백엔드 서버로 전달합니다.
proxy_set_header Host $host;
# WebSocket 연결 시 프록시 캐시를 사용하지 않도록 설정합니다.
proxy_cache_bypass $http_upgrade;
# WebSocket 백엔드로 연결
proxy_pass http://websocket_backend;
}
}
위와 같이 구성 후 wscat을 통해 메세지을 보내게 되면 WebSocket을 NGINX Revserse Proxy를 통해 서버에서 응답하는 것을 확인할 수 있습니다.
wscat -c ws://[NGINX IP]:[NGINX WebSocket Proxy Port]/[WebSocket Endpoint]

7. 결론
Socket은 HTTP와 달리 지속적인 연결을 유지하며 실시간 양방향 통신이 가능하다는 점에서 실시간 서비스를 구현하는 데 매우 효과적인 기술입니다. 본 문서에서는 Python을 활용하여 TCP 및 Unix Domain Socket 서버, WebSocket 서버를 구현하고, 이를 NGINX를 통해 Reverse Proxy로 연결하는 전반적인 과정을 다루었습니다. 특히 NGINX의 stream 블럭을 이용한 L4 프록시와, WebSocket을 위한 L7 프록시 설정을 통해 다양한 유형의 소켓 기반 통신을 유연하게 구성할 수 있는 방법을 살펴보았습니다. 이를 기반으로 안정적이고 확장 가능한 실시간 통신 서비스를 구축하는 데 도움이 되기를 바랍니다.
NGINX에 관련된 더 많은 정보를 알고싶으시다면 NGINX STORE NGINX 카테고리를 방문해주세요.
댓글을 달려면 로그인해야 합니다.