🎈문제상황
외부 프로젝트 팀에 참가해 작업했던 프로젝트의 EC2 기간이 끝났습니다. 해당 프로젝트는 기능 개선 후 추가 개발 예정이라 기획 / 디자인 팀에서 심혈을 기울여 작업중에 있으며 인스타 등의 마케팅을 하며 서버가 계속 살아있어야 하는데 EC2, RDS 두 개를 사용하면 계속해서 AWS에서 비용이 발생합니다. 그래서 해당 프로젝트의 프로젝트 종료 전까지는 지속적으로 사용할 서버가 필요해 안쓰는 안드로이드 핸드폰을 사용해 자체적으로 배포하기로했습니다.
단순히 안드로이드 기기를 웹서버로 가용하는 방법은 간단합니다. 밑에 설명할 와이파이와 관련된 설정을 작업 후 termux, userland와 같은 터미널 에뮬러이터를 사용해 언어, 프레임워크등을 다운 후 gradlew build, java -jar ...와 같은 명령어를 통해 직접 실행하면 됩니다.
하지만 프로젝트에 사용되는 스택들이 추가되며 관리의 필요성을 느끼면 Docker 도입을 통한 컨테이너의 필요성을 체감하는데 Docker는 커널에 특정 기능(namespace, cgroups 등)을 필요로 합니다. 하지만 보안상의 이유로 제한되어 있으며 또 Root권한도 제한되어있습니다.
그래서 루팅을 후 커널 컴파일을 통해 커널에 대한 접근 권한을 얻거나 앞으로 설명할 가상화 에뮬레이터를 통한 배포를 실행해야합니다. 저는 루팅을 시도했다 중고 테블릿이 벽돌이 된 후 루팅 없이 가능한 방법을 찾는데 성공했습니다... 🥲
🎈순서
1. termux 설치
Releases · termux/termux-app
Termux - a terminal emulator application for Android OS extendible by variety of packages. - termux/termux-app
github.com
2. 와이파이 설정(포트 포워딩, DDNS 설정 등)
3. termux ssh 설정(편의를 위함)
Release Nightly Release 20250101 · termux/termux-x11
This is a nightly release of the termux-x11 app. Based on b13fcd5
github.com
5. alpine linux 설치
6. nginx를 사용한 포트 포워딩 확인 및 배포
1. termux는 안드로이드에서 리눅스 환경을 구성할 수 있게 해주는 에뮬레이터입니다.
2. 핸드폰을 사용한 배포는 집의 와이피이를 사용합니다. 그리고 와이파이는 계속해서 IP가 변동되기 때문에 도메인을 사용해 ip변동을 대응하는 방법입니다.
3. ssh 설정은 핸드폰 / 테블릿 화면보다 컴퓨터를 사용한 개발이 편하게 때문에 큰 화면의 블루투스 키보드를 사용한 개발 환경을 사용하는 사람이면 넘겨도 되는 부분입니다.
4. termux만으로는 커널이 필요한 docker를 사용하기에는 부족합니다. 안드로이드 OS자체에서 커널 사용을 막기 때문에 커널 컴커스텀 컴파일을 통한 Docker사용 방법이 있지만 저는 해당 방법을 사용하다 저가 테블릿을 하나 날려먹었기 때문에 루팅없이 진행하기 위한 해당 방법을 선택했습니다....
5. 현재 사용중인 핸드폰은 지급제의 저사양 핸드폰을 사용중이라 경량형 Linux인 Alpine 모델을 선택했습니다.
6. alpine linux를 사용한 설치 후 포트 포워딩을 통해 termux에서 alpine linux container까지의 연결을 시도할 겁니다. 이에 대한 확인 법으로 nginx를 사용할 예정이며 이후 실제 프로젝트를 올린 후에도 nginx를 통한 인프라 개선이 있을 예정입니다 :)
🎈 1. Termux 설치
https://github.com/termux/termux-app/releases
Releases · termux/termux-app
Termux - a terminal emulator application for Android OS extendible by variety of packages. - termux/termux-app
github.com
해당 링크에서 다운받아 핸드폰/테블릿에 설치하면됩니다
🎈 2. Wi-Fi 설정
아파트 기본 와이파이를 사용하는 경우도 있지만 저는 Iptime을 사용하기 때문에 Iptime을 기준으로 설명하겠습니다.
웹 브라우저에 192.168.0.1입력 후 접속하면 iptime 관리자 화면이 나옵니다. 로그인 후 관리도구로 들어갑니다.
저희가 필요한 설정은 3가지 입니다.
1. 고급설정 - 네트워크 관리 - DHCP 서버 설정
2. 고급설정 - NAT/라우터 관리 - 포트포워드 관리
3. 고급설정 - 특수기능 - DDNS 설정
DHCP 서버 설정
해당 화면에서 웹서버로 사용할 기기를 등록해주시면 됩니다. 어떤 기기인지 헷갈린다면 설정 - 휴대전화 정보 - 상태 정보 - Wi-Fi MAC 주소 - 사용중인 와이파이 선택 - MAC 주소를 확인해주시면됩니다.
휴대전화 Wi-Fi MAC 주소와는 다르기 때문에 Wi-Fi MAC 주소 - 와이파이 선택 - MAC 주소로 접근해야 해당 주소와 맞는 기기를 선택할 수 있습니다.
포트포워드 관리
AWS에서 인바운드 포트 열어주듯이 사용할 포트들을 열어주면됩니다.
http, https등을 비롯해 DB연결을 위한 3306, spring 프로젝트를 위한 8080포트까지 열어줬습니다. 그리고 termux는 기본적으로 sshd를 위한 8022포트가 열려있어 해당 설정은 추가 안해도괜찮습니다.
DDNS 설정
iptime 사용자는 최초 설정 때 DDNS를 위한 호스트를 설정합니다. 그리고 Wi-Fi의 IP는 유동적이기 때문에 해당 도메인으로 요청을 주고받을 예정이나 해당 부분을 확인해주시면됩니다.
이제 본격적으로 Termux로 작업해보겠습니다 :)
🎈 3. Termux SSH 설정
핸드폰/테블릿 화면은 작고 외부 작업 시 핸드폰에 접속하여 수정을 해야할 때가 있습니다. 따라서 SSH를 통해 원격 접속해 작업하겠습니다.
해당 작업부터는
https://github.com/LinuxDroidMaster/Termux-Projects/blob/main/projects/docker_android.md
Termux-Projects/projects/docker_android.md at main · LinuxDroidMaster/Termux-Projects
Set of projects that can be done with Termux such as setting up web servers, Torrents servers, etc. - LinuxDroidMaster/Termux-Projects
github.com
https://github.com/LinuxDroidMaster/Termux-Desktops
GitHub - LinuxDroidMaster/Termux-Desktops: Collection of scripts to launch Desktops with audio in Termux X11 and how to use hard
Collection of scripts to launch Desktops with audio in Termux X11 and how to use hardware acceleration - LinuxDroidMaster/Termux-Desktops
github.com
해당 레포에서의 설명을 직접 적용해보며 겪었던 이슈도 정리할 예정입니다. 해당 레포에는 유튜브 설명까지 자세히 나와있기 때문에 레포를 통해 작업하셔도 무관합니다.
먼저 termux를 설치했다면 ssh를 설정해줍시다.
pkg update -y && pkg upgrade -y
pkh install openssh -y
또 저희는 비밀번호를 사용해서 접속할 예정이니 비밀번호도 설정해줍시다.
passwd
<사용할 비밀번호 입력>
sshd
비밀번호 설정 후 sshd를 입력하면 이제 sshd가 실행되며 외부에서 접속해 작업할 수 있습니다.
외부에서 접속 방법은
ssh <설정한 host>.iptime.org -p 8022
입력 후 비밀번호를 입력하면 성공입니다.
🎈 4. Termux Desktop 설치
https://github.com/LinuxDroidMaster/Termux-Desktops?tab=readme-ov-file#first-steps
GitHub - LinuxDroidMaster/Termux-Desktops: Collection of scripts to launch Desktops with audio in Termux X11 and how to use hard
Collection of scripts to launch Desktops with audio in Termux X11 and how to use hardware acceleration - LinuxDroidMaster/Termux-Desktops
github.com
위의 레포를 보면 유튜브 비디오로 Termux Desktop 설치에 대해 설명해줍니다.
https://www.youtube.com/watch?v=rq85dxMb7e4
해당 내용을 정리하면
pkg update
pkg upgrade
pkg install x11-repo
pkg install termux-x11-nightly
pkg install tur-repo
pkg install pulseaudio
pkg install proot-distro
pkg install wget
pkg install git
pkg install xfce4
여러 패키지를 설치 후
cd ~
wget https://raw.githubusercontent.com/LinuxDroidMaster/Termux-Desktops/main/scripts/termux_native/startxfce4_termux.sh
해당 파일을 wget으로 다운해줍니다.
그리고 위에서 얘기했던 termux-x11-nightly를 기기에 직접 또 설치해줘야합니다. termux에서만 설치하면 오류가 발생하며 제대로 작업이 진행이 안됬습니다.
https://github.com/termux/termux-x11/releases/tag/nightly
어플리케이션을 직접 기기에 설치 후 wget으로 다운 받았던 스크립트 파일을 termux에서 실행합니다.
bash startxfce4_termux.sh
그러면 스크립가 알아서 여러 작업을 진행해주며 x11이 실행되며 GUI화면이 나타납니다. 하지만 저희는 외부 작업시 termux를 통한 터미널 환경을 통해 작업을 계속할겁니다.
🎈 5. Qemu를 통한 Alpine Linux 실행
https://github.com/AntonyZ89/docker-qemu-arm
GitHub - AntonyZ89/docker-qemu-arm: Run Docker x86_64 on Arm computers or Android
Run Docker x86_64 on Arm computers or Android. Contribute to AntonyZ89/docker-qemu-arm development by creating an account on GitHub.
github.com
이제 본격적으로 docker를 실행하기 위해 qemu와 관련된 작업을 진행합니다. qemu는 가상화와 관련된 에뮬레이터입니다. 가상화 에뮬레이터의 사용 이유는 처음에 소개한대로 kernel, root에 대한 접근 권한 문제를 우회하기 위함입니다.
$ git clone https://github.com/antonyz89/docker-qemu-arm
$ cd docker-qemu-arm
$ ./termux-setup.sh
1. 레포 클론
2. 레포로 이동 후 termux-setup.sh 스크립트 파일 실행
스크립트 파일이 실행되는데 조금 시간이 필요합니다. 실행이 완료되면 해당 폴더 안에 alpine라는 폴더가 추가됩니다.
이제 alpine폴더로 이동 후 startqemu.sh파일을 실행해줍니다.
참고로 qemu 내부에서의 속도는 ec2를 사용할 때보다 느립니다. 저는 Ram 3GB짜리를 사용해서 그럴 거라고 예상중입니다. qemu을 통해 alpine container에 접속 후 docker 관련 커맨드를 입력하면 성공적으로 작동합니다 :)
🎈 6. 포트포워딩 / Nginx 설정
이제 alpine컨테이너에서 docker 작동을 확인했으니 alpine까지의 요청을 보낼 수 있게 termux와 alpine의 포트 포워딩을 진행하겠습니다.
터미널을 하다 더 열어 똑같이 ssh 연결을 통해 termux까지만 접근해줍니다. 이제 저희는 alpine, termux 2개의 공간에서 작업을 진행합니다.
먼저 termux에서 포트를 alpine까지 연결하겠습니다.
작업에 참고한 레포들을 보면 포워딩을 할 때
ssh -i qemukey -L 8080:localhost:4647 root@localhost -p 2222
해당 커맨드를 사용하는데 이건 같은 wifi에서만 작동합니다. 그래서 외부에서 작업할 수 있게 바꿔줍시다.
ssh -f -N -T -i ./qemukey -L 0.0.0.0:8080:localhost:8080 root@localhost -p 2222
- -f : ssh 세션을 백그라운드로 실행
- -N : 원격 명령을 실행하지 않음
- -T : 가상 터미널을 할당하지 않음(단순 포워딩을 위해)
-T 말고는 필수입니다.
-f를 통해 백그라운드로 실행해야 작업중인 터미널을 닫아도 포워딩을 유지되면 -N설정을 입력 안하면 포워딩이 진행되며 alpine container로 이동됩니다.
그리고 가끔 서버를 키고 끌 때가 있으니 해당 스크립트가 적힌 실행 파일을 만들면 편합니다.
nano port-forwarding.sh
chmod +x port-forwarding.sh
이름은 원하는걸로 설정 후 위의 ssh 관련 스크립트를 입력 후 저장 및 종료합니다.
그리고 실행하려면 파일의 권한을 변경해야하기 때문에 chmod로 권한을 변경해주면 이제 bash 커맨드를 사용해 포트 포워딩을 보다 손쉽게 할 수 있습니다 :)
이제 alpine 터미널로 이동해 ssh를 통한 포트포워딩을 허용해줘야합니다.
/etc/ssh/
해당 위치의 sshd_config파일을 수정해줍시다.
vi를 통해 파일에 접근하면
사진과 같이 많은 설정과 설명들이 있는데 밑으로 쭉 내리다 보면 2개의 설정이 보입니다.
AllowAgentForwarding yes
AllowTcpForwarding yes
2개의 설정이 no로 설정되있을 텐대 yes로 바꿔 포워딩을 허용해줍시다 이제 termux - alping까지의 포워딩이 완성됬습니다.
해당 설정을 완료하려면 alpine을 껏다 켜야합니다. 이제 터미널을 끄고 안드로이드 기기의 termux를 완전 종류 후 안드로이드 기기에서 termux 접속 후 sshd입력해 sshd를 허용 후 alpine폴더로 이동해 startqemu.sh를 실행시켜줍니다.
이번에 안드로이드 기기에서 qemu를 실행시킨 이유는 이제 계속해서 termux를 실행하며 웹서버로의 준비가 끝났기 때문입니다. 터미널에서 termux를 실행, 작업 후 터미널을 꺼버리면 alpine container까지 내려가 서버가 다운됩니다. 이를 방지하기 위해 안드로이드 기기에서 qemu를 실행합니다.
Nginx 설치
nginx 설치는 제일 간단합니다.
docker pull nginx
docker run -d -p 8080:80 nginx
nginx 이미지를 받고 포워딩을 한 포트와 80번 포트를 연결시킵니다. Nginx는 기본적으로 80포트로 요청을 받기 때문에 내부 포트는 80번으로 설정해줍니다.
마지막으로 확인하자면
- 와이파이 관리자 화면에서 ddns, 포트포워딩, dhcp 서버 설정
- alpine 터미널에서 sshd_config파일의 설정 변경 후 재가동
- termux 터미널에서 포트포워딩 스크립트 실행
- alpine 터미널에서 nginx 이미지 다운 및 설정한 포트로 가동
이제 iptime에서 제공하는 도메인에 설정한 포트로 접속하면 nginx화면을 볼 수 있습니다!!!
host-name.iptime.org:8080
감격스러운 화면입니다. 이제 간단한 사이드 프로젝트는 ec2가 아닌 핸드폰을 통해 배포할 수 있게 됬습니다 :)
🎈 후기
시작은 ec2에서 조금씩 발생하는 몇 천원이 은근히 아까워서 시작했습니다. 그래서 알아보니 이미 웹서버를 핸드폰으로 배포한 사람들의 한글 포스팅도 있어서 시도했다가 docker에서 막혀 시간이 오래 걸렸습니다. 만약 돈이 많았으면 라즈베리파이4를 사서 해봤을텐대라는 생각도 해당 작업을 하면서 자주 들었습니다. termux말고도 userland도 사용해봤고 루팅했다가 테블릿도 벽돌이 됬지만 결국 성공해서 다행입니다. 그리고 이것 뿐만 아니라 다른 작업을 할 때도 이미 같은 생각을 했던 괴물 개발자들의 포스팅을 보며 작업을 하는데 이런거를 처음 성공한 사람들에 대한 감사함과 이걸 어떻게 했지...라는 궁금함과 존경심도 동시에 듭니다.
최근 작업 중 가장 오랜 시간을 들여 완성한 결과물인 만큼 기쁨도 큽니다. 시간이 가장 오래 걸렸던 이유는 원하는 작업에 대한 정보가 적었습니다. 안드로이드 기기에서 docker를 돌리는 포스팅들은 rooting을 기본 조건으로 깔고 진행하기 때문에 루팅 없이 docker를 돌리기 위한 방법을 찾는데 오랜 시간이 걸렸고 레포에서 설명하지 않은 몇몇 이슈들도 조금 있어서 그것들을 완전히 해결하는데 조금 시간이 더 걸렸습니다.
🎈 트러블 슈팅
SSH 접속 오류
user@0 ~ % ssh user.iptime.org -p 8022
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!
Someone could be eavesdropping on you right now (man-in-the-middle attack)!
It is also possible that a host key has just been changed.
The fingerprint for the ED25519 key sent by the remote host is
SHA256:<암호값>.
Please contact your system administrator.
Add correct host key in /Users/<mac북에 설정한 닉네임>/.ssh/known_hosts to get rid of this message.
Offending ECDSA key in /Users/<mac북에 설정한 닉네임>/.ssh/known_hosts:14
Host key for [user.iptime.org]:8022 has changed and you have requested strict checking.
Host key verification failed.
하다보면 여러 에러가 발생해 termux 앱 데이터를 삭제 후 다시 sshd를 적용할 일이 생길 수 있습니다. 그러면 sshd설정이 변하기 때문에 위와 같은 에러가 발생합니다. 그러면 외부 접속 기기(노트북, 데스크탑 등)에서 기존의 ssh 정보를 삭제 후 다시 ssh 접속을 시도하면 됩니다.
mac을 기준으로
/Users/<mac북에 설정한 닉네임>/.ssh/known_hosts:
해당 위치의 known_hosts파일에 끝 줄을 보면 최근 실행한 ssh 정보가 있습니다. 해당 줄을 지워주면 됩니다.
필요한 vim 명령어는 3가지 입니다.
- G : 파일의 끝으로 이동
- dd : 해당 줄 삭제
- qw! : 저장 후 닫기
process completed signal 9
https://namu.wiki/w/Termux#s-7.3
Android OS는 자식 프로세스가 32개를 초과하는 모든 프로세스 및 과도한 CPU를 사용하는 프로세스를 워치독을 이용하여 강제 종료하게 되어 사용자가 쉘 프로세스를 종료하지 않았음에도 터미널에서 [Process completed (signal 9) - press Enter] 메시지가 표시될 수 있다.
위의 설명을 보면 좌원 관리를 위해 프로세스를 꺼버린다는 내용인데 간단하게 팬텀 프로세스 킬러를 끄면 됩니다.
https://www.youtube.com/watch?v=s2fYaRvMzk4
위 영상에서 끄는 방법을 설명해주는데 정리하면
개발자 옵션 -> 무선 디버깅 on
apt update
apt install android-tools
분할 디스플레이 하고나서
adb pair // 이 명령어를 통해 장치를 페어링
개발자 옵션 > 무선 디버깅 > 페어링 코드로 기기 페어링 선택 // 여기서 끄면 안됨
adb pair <ip 주소>:<포트번호>
페어링코드 입력 -> 이러면 페어링 성공
이후 맨 위의 IP 주소와 포트 클릭 후 복사
adb connect {ip 주소}:{포트번호} // 붙여넣기 -> 이러면 연결 성공
https://github.com/KitsunedFox/termux-monet // 아래는 여기에 있는 3가지 명령어
adb shell "/system/bin/device_config set_sync_disabled_for_tests persistent"
adb shell "/system/bin/device_config put activity_manager max_phantom_processes 2147483647"
adb shell settings put global settings_enable_monitor_phantom_procs false
위 3가지 명령어 입력
exit -> 끝
위 내용을 따라하면 팬텀 프로세스 킬러는 비활성화되고 이제 정상적으로 서버를 운용할 수 있습니다 :)