1. VM mobile_app.py 재실행 (systemd 방식)
# 1. 기존 실행 프로세스 정리
sudo systemctl stop brewgram-mobile.service || true
sudo systemctl stop brewgram-worker.service || true
pkill -f "uvicorn mobile_app:app" || true
pkill -f "uvicorn worker_api:app" || true

# 2. 최신 브랜치 가져오기 (✅ 브랜치 여기서 변경)
cd ~/Gen_for_SmallBusiness
git fetch origin
git switch main
git pull --ff-only origin main

# 3. 의존성 동기화
uv sync

# 4. systemd 서비스 파일 최신 반영
sudo install -m 644 infra/systemd/brewgram-mobile.service /etc/systemd/system/brewgram-mobile.service
sudo install -m 644 infra/systemd/brewgram-worker.service /etc/systemd/system/brewgram-worker.service
sudo systemctl daemon-reload

# 5. worker는 현재 openai_image 경로에서 불필요하므로 비활성화
sudo systemctl disable brewgram-worker.service
sudo systemctl reset-failed brewgram-worker.service

# 터널 주소 등록 이후
# 6. 모바일앱만 systemd로 실행
sudo systemctl enable brewgram-mobile.service
sudo systemctl restart brewgram-mobile.service

# 7. 상태 확인
sudo systemctl status brewgram-mobile.service --no-pager -l

# 8. 로그 실시간 확인
sudo journalctl -u brewgram-mobile.service -f

# 9. 도메인 확인
curl -I <https://brewgram.duckdns.org/stitch/manifest.webmanifest>
curl -sS <https://brewgram.duckdns.org/api/mobile/bootstrap> | head

# 10. 네트워크 일시 중단 후 VM에서 연결 확인
curl -sS <http://127.0.0.1:8011/api/mobile/bootstrap>
curl -sS <http://127.0.0.1:8011/api/mobile/bootstrap>

  1. Mac 캡처 워커, 터널 명령어 (+잠자기 방지)
# 1. SSH 키 인증 확인
ssh-add -l

	# The agent has no identities.가 나오면 키를 추가
	ssh-add ~/.ssh/brewgram_deploy
	
	# SSH 접속 테스트
	ssh brewgram
	
	# 권한 정리
	chmod 700 ~/.ssh
	chmod 600 ~/.ssh/config
	chmod 600 ~/.ssh/brewgram_deploy
	
	# 다시 테스트
	ssh brewgram

	# VM에 SSH 키 등록
	sudo install -d -m 700 -o spai0608 -g spai0608 /home/spai0608/.ssh

	echo 'ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIHVpxH42dS/nXZInfLS8cTgqBAU7tg/FGHRJVXfyIAIY github-actions-deploy' | sudo tee -a /home/spai0608/.ssh/authorized_keys
	
	sudo chown spai0608:spai0608 /home/spai0608/.ssh/authorized_keys
	sudo chmod 600 /home/spai0608/.ssh/authorized_keys
	sudo chmod 700 /home/spai0608/.ssh
	

# 2. Mac Instagram 캡처 워커 켜기
cd /Users/apple/Gen_for_SmallBusiness

CAPTURE_WORKER_TOKEN="+4rORPHHJQetGVww+qzxtFuSrV/538NwEwPuIWTAKKk=" \\
CAPTURE_WORKER_HEADLESS=1 \\
uv run uvicorn scripts.instagram_capture_worker:app --host 127.0.0.1 --port 8020

	# 정상 확인
	uvicorn running on <http://127.0.0.1:8020>
	
	
# 3. Cloudflare Tunnel 켜기 (다른 터미널)
cloudflared tunnel --url <http://127.0.0.1:8020>

	# 출력 중 이런 URL을 복사 <https://xxxx-xxxx-xxxx.trycloudflare.com>
	# VM env에 Tunnel URL 반영
		# 맥에서 SSH 접속
		ssh brewgram
		
		# VM 안에서
		sudo nano /etc/brewgram/mobile_app.env
		
		# 아래 값 수정
		INSTAGRAM_CAPTURE_WORKER_URL=https://xxxx-xxxx-xxxx.trycloudflare.com
		INSTAGRAM_CAPTURE_WORKER_TOKEN=+4rORPHHJQetGVww+qzxtFuSrV/538NwEwPuIWTAKKk=
		INSTAGRAM_CAPTURE_WORKER_TIMEOUT=90.0
		
		# 저장 후 VM 모바일앱 재시작
		sudo systemctl enable brewgram-mobile.service
		sudo systemctl restart brewgram-mobile.service
		# 확인
		sudo systemctl status brewgram-mobile.service --no-pager
		sudo journalctl -u brewgram-mobile.service -n 80 --no-pager
		curl -sS <https://brewgram.duckdns.org/health>
	
	
# 4. Mac 캡처 워커 테스트 (정상이면 ok 1)
curl -sS -X POST <http://127.0.0.1:8020/capture> \\
  -H "Authorization: Bearer +4rORPHHJQetGVww+qzxtFuSrV/538NwEwPuIWTAKKk=" \\
  -H "Content-Type: application/json" \\
  -d '{"url":"<https://www.instagram.com/unstuffy_cafe/","count>":1}' \\
  | python3 -c 'import sys,json; p=json.load(sys.stdin); print(p["status"], len(p["images"]))'

# 5. VM에서 터널 헬스체크
source /etc/brewgram/mobile_app.env
curl -fsS "${INSTAGRAM_CAPTURE_WORKER_URL%/}/health"
# 정상이면 {"ok":true,"headless":true,"profile_dir":"..."}

# 정리하면, 데모 중 자동 Instagram URL 캡처까지 쓸 거면 맥에서 계속 켜둘 터미널은 2개
# 1. Mac capture worker: uvicorn scripts.instagram_capture_worker:app --port 8020
# 2. Cloudflare Tunnel: cloudflared tunnel --url <http://127.0.0.1:8020>
# 이 둘은 맥북 잠자기/네트워크 끊김/터미널 종료 시 같이 끊김
# 데모 중 맥북 잠자기 방지를 하려면 이 터미널에서 아래만 켜두면 됩니다.
caffeinate -dimsu 

  1. VM DB 삭제 명령어
pkill -f "uvicorn mobile_app:app" || true

rm -f /srv/brewgram/data/history.db
rm -f /srv/brewgram/data/history.db-shm
rm -f /srv/brewgram/data/history.db-wal

ls -lah /srv/brewgram/data

# 삭제 후 systemd vm 재실행
cd ~/Gen_for_SmallBusiness

sudo systemctl stop brewgram-mobile.service

sudo rm -f /srv/brewgram/data/history.db
sudo rm -f /srv/brewgram/data/history.db-shm
sudo rm -f /srv/brewgram/data/history.db-wal

sudo systemctl start brewgram-mobile.service

sudo systemctl status brewgram-mobile.service --no-pager
curl -sS <http://127.0.0.1:8011/health>

  1. VM 실행 중 테이블 데이터 삭제
# 온보딩부터 다시
cp /srv/brewgram/data/history.db \\
  /srv/brewgram/data/history.db.backup-$(date +%Y%m%d-%H%M%S)

sqlite3 /srv/brewgram/data/history.db "
PRAGMA busy_timeout = 10000;
PRAGMA foreign_keys = ON;
BEGIN IMMEDIATE;
DELETE FROM generated_uploads;
DELETE FROM reference_images;
DELETE FROM generation_outputs;
DELETE FROM generations;
DELETE FROM instagram_connections;
DELETE FROM brands;
COMMIT;
VACUUM;
"

# 삭제 확인
sqlite3 /srv/brewgram/data/history.db "
SELECT 'brands', COUNT(*) FROM brands
UNION ALL SELECT 'instagram_connections', COUNT(*) FROM instagram_connections
UNION ALL SELECT 'generations', COUNT(*) FROM generations
UNION ALL SELECT 'generation_outputs', COUNT(*) FROM generation_outputs
UNION ALL SELECT 'generated_uploads', COUNT(*) FROM generated_uploads
UNION ALL SELECT 'reference_images', COUNT(*) FROM reference_images;
"

포트별로 보면 이렇게 정리하면 된다.