SSH로 클라우드 Mac에 접속해 오래 걸리는 빌드를 시작한 뒤 노트북을 덮었다가 다시 연결했더니 터미널이 사라져 있을 수 있습니다. 이때 가장 곤란한 점은 작업을 다시 실행해야 한다는 사실이 아니라, 작업이 실패했는지, 끝났는지, 아니면 백그라운드에서 계속 실행 중인지 판단할 수 없다는 것입니다. 안정적인 해결책은 연결 제한 시간을 무작정 늘리는 것이 아니라 네트워크 연결, 터미널 세션, 실제 작업을 세 계층으로 분리하는 것입니다. SSH는 노드 접속을 담당하고, tmux는 터미널 상태를 보존하며, 로그와 종료 코드는 결과를 입증합니다.
연결 끊김이 어느 계층에 영향을 주는지 먼저 구분하기
원격 데스크톱이나 SSH 연결이 끊겼다는 것은 클라이언트와 클라우드 Mac 사이의 대화형 통신 채널이 중단됐다는 뜻일 뿐, 물리 노드가 멈췄다는 의미는 아닙니다. 하지만 SSH 의사 터미널에 직접 연결된 포그라운드 프로세스는 세션이 닫힐 때 연결 종료 신호를 받을 수 있습니다. 그래픽 인터페이스에서 연 터미널도 무인 작업의 실행 지점으로는 적합하지 않습니다. 창을 닫거나 데스크톱에서 로그아웃하면 해당 프로세스의 수명 주기가 달라질 수 있기 때문입니다.
실제 빌드로 바로 시행착오를 겪지 말고, 먼저 10분짜리 간단한 작업으로 환경을 검증합니다.
mkdir -p "$HOME/jobs/session-check"
cd "$HOME/jobs/session-check"
date -u +"start=%Y-%m-%dT%H:%M:%SZ" > run.log
sleep 600
date -u +"finish=%Y-%m-%dT%H:%M:%SZ" >> run.log
명령을 실행한 뒤 일부러 연결을 끊고, 다시 접속해 run.log를 확인합니다. 이 기준 테스트를 통해 노드 자체가 계속 실행되는지는 확인할 수 있지만, 세션 관리 도구를 대체할 수는 없습니다.
SSH 연결 유지는 “연결 장애를 얼마나 빨리 감지할 것인가”를 해결하고, tmux는 “연결이 끊긴 뒤에도 작업을 복구 가능한 터미널에 유지할 것인가”를 해결합니다. 둘은 서로 대체할 수 없습니다.
SSH 연결 유지와 명확한 시간 제한 설정하기
로컬 Mac의 ~/.ssh/config에 해당 노드 전용 설정을 만듭니다. 주소와 사용자 이름은 콘솔에서 제공하는 실제 값으로 바꿔야 합니다.
Host minid-node
HostName <node-address>
User <system-user>
ServerAliveInterval 30
ServerAliveCountMax 3
TCPKeepAlive yes
ConnectTimeout 10
ServerAliveInterval 30은 클라이언트가 30초마다 애플리케이션 계층 탐색 요청을 보낸다는 뜻입니다. 연속 세 번 응답이 없으면 SSH는 터미널을 무기한 멈춘 상태로 두지 않고 끊어진 연결을 종료합니다. 이 설정은 자동 재접속을 수행하지 않으며 포그라운드 프로세스의 생존도 보장하지 않습니다.
접속하기 전에 최종 적용되는 설정을 확인할 수 있습니다.
ssh -G minid-node | grep -E 'serveralive|tcpkeepalive|connecttimeout'
ssh minid-node
네트워크를 자주 전환하는 환경이라면 시간 제한을 수십 분까지 늘리지 않는 것이 좋습니다. 연결이 끊겼음을 빠르게 확인해야 tmux에 다시 들어가 실제 진행 상태를 확인하기도 쉽습니다.
tmux로 장시간 작업 관리하기
먼저 tmux가 설치되어 있는지 확인하고, 없다면 현재 환경에서 사용하는 패키지 관리 방식으로 설치합니다.
command -v tmux || brew install tmux
tmux new-session -s ios-build
세션 이름에는 작업 용도가 드러나야 합니다. 예를 들어 ios-build, integration-test, asset-export처럼 지정하고, 의미가 모호한 work를 계속 재사용하지 않습니다. 세션에 들어간 뒤 별도의 디렉터리를 만들고, 출력이 터미널과 로그에 동시에 기록되도록 합니다.
job_dir="$HOME/jobs/ios-build-$(date +%Y%m%d-%H%M%S)"
mkdir -p "$job_dir"
cd "$job_dir"
set -o pipefail
caffeinate -i /path/to/run-build.sh 2>&1 | tee build.log
status=${PIPESTATUS[0]}
printf '%s
' "$status" > exit-code.txt
date -u +"%Y-%m-%dT%H:%M:%SZ" > finished-at.txt
Control-b를 누른 다음 d를 누르면 작업을 종료하지 않고 세션에서 분리할 수 있습니다. 노드에 다시 접속한 뒤에는 다음 명령을 실행합니다.
tmux list-sessions
tmux attach-session -t ios-build
caffeinate -i는 명령이 실행되는 동안에만 유휴 상태로 인한 잠자기를 방지해야 한다고 선언합니다. 특정 작업과 함께 사용해야 하며, 편의를 위해 영구적으로 실행해서는 안 됩니다. 순수한 명령줄 빌드라면 디스플레이까지 강제로 깨워 둘 필요는 없습니다.
중복 실행 방지하기
네트워크 연결이 끊긴 뒤에는 먼저 tmux list-sessions와 pgrep -fl run-build를 실행합니다. 기존 작업이 없다는 사실을 확인한 뒤에만 다시 시작해야 합니다. 그렇지 않으면 두 빌드가 동일한 파생 데이터 디렉터리, 캐시 또는 산출물 경로에 동시에 쓰면서 재현하기 어려운 혼합 결과를 남길 수 있습니다.
로그와 종료 코드를 검증 기준으로 사용하기
다시 접속했을 때 터미널 출력이 계속 올라온다는 사실만으로는 작업을 검증할 수 없습니다. 모든 장시간 작업은 최소한 시작 시각, 종료 시각, 전체 로그, 종료 코드를 남겨야 합니다. 종료 코드가 0이어야만 스크립트가 약속된 방식으로 성공적으로 끝났다는 뜻입니다. 로그 마지막에 특정 단어가 나타났다는 사실로 종료 코드를 대신할 수는 없습니다.
다음 순서로 확인하면 상태를 빠르게 판단할 수 있습니다.
| 확인 항목 | 명령 | 판단 |
|---|---|---|
| 세션이 존재하는가 | tmux list-sessions |
세션이 있어도 작업이 실행 중이라는 뜻은 아님 |
| 프로세스가 존재하는가 | pgrep -fl run-build |
현재 실행 인스턴스 확인 |
| 로그가 계속 증가하는가 | tail -n 30 build.log |
진행 상황이나 정체 지점 판단 |
| 정상적으로 종료됐는가 | cat exit-code.txt |
0이면 스크립트 성공 |
| 종료 시각 | cat finished-at.txt |
결과가 이번 실행에서 생성됐는지 판단 |
스크립트는 실행할 때마다 새 디렉터리를 생성해야 하며, 이전 실행의 로그를 덮어쓰면 안 됩니다. 정리가 필요할 때는 아카이브가 완료됐음을 확인한 디렉터리를 날짜별로 삭제해야 합니다. 전체 ~/jobs를 대상으로 재귀 삭제를 실행해서는 안 됩니다.
실제 사용 전에 의도적으로 연결 끊김 테스트하기
실제 작업에 적용하기 전에 안전하게 반복할 수 있는 테스트 작업을 시작한 뒤 SSH 연결 끊기, 원격 데스크톱 닫기, 로컬 네트워크 전환을 차례로 검증합니다. 다시 연결할 때마다 tmux 세션, 대상 프로세스, 로그 증가 여부, 종료 코드 파일을 모두 확인합니다.
작업이 그래픽 인터페이스에 의존한다면 원격 데스크톱 연결이 끊긴 뒤에도 계속 실행되는지 별도로 검증해야 합니다. 명령줄 도구와 그래픽 애플리케이션의 수명 주기는 서로 다릅니다. 작업이 예상보다 일찍 종료되면 먼저 스크립트의 종료 코드와 로그를 확인하고, 다음으로 터미널이 닫혔는지 확인한 뒤, 마지막으로 저장 공간과 프로세스 리소스를 점검합니다. 모든 실패의 원인을 네트워크로 단정해서는 안 됩니다.
실제 운영에 사용할 수 있는 점검 목록에는 다음 항목이 포함되어야 합니다.
- SSH 설정을
ssh -G로 검증할 수 있어야 합니다. - 장시간 작업 유형마다 별도의 tmux 세션을 사용합니다.
- 작업 디렉터리를 시간 기준으로 생성하고 이전 결과를 덮어쓰지 않습니다.
- 표준 출력과 표준 오류를 검색 가능한 하나의 로그에 기록합니다.
- 종료 코드와 UTC 기준 종료 시각을 별도로 저장합니다.
- 연결이 끊긴 뒤에는 기존 작업부터 복구하며 중복 실행하지 않습니다.
- 작업이 끝나면 불필요한 세션을 직접 종료하고 산출물을 보관합니다.
자주 묻는 질문
SSH 연결이 끊기면 원격 Mac의 작업도 항상 종료되나요?
항상 그렇지는 않습니다. SSH 터미널에 직접 연결된 프로세스는 종료 신호를 받을 수 있지만, tmux 안에서 시작한 작업은 계속 실행됩니다. 재접속 후 세션과 로그를 확인해야 합니다.
ServerAliveInterval 설정만으로 장시간 작업을 보호할 수 있나요?
아니요. 이 설정은 끊어진 연결을 감지할 뿐 프로세스를 보존하지 않습니다. 작업은 tmux에서 실행하고 표준 출력, 오류와 종료 코드를 파일로 남겨야 합니다.
MiniD 클라우드 Mac
전용 물리 Mac mini를 일·주·월 단위로 대여
모든 플랜은 전용 물리 Mac mini에서 실행되며 원격 데스크톱과 SSH로 접속할 수 있습니다. 최신 모델·리전·기간은 주문 페이지에서 확인하세요.