mirror of
https://github.com/coder/coder.git
synced 2026-06-02 20:48:20 +00:00
feat(scripts): add develop.sh port flag (#22961)
## Summary - add a `--port` flag to `scripts/develop.sh` so the API can run on a non-default port - make the script use the selected API port for access URL defaults, readiness checks, login, proxy wiring, and printed URLs - reject oversized `--port` values early and treat an existing dev frontend on port 8080 as a conflict when the requested API is not already running - pin the frontend dev server to port 8080 so inherited `PORT` environment variables do not move it to a different port ## Testing - `bash -n scripts/develop.sh` - `shellcheck -x scripts/develop.sh` - `bash scripts/develop.sh --port abc` - `bash scripts/develop.sh --port 8080` - `bash scripts/develop.sh --port 999999999999999999999` - started `./scripts/develop.sh --port 3001` and verified: - `http://127.0.0.1:3001/healthz` - `http://127.0.0.1:3001/api/v2/buildinfo` - `http://127.0.0.1:8080/healthz` - `http://127.0.0.1:8080/api/v2/buildinfo` - simulated an existing dev frontend on `127.0.0.1:8080` and verified `./scripts/develop.sh --port 3001` exits with a conflict error
This commit is contained in:
+67
-22
@@ -1,9 +1,10 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Usage: ./develop.sh [--agpl]
|
||||
# Usage: ./develop.sh [--agpl] [--port <port>]
|
||||
#
|
||||
# If the --agpl parameter is specified, builds only the AGPL-licensed code (no
|
||||
# Coder enterprise features).
|
||||
# Coder enterprise features). The --port parameter changes the API port. The
|
||||
# frontend dev server still listens on port 8080.
|
||||
|
||||
SCRIPT_DIR=$(dirname "${BASH_SOURCE[0]}")
|
||||
# shellcheck source=scripts/lib.sh
|
||||
@@ -13,7 +14,14 @@ source "${SCRIPT_DIR}/lib.sh"
|
||||
[[ -n ${VERBOSE:-} ]] && set -x
|
||||
set -euo pipefail
|
||||
|
||||
CODER_DEV_ACCESS_URL="${CODER_DEV_ACCESS_URL:-http://127.0.0.1:3000}"
|
||||
api_port=3000
|
||||
web_port=8080
|
||||
proxy_port=3010
|
||||
CODER_DEV_ACCESS_URL="${CODER_DEV_ACCESS_URL:-}"
|
||||
access_url_set=0
|
||||
if [ -n "${CODER_DEV_ACCESS_URL}" ]; then
|
||||
access_url_set=1
|
||||
fi
|
||||
DEVELOP_IN_CODER="${DEVELOP_IN_CODER:-0}"
|
||||
debug=0
|
||||
DEFAULT_PASSWORD="SomeSecurePassword!"
|
||||
@@ -26,12 +34,17 @@ multi_org=0
|
||||
unset CODER_SESSION_TOKEN
|
||||
unset CODER_URL
|
||||
|
||||
args="$(getopt -o "" -l access-url:,use-proxy,agpl,debug,password:,multi-organization -- "$@")"
|
||||
args="$(getopt -o "" -l access-url:,use-proxy,agpl,debug,password:,multi-organization,port: -- "$@")"
|
||||
eval set -- "$args"
|
||||
while true; do
|
||||
case "$1" in
|
||||
--access-url)
|
||||
CODER_DEV_ACCESS_URL="$2"
|
||||
access_url_set=1
|
||||
shift 2
|
||||
;;
|
||||
--port)
|
||||
api_port="$2"
|
||||
shift 2
|
||||
;;
|
||||
--agpl)
|
||||
@@ -72,28 +85,59 @@ if [ "${CODER_BUILD_AGPL:-0}" -gt "0" ] && [ "${multi_org}" -gt "0" ]; then
|
||||
echo '== ERROR: cannot use both multi-organizations and APGL build.' && exit 1
|
||||
fi
|
||||
|
||||
validate_port() {
|
||||
local port=$1
|
||||
local flag=$2
|
||||
|
||||
if ! [[ "${port}" =~ ^[0-9]+$ ]]; then
|
||||
error "${flag} must be an integer between 1 and 65535"
|
||||
fi
|
||||
if [ "${#port}" -gt 5 ]; then
|
||||
error "${flag} must be an integer between 1 and 65535"
|
||||
fi
|
||||
if ((10#${port} < 1 || 10#${port} > 65535)); then
|
||||
error "${flag} must be an integer between 1 and 65535"
|
||||
fi
|
||||
}
|
||||
|
||||
validate_port "${api_port}" "--port"
|
||||
if [ "${api_port}" -eq "${web_port}" ]; then
|
||||
error "--port cannot use ${web_port} because the frontend dev server uses that port"
|
||||
fi
|
||||
if [ "${use_proxy}" -gt "0" ] && [ "${api_port}" -eq "${proxy_port}" ]; then
|
||||
error "--port cannot use ${proxy_port} when --use-proxy is enabled because the workspace proxy uses that port"
|
||||
fi
|
||||
if [ "${access_url_set}" -eq 0 ]; then
|
||||
CODER_DEV_ACCESS_URL="http://127.0.0.1:${api_port}"
|
||||
fi
|
||||
|
||||
api_url="http://127.0.0.1:${api_port}"
|
||||
api_local_url="http://localhost:${api_port}"
|
||||
web_url="http://127.0.0.1:${web_port}"
|
||||
|
||||
if [ -n "${CODER_AGENT_URL:-}" ]; then
|
||||
DEVELOP_IN_CODER=1
|
||||
fi
|
||||
|
||||
# Preflight checks: ensure we have our required dependencies, and make sure nothing is listening on port 3000 or 8080
|
||||
# Preflight checks: ensure we have our required dependencies, and make sure
|
||||
# nothing is listening on the configured API or frontend ports.
|
||||
dependencies curl git go jq make pnpm
|
||||
|
||||
if curl --silent --fail http://127.0.0.1:3000; then
|
||||
if curl --silent --fail "${api_url}" >/dev/null 2>&1; then
|
||||
# Check if this is the Coder development server.
|
||||
if curl --silent --fail http://127.0.0.1:3000/api/v2/buildinfo 2>&1 | jq -r '.version' >/dev/null 2>&1; then
|
||||
echo '== INFO: Coder development server is already running on port 3000!' && exit 0
|
||||
if curl --silent --fail "${api_url}/api/v2/buildinfo" 2>&1 | jq -r '.version' >/dev/null 2>&1; then
|
||||
echo "== INFO: Coder development server is already running on port ${api_port}!" && exit 0
|
||||
else
|
||||
echo '== ERROR: something is listening on port 3000. Kill it and re-run this script.' && exit 1
|
||||
echo "== ERROR: something is listening on port ${api_port}. Kill it and re-run this script." && exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
if curl --fail http://127.0.0.1:8080 >/dev/null 2>&1; then
|
||||
if curl --fail "${web_url}" >/dev/null 2>&1; then
|
||||
# Check if this is the Coder development frontend.
|
||||
if curl --silent --fail http://127.0.0.1:8080/api/v2/buildinfo 2>&1 | jq -r '.version' >/dev/null 2>&1; then
|
||||
echo '== INFO: Coder development frontend is already running on port 8080!' && exit 0
|
||||
if curl --silent --fail "${web_url}/api/v2/buildinfo" 2>&1 | jq -r '.version' >/dev/null 2>&1; then
|
||||
echo "== ERROR: Coder development frontend is already running on port ${web_port}, but the requested API on port ${api_port} is not already running. Stop the frontend and re-run this script." && exit 1
|
||||
else
|
||||
echo '== ERROR: something is listening on port 8080. Kill it and re-run this script.' && exit 1
|
||||
echo "== ERROR: something is listening on port ${web_port}. Kill it and re-run this script." && exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
@@ -176,12 +220,12 @@ fatal() {
|
||||
trap 'fatal "Script encountered an error"' ERR
|
||||
|
||||
cdroot
|
||||
DEBUG_DELVE="${debug}" DEVELOP_IN_CODER="${DEVELOP_IN_CODER}" start_cmd API "" "${CODER_DEV_SHIM}" server --http-address 0.0.0.0:3000 --swagger-enable --access-url "${CODER_DEV_ACCESS_URL}" --dangerous-allow-cors-requests=true --enable-terraform-debug-mode "$@"
|
||||
DEBUG_DELVE="${debug}" DEVELOP_IN_CODER="${DEVELOP_IN_CODER}" start_cmd API "" "${CODER_DEV_SHIM}" server --http-address "0.0.0.0:${api_port}" --swagger-enable --access-url "${CODER_DEV_ACCESS_URL}" --dangerous-allow-cors-requests=true --enable-terraform-debug-mode "$@"
|
||||
|
||||
echo '== Waiting for Coder to become ready'
|
||||
# Start the timeout in the background so interrupting this script
|
||||
# doesn't hang for 60s.
|
||||
timeout 60s bash -c 'until curl -s --fail http://localhost:3000/healthz > /dev/null 2>&1; do sleep 0.5; done' ||
|
||||
timeout 60s bash -c "until curl -s --fail ${api_local_url}/healthz > /dev/null 2>&1; do sleep 0.5; done" ||
|
||||
fatal 'Coder did not become ready in time' &
|
||||
wait $!
|
||||
|
||||
@@ -192,7 +236,7 @@ fatal() {
|
||||
# Try to create the initial admin user.
|
||||
echo "Login required; use admin@coder.com and password '${password}'" >&2
|
||||
|
||||
if "${CODER_DEV_SHIM}" login http://127.0.0.1:3000 --first-user-username=admin --first-user-email=admin@coder.com --first-user-password="${password}" --first-user-full-name="Admin User" --first-user-trial=false; then
|
||||
if "${CODER_DEV_SHIM}" login "${api_url}" --first-user-username=admin --first-user-email=admin@coder.com --first-user-password="${password}" --first-user-full-name="Admin User" --first-user-trial=false; then
|
||||
# Only create this file if an admin user was successfully
|
||||
# created, otherwise we won't retry on a later attempt.
|
||||
touch "${PROJECT_ROOT}/.coderv2/developsh-did-first-setup"
|
||||
@@ -266,12 +310,13 @@ fatal() {
|
||||
# Create the proxy
|
||||
proxy_session_token=$("${CODER_DEV_SHIM}" wsproxy create --name=local-proxy --display-name="Local Proxy" --icon="/emojis/1f4bb.png" --only-token)
|
||||
# Start the proxy
|
||||
start_cmd PROXY "" "${CODER_DEV_SHIM}" wsproxy server --dangerous-allow-cors-requests=true --http-address=localhost:3010 --proxy-session-token="${proxy_session_token}" --primary-access-url=http://localhost:3000
|
||||
start_cmd PROXY "" "${CODER_DEV_SHIM}" wsproxy server --dangerous-allow-cors-requests=true --http-address="localhost:${proxy_port}" --proxy-session-token="${proxy_session_token}" --primary-access-url="${api_local_url}"
|
||||
) || echo "Failed to create workspace proxy. No workspace proxy created."
|
||||
fi
|
||||
|
||||
# Start the frontend once we have a template up and running
|
||||
CODER_HOST=http://127.0.0.1:3000 start_cmd SITE date pnpm --dir ./site dev --host
|
||||
# Start the frontend once we have a template up and running. We pin the
|
||||
# port because some environments export PORT for unrelated services.
|
||||
PORT="${web_port}" CODER_HOST="${api_url}" start_cmd SITE date pnpm --dir ./site dev --host
|
||||
|
||||
interfaces=(localhost)
|
||||
if command -v ip >/dev/null; then
|
||||
@@ -289,14 +334,14 @@ fatal() {
|
||||
log "== =="
|
||||
log "== Coder is now running in development mode. =="
|
||||
for iface in "${interfaces[@]}"; do
|
||||
log "$(printf "== API: http://%s:3000%$((space_padding - ${#iface}))s==" "$iface" "")"
|
||||
log "$(printf "== API: http://%s:${api_port}%$((space_padding - ${#iface}))s==" "$iface" "")"
|
||||
done
|
||||
for iface in "${interfaces[@]}"; do
|
||||
log "$(printf "== Web UI: http://%s:8080%$((space_padding - ${#iface}))s==" "$iface" "")"
|
||||
log "$(printf "== Web UI: http://%s:${web_port}%$((space_padding - ${#iface}))s==" "$iface" "")"
|
||||
done
|
||||
if [ "${use_proxy}" -gt "0" ]; then
|
||||
for iface in "${interfaces[@]}"; do
|
||||
log "$(printf "== Proxy: http://%s:3010%$((space_padding - ${#iface}))s==" "$iface" "")"
|
||||
log "$(printf "== Proxy: http://%s:${proxy_port}%$((space_padding - ${#iface}))s==" "$iface" "")"
|
||||
done
|
||||
fi
|
||||
log "== =="
|
||||
|
||||
Reference in New Issue
Block a user