Skip to content

Commit 687eb04

Browse files
JihaoXinclaude
andcommitted
Auto-detect primary IP for webapp BASE_URL
socket.gethostname() returns "mcnode15" which resolves to 127.0.1.1 on the host itself and is not in every user's /etc/hosts. Replace with a get_primary_ip() helper that asks the kernel which interface routes outbound traffic — works on any machine without config. Also bump webpage submodule: mcnode15 → 172.18.0.26 in static links. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent b67177a commit 687eb04

File tree

4 files changed

+26
-9
lines changed

4 files changed

+26
-9
lines changed

ark/cli.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3067,7 +3067,8 @@ def _check_linger():
30673067
def _cmd_webapp_install(host: str, port: int, dev: bool = False):
30683068
"""Install and start ARK webapp as a systemd user service."""
30693069
import subprocess as _sp
3070-
import socket as _socket
3070+
3071+
from ark.paths import get_primary_ip
30713072

30723073
# Shared data directory for both dev and prod
30733074
data_dir = get_ark_root() / ".ark" / "data"
@@ -3111,15 +3112,14 @@ def _cmd_webapp_install(host: str, port: int, dev: bool = False):
31113112
prod_env_link.symlink_to(main_env)
31123113

31133114
# Environment variables for systemd service
3114-
hostname = _socket.gethostname()
31153115
env_vars = {
31163116
"ARK_WEBAPP_DB_PATH": str(db_path),
31173117
"PROJECTS_ROOT": str(data_dir / "projects"),
31183118
}
31193119

31203120
if dev:
31213121
env_vars["ARK_SESSION_COOKIE"] = "session_dev"
3122-
env_vars["BASE_URL"] = f"http://{hostname}:{port}"
3122+
env_vars["BASE_URL"] = f"http://{get_primary_ip()}:{port}"
31233123
# Load dev-only env overrides
31243124
dev_env_file = get_config_dir() / "webapp-dev.env"
31253125
if not dev_env_file.exists():

ark/paths.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,3 +33,21 @@ def get_config_dir() -> Path:
3333
d = get_ark_root() / ".ark"
3434
d.mkdir(exist_ok=True)
3535
return d
36+
37+
38+
def get_primary_ip() -> str:
39+
"""Return the IP of the interface that routes outbound traffic.
40+
41+
Uses socket.connect() on a UDP socket — no packet is sent, but the kernel
42+
resolves the source IP for the route to 8.8.8.8. More reliable than
43+
socket.gethostname() on hosts where the hostname resolves to 127.0.1.1.
44+
"""
45+
import socket
46+
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
47+
try:
48+
s.connect(("8.8.8.8", 80))
49+
return s.getsockname()[0]
50+
except Exception:
51+
return socket.gethostname()
52+
finally:
53+
s.close()

ark/webapp/config.py

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,16 @@
44

55
import os
66
import secrets
7-
import socket
87
from pathlib import Path
98

10-
from ark.paths import get_ark_root, get_config_dir
9+
from ark.paths import get_ark_root, get_config_dir, get_primary_ip
1110

1211

1312
def _env_file() -> Path:
1413
return get_config_dir() / "webapp.env"
1514

1615
_DEFAULTS = {
17-
"BASE_URL": f"http://{socket.gethostname()}:9527",
16+
"BASE_URL": f"http://{get_primary_ip()}:9527",
1817
"EMAIL_DOMAINS": "",
1918
"SMTP_HOST": "smtp.gmail.com",
2019
"SMTP_PORT": "587",
@@ -53,14 +52,14 @@ def _load_env_file() -> dict[str, str]:
5352

5453
def _write_default_env():
5554
"""Create .ark/webapp.env with placeholder values on first run."""
56-
hostname = socket.gethostname()
55+
ip = get_primary_ip()
5756
_root = get_ark_root()
5857
_config_dir = get_config_dir()
5958
content = f"""\
6059
# ARK Web App configuration
6160
# Edit this file, then restart: ark webapp
6261
63-
BASE_URL=http://{hostname}:9527
62+
BASE_URL=http://{ip}:9527
6463
6564
# SMTP — required for magic link login
6665
SMTP_HOST=smtp.gmail.com

0 commit comments

Comments
 (0)