리버스 프록시를 추가하기 전까지 내 홈랩은 망가진 것 같았다
내 홈랩은 고장 나지 않았다. 컨테이너는 잘 실행되고 있었고, 서비스에도 접속할 수 있었으며, 내 하루를 방해하는 일도 없었다. 순수하게 기술적인 관점에서 보면 모든 것이 정확히 의도한 대로 작동하고 있었다. 하지만 사용하면서 느껴지는 것은, 시스템이 나를 위해 협력하기보다는 나를 참아주는 것 같았다. 모든 상호작용에는 충분히 귀찮을 정도의 마찰이 있었지만, 이를 고치기에는 충분하지 않은 정도였다. 그래서 나는 고치지 않았다. 나는 돌아가며 사용했으며, 기억할 필요 없는 것들을 외워야 했고, 이것이 단순히 홈랩을 운영하는 과정의 일부임을 조용히 받아들였다.
문제는 '작동한다'가 꽤 낮은 기준이라는 것입니다. 제가 리버스 프록시를 추가하고 나서야 그 마찰의 얼마나 많은 부분을 당연하게 받아들였는지 깨달았습니다. 겉보기에는 아무 것도 크게 바뀌지 않았습니다. 같은 서비스, 같은 기계, 같은 설정이 그대로였습니다. 하지만 갑자기 모든 것이 함께 있는 듯한 느낌이 들었습니다.
모든 것이 작동했지만 지저분하게 느껴졌다
모든 서비스가 다른 포트 뒤에 있었고, 아무것도 연결되어 있는 것 같지 않았다
우분투 머신에서의 내 도커 설정은 단순하게 시작되었다. 하나의 컨테이너, 그 다음 다른 하나, 그리고 몇 개 더. 그 부분은 항상 무해하게 느껴진다.
그러자 포트들이 쌓이기 시작했다. 한 서비스는 3000번, 다른 서비스는 8080번, 또 다른 것은 9000번에 있었는데, 아무도 깊게 고민하고 싶어하지 않을 때 물건들이 가는 곳이 바로 그곳인 모양이었다. 나는 내 설정에 접근하는 방법을 기억하기 위해 북마크를 만들어 두었다. 하나를 잊어버리면, 그냥 추측했다. 추측이 틀리면, 여러 탭을 열고 그중 하나가 어디쯤 쓸모 있는 곳에 도착하기를 바랐다.
그것은 또한 모든 것을 일시적으로 느끼게 만들었다. 아무것도 제대로 된 자리를 갖고 있지 않았다. 그것은 내가 기억해야 하는 끝점들의 목록일 뿐이었다. 아무것도 고장 난 것은 없었다. 단지 내가 스스로 정리되기를 거부하는 시스템을 끊임없이 보완하고 있는 듯한 느낌이 들었다.
나는 마찰에 익숙해졌다
모든 것이 기술적으로 작동할 때, 그것이 얼마나 짜증나는지 의문을 갖는 것을 멈추게 된다
이 부분이 정말로 당신을 몰래 덮치는데, 아무 것도 충돌하지 않기 때문에 모든 것이 괜찮다고 가정하게 됩니다. 그래서 계속해서 서비스를 추가하게 됩니다. 더 많은 컨테이너, 더 많은 포트, 나중에 정리하겠다고 자신에게 약속하는 작은 우회 방법들입니다. 원격 접속은 ‘필요하다면 작동시킬 수 있다’라는 모호한 범주에 속해 있었습니다. HTTPS는 표준이라기보다는 제안에 가까웠습니다.
누군가와 무언가를 공유하는 것은 퍼즐을 설명하는 것처럼 느껴졌다. ‘이 IP로 가서, 이 포트를 추가하고, 경고는 무시해; 괜찮아.’ 실제로 괜찮더라도 설득력 있어 보이지 않는다. 진짜 문제는 기술적인 것이 아니었다. 행동적인 것이었다. 나는 내 홈랩을 피하기 시작했는데, 그것과 상호작용하는 것이 노력이 되는 것처럼 느껴졌기 때문이다; 이런 일은 절대 일어나서는 안 된다.
수리는 예상보다 간단했다
리버스 프록시는 모든 것이 단일하고 예측 가능한 방식으로 접근될 수 있도록 해줍니다
리버스 프록시는 마치 네트워킹 교과서에 나올 법한 것처럼 들린다. 실제로는 단순히 트래픽 라우터일 뿐이다. 포트와 IP 조합을 기억하는 대신, 각 서비스에 적절한 주소를 부여한다. 인간에게 의미 있는 무언가를 말이다. 그래서 IP와 포트 번호를 입력하는 대신, 이름과 같은 것을 입력한다. 프록시는 그 요청을 받아서 배후의 올바른 컨테이너로 보낸다.
또한 HTTPS, 라우팅, 접근 규칙을 처리하는 유일한 장소가 됩니다. 각 서비스마다 같은 문제를 반복해서 해결하는 것을 멈추고, 한 번만 해결하면 됩니다. 나머지 모든 것이 그 혜택을 받습니다.
내가 처음에 눈치챈 것은 내가 생각해야 할 것이 거의 없다는 것이었다. 모든 서비스에는 정확한 주소가 있었다. 숫자가 아니고, 추측이 아니며, 여전히 맞기를 바라는 즐겨찾기 또한 아니었다. 그냥 실제 기능과 일치하는 이름일 뿐이었다. 두 번째 변화는 일관성이었다. 모든 것에 접근하는 방식이 동일했다. 예외는 없었다. 아니, ‘역사적인 이유로 이건 다르게 작동한다’는 일도 없었다. 그다음은 HTTPS였다. 경고도, 망설임도, 정말로 이렇게 로그인해야 하는지 잠시 고민하는 순간도 없었다.
원격 액세스도 더 이상 해킹처럼 느껴지지 않았다. 모든 것이 단일 진입점을 통해 흐를 때, 이를 적절히 노출하는 것은 스스로 의심하지 않고 실제로 관리할 수 있는 일이 된다. 작은 것들조차도 개선되었다. 서비스를 여는 것이 더 빨라진 것 같았다. 더 이상 서비스를 어떻게 접속할지를 기억하기 위해 멈추지 않았기 때문이다. 새로운 서비스를 추가하는 것도 나중에 처리할 일이 아니라 자연스러운 일이 되었다. 이러한 변화들 자체가 극적이진 않았지만, 함께하면 내가 무시하고 있던 거의 모든 불편을 제거했다.
나는 그것을 nginx로 설정했다
간단한 Docker nginx 리버스 프록시만으로 전체 홈랩을 정리하기에 충분합니다
여기가 보통 상황이 실제보다 더 어려워 보이는 곳입니다. 저는 Docker에서 실행되는 Nginx를 선택했습니다. 고급 대시보드는 없고, 단지 깔끔하고 예측 가능한 설정만 있습니다. 아래 코드에서 "myapp"은 포함하려는 앱의 자리 표시자 이름이라는 점을 주목하세요.
먼저, Docker 네트워크를 생성하세요. 이렇게 하면 nginx가 컨테이너 이름으로 통신할 수 있습니다.
docker network create proxy컨테이너를 실행할 때 이 네트워크에 연결하십시오:
docker run -d \
--name myapp \
--network proxy \
-p 3000:3000 \
myapp-image이제 Nginx를 실행할 시간입니다:
docker run -d \
--name nginx-proxy \
--network proxy \
-p 80:80 \
-v $(pwd)/nginx.conf:/etc/nginx/nginx.conf:ro \
nginxNginx를 올린 후에는 이를 구성할 시간입니다. 다음은 트래픽을 컨테이너로 라우팅하는 최소한의 예제입니다:
events {}
http {
server {
listen 80;
server_name myapp.local;
location / {
proxy_pass http://myapp:3000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
}
이제 http://192.168.x.x:3000 대신 http://myapp.local에서 서비스를 이용할 수 있습니다. 이제 남은 것은 다른 서비스에 대해서도 이 과정을 반복하는 것입니다. 각 서비스는 고유한 server_name과 proxy_pass를 갖게 됩니다.
그게 전부입니다. 마법도 없고, 신비함도 없습니다. 나중에 HTTPS를 원한다면, 동반 컨테이너를 사용하여 Let’s Encrypt를 추가할 수 있습니다. 하지만 이 기본 설정만으로도 대부분의 문제는 이미 해결됩니다.
차이는 기술적인 문제가 아니라, 전체 설정이 하나로서 어떻게 작동하는가에 관한 것이었다
이 부분이 저를 놀라게 한 부분입니다. 리버스 프록시를 추가해도 제 홈랩이 더 빨라지지 않았습니다. 기능이 추가되지 않았습니다. 제 설정이 할 수 있는 것을 바꾸지도 않았습니다. 단지 사용 느낌이 바뀌었습니다. 새 컨테이너를 띄우는 것이 더 이상 두 번째 문제를 해결해야 하는 일이 되지 않았습니다. 어떻게 접근될지 이미 알고 있습니다. 다른 모든 것과 같은 구조에 맞습니다.
나는 기억, 즐겨찾기, 작은 임시방편에 의존하는 것을 멈췄다. 나는 내 설정과 타협하는 것을 멈췄다. 그것은 단지 완전하다고 느껴지는 방식으로 작동한다. 그리고 한 번 익숙해지면, 포트와 추측으로 돌아가는 것이 약간 부끄럽게 느껴진다.







