여기서도 읽을 수 있습니다! Notion
code-server
는 웹에서 VS-Code
를 쓸 수 있도록 해주는 서비스다. 전역 후 아이패드로 코딩할 생각에 행복회로를 돌리던 나는 미리 구현해놓기로 했다. 어차피 사지방에서 코딩할 때도 필요해서.. 그런데 자료가 상당히 부족하고, nginx
나 proxy
에 관한 지식도 부족해 많이 헤맸다. 이 과정을 기록해둬 나중에 다시 환경을 구축해야 할 때 참고하고자 한다.
AWS EC2
에 올릴 예정이니, 인스턴스 생성을 가장 먼저 해야한다.
나머지 포트들은 각자 필요하면 추가하기~
이대로 인스턴스를 만들어주기만 하면 AWS
자체에서 할 설정은 없다. 이후 과정들은 ssh
로 인스턴스에 접속한 상태에서 진행한다.
ssh -i ubuntu@<ec2 public domain>
공식문서에서 제공하는 설치 명령어를 사용하면 된다. 이 경우 서비스가 systemctl --user
단에 설정된다.
curl -fsSL https://code-server.dev/install.sh | sh
그 다음 systemctl --user
에 code-server
를 활성화해야 한다. 이 명령어는 설치 명령어에서 마지막에 하라고 알려준다.
systemctl --user enable --now code-server
code-server
는 localhost
로만 서비스를 제공한다. 이를 외부로 보내줄 proxy가 필요하다. nginx
로 이를 구현해보자. 먼저 nginx
를 설치한다.
sudo apt install nginx
이후 code-server가 사용할 .conf
파일을 만들어준다. 우린 certbot
을 통해 ssl을 설정할거고, 테스트도 할 겸 http 연결로 만들어주자.
sudo vim /etc/nginx/sites-available/code-server.conf
server {
listen 80;
listen [::]:80;
server_name <instance ip>;
location / {
proxy_pass http://127.0.0.1:8080/;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection upgrade;
proxy_set_header Accept-Encoding gzip;
}
}
sites-enable
에 링크를 생성해준다. 이후 수정할 때는 sites-available
의 파일만 수정해주면 된다!
sudo ln -s /etc/nginx/sites-available/code-server.conf /etc/nginx/sites-enabled/code-server.conf
이후 nginx
문법을 확인하고 서비스를 재시작해준다. 이 때는 그냥 systemctl
이다.
sudo nginx -t
sudo systemctl restart nginx
여기까지 하면 인스턴스 ip만 주소창에 치면 code-server
접속이 가능하다. 하지만 code-server
에선 안전하지 않은 도메인으로 접속하면 일부 기능을 제한시킨다. ssl을 적용시켜보자.
우선, 도메인을 하나 구매하고, A 레코드에 인스턴스 주소를 추가해둔다. (서브도메인은 마음대로~) 이렇게 한 상태에서 진행하는 게 마음이 편하다.
certbot
저장소 추가. sudo add-apt-repository ppa:certbot/certbot
패키지 목록을 업데이트, `certbot`설치
sudo apt-get update
sudo apt-get install python-certbot-nginx
간혹 업데이트와 업그레이드가 되지 않는 경우 (최신버전 권장)
sudo add-apt-repository ppa:certbot/certbot
sudo vim /etc/nginx/sites-available/code-server.conf
서버 블록 파일 안에 `server_name`을 설정하고자 하는 도메인 이름으로 변경
server {
listen 80;
listen [::]:80;
server_name <your domain>;
location / {
proxy_pass http://127.0.0.1:8080/;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection upgrade;
proxy_set_header Accept-Encoding gzip;
}
}
문법검사 + 재시작
sudo nginx -t
sudo systemctl restart nginx
https
리다이렉션 옵션 선택 sudo certbot --nginx -d <your domain>
위와 같이 설정하면, ec2
와 ssh
연결을 끊는 순간 웹페이지가 다음과 같은 메시지를 띄우며 접속이 안 될 것이다.
502 Bad Gateway nginx/1.14.0 (Ubuntu)
이는 다음 명령으로 해결할 수 있다.
loginctl enable-linger ubuntu
여기까지 따라오면 설정은 끝이다. 이제 로컬에서 사용하는 vscode의 설정을 settings-sync로 옮겨와 작업환경을 구성하고, 터미널을 꾸미면 된다! 이 뒤는 왜 저 명령을 사용하는지에 대한 내용으로, 궁금하지 않다면 읽지 않아도 된다 사실 뒷내용은 이 부분에서 삽질을 가장 오래 해서 적는 푸념글에 가깝다
ssh 연결에 사용하는 22번 포트 단절을 nginx가 비정상적 종료라 생각하고 서버를 내려버린다라는 가정을 세우고, 설정 문제일거라 생각하고 뭐가 문제인지 8시간이 넘게 구글링했는데, 시원한 해결방법을 발견할 수 없었다. 구글에는 나처럼 멍청한 사람이 없었기 때문이다... 그리고 나중에 확인해보니, 심지어 nginx 자체는 내려가지 않았다(인스턴스 ip로 접속해보니 success가 출력된다).
결국 새로운 인스턴스를 만들고 공식 가이드와 타 커뮤니티 가이드들, 그리고 위 글을 참고하여 차근차근 다시 해보고 있었는데, 한 가지 의문이 들었다.
왜 타 커뮤니티에선 전역
systemd
를 사용하는데 공식 가이드만systemd -user
레벨을 사용하는 걸까?
실제로 위 스크립트를 실행하면 전역 systemd
로는 설정이 안되고, user
레벨에서만 가능하다 (애초에 파일 생성을 user
레벨에서 설정하는 경로로 넣어주니까..) 왜 그런지 궁금해서 systemd -user
에 대해 검색해보기 시작했다. 그리고 충격적인 사실을 알게 되었다.
PAM 모듈은 사용자가 로그인을 하게 되면 자동으로 systemd –user 명령을 실행해준다. 그리고 로그아웃을 하게되면 systemd –user 로 실행된 프로세스는 종료된다.
그렇다, 연결이 끊어진 이유는 ssh
와 관련된게 아니라, 로그아웃이 됐기 때문이다!
크게 두 가지 방법으로 이를 해결할 수 있다.
systemd
로 설정을 옮긴다.loginctl enable-linger
로 user manager
가 로그아웃시에도 끊어지지 않게 한다.나는 이미 도메인에 ssl까지 세팅을 해놨고, 터미널 세팅도 하다가 이 이슈를 발견해서 2번으로 해결했다. 파일들을 통채로 옮기다 무슨 일이 벌어질지 걱정이 됐기 때문이다 (더 이상 구글링을 하고싶지 않기도 했다)
어떤 선택이 보안적 측면에서, 또는 시스템 측면에서 유리할지는 모르겠다. 다만 어차피 유저별로 systemd
를 나눠둘 이유도 없으며, 로그아웃시에도 켜져있어야 하니 1이 더 근본적인 해결책에 가깝다 생각한다. 이렇게 할 경우 간편한 공식 설치 명령어보단 직접 [Unit]
을 작성해 구성하는 편이 더 자연스럽다 (설치를 다 해두고 옮기는건 그림이 뭔가 웃기잖아,, 처음부터 맞는 자리에 설치해야지)
어려워보이는 ssl 설정은 쉽게 끝냈는데, 문제의 원인을 빠르게 찾아내지 못했고, 리눅스 systemd
에 무지해서 시간이 너무 오래 끌렸다. 문제가 생겼을 때 그 현상 자체만 생각하며 검색하며 문제를 해결한 다른 누군가를 찾는것보다, 내가 해온 과정을 처음부터 되짚어가며 놓친게 없는지 하나하나 확인해보는게 더 생산적인 문제해결방식이라는 생각을 하게 됐다.
유용한 정보 정말 감사드립니다! 저도 EC2를 사용해서 원격으로 개발을 하려고 알아보다가 이 글을 보고 도움을 많이 받았습니다. 그런데 EC2 EBS-backed instance의 경우 stop을 시킨 후 다시 start 했을 때 public IPv4가 변경되어 기존에 설정했던 ip 와 도메인으로 접속이 안 되는 문제가 발생했는데, 혹시 JaKe님은 이 문제를 해결하셨나요?