[DRAFT] 휴대폰으로 알람을 보내보자 - ntfy
너무 오래 앉아있는 현대인을 일어나게 하라.
현대인 대부분은 사무실 의자에 앉아서 9시간 이상을 보낸다. 이 때 더욱 심각한 문제는 컴퓨터 모니터를 들여다보고 있다보면 한 시간이 훌쩍 지나도록 시간가는 줄 모른다는 것이다. 이런 생활 습관은 내 허리와 눈 건강에 지대한 악영향을 미칠 것이 자명하다. (실제 요즘 시력이 조금씩 떨어지고 있다…)
이 문제를 해결해 보고자 일명 구글 타이머도 구매하여 사용해보았지만, 여러 사람이 함께 쓰는 사무실에서 소리로 알람을 울리는 방식은 굉장한 민폐가 아닐 수 없다. 그렇다고 소리를 끄고 쓰면 잘 사용하지 않게 된다.
아… 어떡하나?
어떻게 해야 시간가는 줄 모르고 앉아있을 나의 옆구리를 쿡 찔러서, 잠시 몸을 풀 시간을 갖도록 만들 수 있을까?
고민을 하던 찰나, 우연히 ntfy라는 오픈소스 프로젝트를 알게 되었다. 그럼 같이 ntfy에 대해 알아보도록 하자.
ntfy는 무엇인가?
ntfy (pronounced notify) is a simple HTTP-based pub-sub notification service. It allows you to send notifications to your phone or desktop via scripts from any computer, and/or using a REST API. It’s infinitely flexible, and 100% free software.
ntfy는 터미널 명령어를 통해 전송된(published) 메시지들을 수신하고, 그 메시지를 구독(subscribe)하고 있는 클라이언트들에게 알람으로써 전달해주는 서비스다.
graph LR
A(("Publisher"))
B["ntfy<br>server"]
C(("Client<br>아이폰"))
D(("Client<br>데스크톱"))
A e0@-->|메시지 생성 및 전달| B e1@-->|메시지| C
B e2@-->|메시지|D
e0@{ animate: true }
e1@{ animate: true }
e2@{ animate: true }
슬쩍 보면 별 기능이 아닌 것처럼 보인다. 그러나, 쉘 스크립트와 crontab을 함께 잘 활용한다면, 메시지 보내는 원하는 대로 자동화할 수 있다. 또한, 메시지를 수신할 수 있는 클라이언트로 pc뿐만 아니라 안드로이드, 아이폰 모두를 사용할 수 있고, 클라이언트의 개수에도 제한이 없다.
자, 이제 ntfy가 뭔지 알았으니 실제 ntfy를 사용법을 알아보도록 하자.
구축하려는 환경
우리가 구축하려는 환경은 다음과 같다.
graph LR
A["Publisher"]
B["ntfy<br>server"]
C(("Client<br>아이폰"))
D(("Client<br>데스크톱"))
E(("Client<br>안드로이드"))
subgraph Any desktop
A
end
subgraph server
B
end
A e0@-->|메시지 생성 및 전달| B e1@-->|메시지| C
B e2@-->|메시지|D
B e3@-->|메시지|E
e0@{ animate: true }
e1@{ animate: true }
e2@{ animate: true }
e3@{ animate: true }
준비물
ntfy 환경 구축에 필요한 준비물은 1)서버와 2)개인 도메인이다. 개인 도메인은 메시지 수신을 위해 반드시 필요하다.
Tailscale을 사용한다면, 개인 도메인이 없더라도 tailscale funnel을 사용하여 공개하는 것도 가능하다! Tailscale 기본 사용법 포스트가 있으니 참고하시길.
ntfy 환경 구축하기
이번 포스팅에서는 proxmox 대신, 도커를 활용하기로 한다.
docker와 docker-compose 설치하기
본 포스팅에선 docker와 docker-compose가 설치되어 있고, 그 사용법에 익숙하다는 것을 전제로 한다. 이들의 절차는 arch wiki를 참고하자.
ntfy를 위한 폴더 준비하기
ntfy 파일들이 저장될 경로를 하나 준비해주자.
필자는 ~/ntfy로 준비했다.
docker-compose.yml 파일 작성하기
docker compose로 환경 구축을 위해 docker-compose.yml을 다음처럼 작성해주자.
작성 내용은 필요에 따라 ntfy의 공식 가이드를 참고하여 커스텀해주자.
필자는 다음과 같은 옵션을 포함하였다.
- 개인 도메인으로 연결
- 계정 인증된 사용자만 subscribe 가능하도록 설정
- 아이폰에서 메시지 수신 가능하도록 설정
services:
ntfy:
image: docker.io/binwiederhier/ntfy
restart: unless-stopped
environment:
NTFY_BASE_URL: https://ntfy.mydomain.com # 이 부분을 개인 도메인으로 바꾸면 된다. subdomain은 ntfy가 아니어도 된다.
NTFY_CACHE_FILE: /var/lib/ntfy/cache.db
NTFY_AUTH_FILE: /var/lib/ntfy/auth.db
NTFY_AUTH_DEFAULT_ACCESS: deny-all
NTFY_BEHIND_PROXY: true
NTFY_ATTACHMENT_CACHE_DIR: /var/lib/ntfy/attachments
NTFY_ENABLE_LOGIN: true
NTFY_UPSTREAM_BASE_URL: https://ntfy.sh # 아이폰으로 메시지 수신을 위해선 이 경로도 설정해줘야 한다. 필요없다면 이 줄은 제거하자.
volumes:
- ./:/var/lib/ntfy # docker-compose.yml이 있는 경로를 ntfy 시스템 파일들의 저장소로 연결
ports:
- 4080:80 # 좌측이 host의 포트, 우측이 도커 내부의 포트다. 필자는 호스트의 4080 포트를 ntfy의 80번 포트와 연결해주었다.
command: servedocker compose run 하기
도커파일 작성이 완료되었다면, docker-compose.yml 파일이 있는 경로에서 다음의 명령어를 입력하여 ntfy 서버를 작동해보자.
docker compose up -d에러가 뜬다면, docker-compose.yml 작성에 오류가 있는 것이니 잘 보고 오류를 해결해주자.
localhost:4080 접속 가능 여부 확인
정상적으로 docker compose가 이뤄졌다면, localhost:4080으로 접속이 잘 되는지 확인해보자.
필자는 다음처럼 ntfy 페이지가 잘 표시되었다.
authentication 작동 여부 확인
앞서 docker-compose.yml에서 아이디와 비밀번호를 통해 인증을 하도록 설정했었다.
실제 의도대로 동작하는지 다음의 그림처럼 subscribe를 시도하여 확인해보자.
계정 생성하기
내가 사용할 계정을 만들어보자. 이를 위해 먼저 우리가 만든 ntfy 컨테이너 내부로 sh 연결을 해줘야 한다.
docker exec -it ntfy sh # ntfy는 우리가 만든 컨테이너 이름이고, 연결할 쉘은 sh이다.그러면 다음처럼 터미널의 prompt가 / #으로 바뀐 것을 알 수 있다.
우리는 지금 컨테이너 내부에 들어와있다.
[will@archbox ntfy]$ docker exec -it ntfy sh
/ #본 포스팅에서는 관리자 계정 하나만 만든다. 이후 필요하다면 사용자 계정을 추가하면 된다.
다음 명령어로 관리자 계정을 만들어준다. 입력하면 password까지 설정할 수 있다.
ntfy user add --role=admin will # 관리자 will 추가, 원하는 이름으로 생성계정 로그인 가능 여부 확인하기
계정을 추가했으니, localhost:4080에 다시 접속하여 로그인 가능 여부를 확인해주자.
로그인이 잘된다면 다음으로 넘어가자.
DNS record 및 reverse proxy 등록
자, 로컬에서 잘 동작하는 것을 확인하였으니 이어서 ntfy에 ntfy.mydomain.com으로 subdomain 주소를 부여해주자.
이 작업의 핵심은 localhost:4080을 ntfy.mydomain.com에 연결해주는 것이다.
이 부분도 굉장히 복잡하여 본 포스팅의 범위를 넘어선다. 자세한 내용은 구글링을 통해 수행하길 바란다.
연결된 ntfy 주소로 접속하고 로그인하기
DNS record 등록과 reverse proxy 등록이 잘 되었다면, ntfy 주소로 접속해보자. 다음처럼 접속이 잘되는 것을 확인하면 된다. 접속이 잘되면 로그인까지 진행해주자.
topic 구독하고 메시지 테스트하기
ntfy는 topic이라는 단위로 수집하는 메시지들을 구분짓고 있다. 나는 personal, server로 topic을 구분하여 수신하고 있다.
예시로써 다음처럼 personal이라는 topic을 구독(subscribe)해보자.
구독이 된 주제는 좌측 Subscribed topics에 뜨게된다.
이어서, 구독한 personal topic 페이지로 가서 테스트 메시지를 보내보자. 1-3번의 순서로 진행하면 된다.
테스트 메시지가 잘 수신되는 것을 알 수 있다.
이어서 terminal에서도 다음의 명령어를 통해 테스트 메시지를 테스트해보자. 터미널에서는 curl을 사용하여 다음처럼 메시지를 보낼 수 있다.
이때 유의할 점이 몇 가지 있다.
- pw/id를 사용하도록 설정한 경우, 메시지를 보낼 때 그 인증정보를 붙여서 보내야 한다. (-u id:pw 옵션을 사용)
- 특정 토픽으로 보내기 위해 ntfy의 주소 뒤에
/topic을 붙여준다. 여기선/personal을 붙여주었다. - 메시지는
-d "메시지"옵션으로 작성해준다.
curl -u will:1234 -d "테스트 메시지 from terminal" https://ntfy.mydomain/personal그러면 이런 출력이 나오면서 메시지가 웹 상에 나타난다.
[will@archbox ntfy]$ curl -u will:1234 -d "테스트 메시지 from terminal" https://ntfy.mydomain.com/personal
{"id":"5Z8FWYtKIYeQ","time":1772193126,"expires":1772236326,"event":"message","topic":"personal","message":"테스트 메시지 from terminal"}