1. 왜 원격 개발 환경을 만들었나
현재 본가(일산)에서 대학까지의 통학시간은 왕복 4시간 정도 되는데, 어쩔 수 없이 지하철에서 랩탑으로 공부하는 시간이 많습니다. 하지만 저장공간, 컴퓨팅 성능, 배터리 등 외부 변인에 아쉬움이 있을 수 밖에 없고, 집에 있는 데스크탑의 GPU자원을 활용하고 싶었습니다. 때마침 연구실에 들어가서 NAS와 Remote SSH로 서버 컴퓨터를 사용하는 방법을 공부할 기회가 생겼고, 이를 개인에 맞춰 구성해볼 수 있었습니다.

2. 최종 구성 요약
데스크탑의 Windows는 호스트 역할만 담당하고, 실제 개발환경은 WSL2 Ubuntu에 구성했습니다. 외부에서 접속할 때 공유기 포트포워딩이나 SSH 포트의 직접 노출을 피하기 위해 Tailscale로 랩탑과 WSL 사이에 사설 네트워크를 구성하고, 그 위에서 OpenSSH를 통해 WSL에 직접 접속하도록 했습니다. 장기 실행 작업은 SSH 연결이 끊겨도 유지되도록 tmux로 관리합니다.

3. 원격 전원 제어: WOL에서 SmartThings 스마트 스위치로
처음에는 Wake-on-LAN으로 데스크탑 전원을 켜려고 했습니다. 내부 네트워크에서는 별 문제가 없었지만, 외부에서 사용하려니 공유기 관리 페이지를 거쳐야 했고 세션 타임아웃이나 접근 문제 때문에 하염없이 기다리거나, 실패하는 일이 부지기수였어서, 안정적인 원격 전원 제어 수단으로 쓰기에는 불편했습니다.

결국 블로그 글이나 커뮤니티를 통해서 서치해본 뒤, 네트워크를 통해 PC를 깨우는 대신 SmartThings와 연동되는 스마트 스위치를 사용하기로 했습니다. 스마트 스위치로 데스크탑의 전원을 공급하고, BIOS에서 AC 전원이 복구되면 자동으로 부팅하도록 설정해서 현재까지 사용 중입니다. 덕분에 빅스비나 SmartThings 어플로 전원을 켜기만 하면 되고, 이후 WSL과 Tailscale, SSH가 올라오도록 구성할 수 있었습니다.
4. WSL에서 원격 개발환경 구축
4.1 WSL2 Ubuntu 설치 및 기본 개발환경 구성
원격 개발환경을 구성하면서 가장 먼저 정한 것은 실제 개발환경을 Windows가 아니라 Linux 기반으로 두는 것이었습니다. 그 이유는 제가 주로 다루는 Python, AI/ML, 서버 개발 생태계가 Linux를 기준으로 구성되는 경우가 많았기 때문입니다. CUDA나 각종 개발 도구의 설치 방법, shell 명령, 권한 체계, 서버에서의 실행 방식까지 실제 작업 환경과 자연스럽게 이어졌습니다. 로컬에서 작성한 명령이나 스크립트를 별도의 변환 없이 다른 Linux 서버에서도 거의 그대로 사용할 수 있다는 점도 장점이었습니다.
CLI 중심의 개발 도구를 사용하기에도 Linux 환경이 더 자연스러웠습니다. Git, Python, Node.js뿐 아니라 Codex와 Claude Code처럼 shell과 파일 시스템을 직접 다루는 도구들을 하나의 Unix 계열 환경 안에서 사용하는 편이 단순했습니다. 이후 tmux와 SSH를 이용해 데스크탑을 원격 개발 머신처럼 사용할 계획과도 잘 맞았습니다.
그래서 게임이나 일반 GUI 프로그램은 Windows에서 그대로 사용하면서, WSL2를 이용하면 별도의 Linux 머신 없이도 같은 데스크탑 안에 독립적인 Ubuntu 개발환경을 둘 수 있었습니다.
4.2 OpenSSH 서버 구성
WSL에 개발환경을 구성한 뒤에는 외부의 랩탑에서 이 환경에 접속할 방법이 필요했습니다. 원격 접속 자체는 Linux 환경에서 익숙하게 사용할 수 있는 OpenSSH를 선택했습니다.
다만 SSH 서버의 22번 포트를 인터넷에 그대로 노출하고 싶지는 않았습니다. 공유기의 포트포워딩이나 공인 IP, DDNS 등을 별도로 관리하는 방식보다는, 제 장치끼리만 연결되는 사설 네트워크를 구성하는 편이 목적에 더 잘 맞았습니다. 그래서 랩탑과 데스크탑 사이의 네트워크에는 Tailscale을 사용하기로 했습니다.
Tailscale을 사용하면 두 장치가 서로 다른 장소와 네트워크에 있어도 같은 사설망에 있는 것처럼 접근할 수 있었습니다. 외부에 SSH 포트를 공개하지 않아도 되고, 접속할 때마다 집의 공인 IP를 신경 쓸 필요도 없다는 점이 마음에 들었습니다.
처음 생각했던 구조는 Tailscale을 Windows에서 실행하고, Windows로 들어온 연결을 WSL의 OpenSSH 서버까지 전달하는 방식이었습니다.

하지만 WSL2는 자체적인 가상 네트워크를 사용했기 때문에 Windows에서 WSL까지 연결을 넘기는 과정이 생각보다 단순하지 않았습니다. 처음에는 portproxy를 사용해 Windows의 특정 포트를 WSL의 SSH 포트로 전달했습니다. 이 방식은 동작했지만 WSL의 내부 IP가 바뀌면 설정도 함께 수정해야 했고, Windows 방화벽과 포트 프록시까지 함께 관리해야 했습니다.
이후에는 WSL의 mirrored networking도 시도했습니다. Windows와 WSL 사이의 네트워크 경계를 줄이면 구조를 단순화할 수 있을 것으로 생각했지만, 실제로는 Windows 방화벽과 Hyper-V 네트워크 설정까지 얽히면서 원하는 형태로 안정적으로 연결되지 않았습니다.
여기서 굳이 Tailscale → Windows → WSL이라는 경로를 유지할 필요가 없다는 생각이 들었습니다. 어차피 최종 목적지는 WSL이었기 때문에 Tailscale 자체를 WSL에 설치했습니다. Windows를 네트워크 중계 지점에서 제외하자 portproxy나 WSL 내부 IP를 관리할 필요도 없어졌습니다. 랩탑에서는 Tailscale을 통해 WSL에 직접 도달하고, 그 위에서 OpenSSH로 접속하는 형태로 정리했습니다.
4.3 tmux를 이용한 세션 유지
원격 개발환경을 실제로 사용하다 보니 작업 세션을 얼마나 안정적으로 유지할 수 있느냐도 중요했습니다. 위 단계를 마친 후, VS Code와 IntelliJ가 기본적으로 제공하는 Remote SSH 기능으로 원격 개발이 가능해졌습니다. 프로젝트 파일과 Python 환경, Git 설정은 모두 데스크탑의 WSL에 두고, 랩탑에서는 IDE만 실행하는 방식이었습니다.
하지만 랩탑이 절전 모드에 들어가거나 네트워크가 끊기고, IDE를 종료하는 상황에서는 원격 세션이 함께 끊기는 점이 불편했습니다. 짧은 작업이라면 다시 접속하면 됐지만, Codex나 Claude Code처럼 오래 실행해 두는 CLI 작업이나 장시간 실행되는 Python 작업에는 적합하지 않았습니다.
그래서 장시간 유지해야 하는 작업은 Warp에서 SSH로 접속한 뒤 tmux 세션 안에서 실행했습니다. 실제 프로세스는 데스크탑의 WSL과 tmux 안에서 동작하기 때문에, 랩탑의 네트워크가 끊기거나 화면을 닫더라도 작업에는 영향을 주지 않았습니다.
이후 다시 랩탑에서 SSH로 접속해 기존 tmux 세션에 붙으면 이전 작업을 그대로 이어갈 수 있었습니다. 결과적으로 코드 작성이나 문서작업, 시각적 피드백은 VS Code나 IntelliJ의 Remote SSH를 사용하고, 장시간 유지해야 하는 터미널 작업은 Warp와 tmux를 사용하는 형태로 역할이 나누어 사용 중입니다.
5. WSL 자동 시작 구성
원격 개발환경을 거의 다 구성하고 나니 마지막으로 사소한 문제가 남았습니다. 데스크탑의 전원을 원격으로 켤 수 있고, WSL 안에는 Tailscale과 OpenSSH도 모두 준비되어 있었지만, Windows가 부팅됐다고 해서 WSL이 자동으로 실행되지 않았고, chrome 원격 데스크탑으로 문제를 해결하는 일이 발생했습니다.
문제는 SmartThings로 데스크탑 전원을 켜더라도 WSL이 시작되지 않으면 그 안에서 실행되는 Tailscale과 SSH 서버도 함께 올라오지 못하고 있었습니다. 처음에는 작업 스케줄러에서 Windows 로그인 시 WSL을 실행하도록 설정했습니다. 일반적으로 직접 PC를 켜서 사용하는 상황에서는 문제가 없었지만, 이번 환경에서는 전원을 원격으로 켠 뒤 Windows 로그인 화면에서 멈춰 있는 경우가 대부분이었습니다. 이 경우 로그인 이벤트 자체가 발생하지 않기 때문에 WSL도 시작되지 않았습니다.
그래서 자동 실행 기준을 사용자 로그인 시점이 아니라 Windows 부팅 시점으로 바꾸고 실제 테스트를 해봄으로써 원하는 세팅을 완성할 수 있었습니다.
6. 실제 일상에서의 사용
통학을 하며 해커톤이나 빅데이터 분석을 할 때 늘 랩탑의 저장공간과 GPU 연산이 고민이었습니다. chrome 원격 데스크톱을 사용해 보기도 하고, 스케줄러를 통해 작업을 자동화하기도 하였습니다. 하지만 간단한 IOT 와 Remote SSH 작업을 했을 뿐인데, 전원 관리와 명령어 입력을 필요할 때마다 할 수 있게 되어 만족스러웠습니다.
다만, IDE나 터미널이 충족시켜주지 못하는 작업같은 경우에는 여전히 chrome 원격 데스크톱을 사용중입니다. 문라이트+아폴로 조합으로 지연을 줄이고 원격으로 게임을 즐기는 것이 가능하다고 서치를 해두었는데, 아직까지 필요를 느끼지 못하여 하고 있지는 않습니다.
7. 정
WOL 대신 SmartThings + 스마트 스위치를 선택한 이유
- 처음에는 WOL을 사용하려 했음
- 외부에서 공유기 관리 페이지를 거치는 과정과 타임아웃이 불편했음
- 전원 제어 자체를 네트워크 구성과 분리하고 싶었음
- 결국 스마트 스위치 + BIOS AC Power Recovery가 더 단순했음
Windows 대신 WSL2 Ubuntu를 개발환경으로 선택한 이유
- 초기화 후 새로 구축하는 상황이라 기존 Windows 환경을 유지할 필요가 없었음
- Python/AI/ML/서버 생태계가 Linux에 더 자연스럽다고 판단
- SSH, tmux, CLI 기반 도구들과도 잘 맞았음
공인 IP + 포트포워딩 대신 Tailscale을 선택한 이유
- SSH 포트를 인터넷에 직접 노출하고 싶지 않았음
- 공인 IP, DDNS, 공유기 포트포워딩을 관리하고 싶지 않았음
- 랩탑과 WSL을 같은 사설 네트워크처럼 연결할 수 있었음
Remote SSH만 쓰다가 tmux를 추가한 이유
- VS Code/IntelliJ Remote SSH만으로도 개발 자체는 가능했음
- 하지만 랩탑 절전, 네트워크 변경, IDE 종료 등에 세션이 영향을 받음
- 장시간 작업은 Warp + SSH + tmux로 데스크탑에 남겨두는 방식이 더 적합했음
'배움 일기' 카테고리의 다른 글
| GDGOC 6th BE Week 3 - Spring 핵심 원리와 JPA 입문 (0) | 2026.10.04 |
|---|---|
| GDGOC 6th BE Week 2 - Backend와 Spring Boot로 첫 API 만들기 (0) | 2026.10.04 |
| Less is more, 바우하우스부터 조너선 아이브까지 (0) | 2026.03.01 |
| Tistory 스킨 'hELLO' HTML 커스텀하기 (0) | 2026.02.28 |
| 디자인 협업 툴, Figma의 기능들 기초 (0) | 2025.12.29 |
