feat: support PORT env var for listen address

Clap now reads PORT from the environment, accepting either a bare port
number (e.g. 8080 -> 0.0.0.0:8080) or a full host:port. CLI --listen
flag still takes precedence. Deploy Dockerfile defaults PORT=9500 and
removes the hardcoded --listen argument.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Alan Kahn 2026-03-03 12:25:58 -05:00
parent 16214ebfcb
commit dd6c709cbe
3 changed files with 19 additions and 4 deletions

View File

@ -25,7 +25,8 @@ USER tidal:tidal
WORKDIR /data
EXPOSE 9500
HEALTHCHECK --interval=30s --timeout=3s --start-period=10s --retries=3 \
CMD curl -sf http://localhost:9500/health || exit 1
CMD curl -sf http://localhost:${PORT:-9500}/health || exit 1
ENV TIDAL_SERVER_LOG=info
ENV PORT=9500
ENTRYPOINT ["/usr/local/bin/tidal-server"]
CMD ["standalone", "--listen", "0.0.0.0:9500", "--schema", "/config/schema.yaml", "--data-dir", "/data"]
CMD ["standalone", "--schema", "/config/schema.yaml", "--data-dir", "/data"]

View File

@ -11,7 +11,7 @@ path = "src/lib.rs"
[dependencies]
axum = "0.8"
clap = { version = "4.5", features = ["derive"] }
clap = { version = "4.5", features = ["derive", "env"] }
subtle = "2"
tower = { version = "0.5", features = ["limit"] }
tower-http = { version = "0.6", features = ["timeout", "trace", "request-id"] }

View File

@ -24,7 +24,7 @@ enum Command {
#[derive(Args)]
struct StandaloneArgs {
#[arg(long, default_value = "127.0.0.1:9400")]
#[arg(long, default_value = "127.0.0.1:9400", env = "PORT", value_parser = parse_listen_addr)]
listen: String,
#[arg(long)]
schema: Option<PathBuf>,
@ -54,6 +54,20 @@ async fn run() -> Result<()> {
}
}
/// Parse a listen address from either a full `host:port` string or a bare port number.
/// When `PORT=8080` is set, clap passes `"8080"` — this normalises it to `0.0.0.0:8080`.
fn parse_listen_addr(s: &str) -> std::result::Result<String, String> {
if s.contains(':') {
s.parse::<SocketAddr>()
.map(|_| s.to_string())
.map_err(|e| format!("invalid address '{s}': {e}"))
} else {
s.parse::<u16>()
.map(|port| format!("0.0.0.0:{port}"))
.map_err(|_| format!("expected host:port or port number, got '{s}'"))
}
}
fn init_tracing() {
let env_filter = std::env::var("TIDAL_SERVER_LOG").unwrap_or_else(|_| "info".into());
let _ = tracing_subscriber::fmt()