fix: use fixed port 3010 for production postgrest, remove dynamic allocation
Dynamic port leasing was the root cause of all the "address already in use" failures. Production now always uses 3010; dev still uses 3001. No more .postgrest-port file, no more port scanning loop, no more race conditions. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
+24
-67
@@ -29,77 +29,36 @@ jobs:
|
||||
APP_DIR=/home/tyler/route-commerce
|
||||
mkdir -p $APP_DIR
|
||||
|
||||
# Free the dev-stack port (3001) and the port the previous deploy used
|
||||
# (so a new deploy can pick it back up if it's the lowest free port)
|
||||
PREV_PORT=$(cat .postgrest-port 2>/dev/null || echo "")
|
||||
for port in 3001 $PREV_PORT; do
|
||||
if [ -n "$port" ] && ss -tln 2>/dev/null | grep -qE "[[:space:]]127\.0\.0\.1:${port}[[:space:]]"; then
|
||||
echo "Port $port in use, freeing..."
|
||||
fuser -k -9 $port/tcp 2>/dev/null || true
|
||||
docker ps -aq --filter "publish=$port" 2>/dev/null | xargs -r docker rm -f 2>/dev/null || true
|
||||
fi
|
||||
done
|
||||
# Production postgrest always owns port 3010. No dynamic allocation.
|
||||
POSTGREST_HOST_PORT=3010
|
||||
export NEXT_PUBLIC_API_URL="http://localhost:$POSTGREST_HOST_PORT"
|
||||
|
||||
# Hard-stop the previous stack by name — works even if docker-compose.yml
|
||||
# is missing or stale from a prior failed deploy.
|
||||
# Note: multiple --filter name= flags are ANDed; use two separate calls.
|
||||
# Tear down previous stack: kill containers by name (two separate calls
|
||||
# because multiple --filter name= flags are ANDed, not ORed).
|
||||
{
|
||||
docker ps -aq --filter "name=route_commerce_"
|
||||
docker ps -aq --filter "name=route-commerce-"
|
||||
} | sort -u | xargs -r docker rm -f
|
||||
# Network can only be removed after all containers are detached.
|
||||
} | sort -u | xargs -r docker rm -f || true
|
||||
# Remove network after containers are gone so Docker allocates a fresh subnet.
|
||||
docker network rm route-commerce_default 2>/dev/null || true
|
||||
sleep 2
|
||||
|
||||
# Verify all route-commerce containers are gone before picking a port.
|
||||
REMAINING=$({ docker ps -aq --filter "name=route_commerce_"; docker ps -aq --filter "name=route-commerce-"; } | sort -u | wc -l)
|
||||
if [ "$REMAINING" -gt 0 ]; then
|
||||
echo "ERROR: $REMAINING route-commerce container(s) still running after teardown"
|
||||
docker ps --filter "name=route_commerce_"
|
||||
docker ps --filter "name=route-commerce-"
|
||||
exit 1
|
||||
fi
|
||||
# Write fresh .env for docker compose
|
||||
cp docker-compose.yml $APP_DIR/docker-compose.yml
|
||||
cat > $APP_DIR/.env <<EOF
|
||||
POSTGRES_USER=${POSTGRES_USER}
|
||||
POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
|
||||
POSTGRES_DB=${POSTGRES_DB}
|
||||
MINIO_ROOT_USER=${MINIO_ROOT_USER}
|
||||
MINIO_ROOT_PASSWORD=${MINIO_ROOT_PASSWORD}
|
||||
POSTGREST_JWT_SECRET=${POSTGREST_JWT_SECRET}
|
||||
POSTGREST_HOST_PORT=${POSTGREST_HOST_PORT}
|
||||
NEXT_PUBLIC_API_URL=${NEXT_PUBLIC_API_URL}
|
||||
EOF
|
||||
|
||||
# Find the first free host port starting from 3011. Persist the choice
|
||||
# so the Build and Deploy steps below can use the same URL.
|
||||
POSTGREST_HOST_PORT=3011
|
||||
for attempt in 1 2 3 4 5 6 7 8 9 10; do
|
||||
if ! ss -tln 2>/dev/null | grep -qE "[[:space:]]127\.0\.0\.1:${POSTGREST_HOST_PORT}[[:space:]]"; then
|
||||
break
|
||||
fi
|
||||
echo "Port $POSTGREST_HOST_PORT in use, trying next... (attempt $attempt)"
|
||||
POSTGREST_HOST_PORT=$((POSTGREST_HOST_PORT + 1))
|
||||
if [ $POSTGREST_HOST_PORT -gt 30200 ]; then
|
||||
echo "ERROR: no free port in 3011-30200 range"
|
||||
exit 1
|
||||
fi
|
||||
sleep 1
|
||||
done
|
||||
echo "Using PostgREST host port: $POSTGREST_HOST_PORT"
|
||||
echo "$POSTGREST_HOST_PORT" > .postgrest-port
|
||||
export NEXT_PUBLIC_API_URL="http://localhost:$POSTGREST_HOST_PORT"
|
||||
export POSTGREST_HOST_PORT
|
||||
|
||||
# Seed config files into APP_DIR if missing (they live in the repo, not in APP_DIR)
|
||||
[ -f $APP_DIR/.env.example ] || cp .env.example $APP_DIR/.env.example
|
||||
[ -f $APP_DIR/docker-compose.yml ] || cp docker-compose.yml $APP_DIR/docker-compose.yml
|
||||
cd $APP_DIR
|
||||
[ -f .env ] || cp .env.example .env
|
||||
# Append production secrets to .env (overriding .env.example defaults)
|
||||
{
|
||||
echo "POSTGRES_USER=${POSTGRES_USER}"
|
||||
echo "POSTGRES_PASSWORD=${POSTGRES_PASSWORD}"
|
||||
echo "POSTGRES_DB=${POSTGRES_DB}"
|
||||
echo "MINIO_ROOT_USER=${MINIO_ROOT_USER}"
|
||||
echo "MINIO_ROOT_PASSWORD=${MINIO_ROOT_PASSWORD}"
|
||||
echo "POSTGREST_JWT_SECRET=${POSTGREST_JWT_SECRET}"
|
||||
echo "POSTGREST_HOST_PORT=$POSTGREST_HOST_PORT"
|
||||
echo "NEXT_PUBLIC_API_URL=$NEXT_PUBLIC_API_URL"
|
||||
} >> .env
|
||||
# Bring the stack up fresh — --force-recreate ensures no stale
|
||||
# network/container references from prior failed attempts
|
||||
docker compose up -d --force-recreate db postgrest minio minio_init
|
||||
# Wait for Postgres healthcheck
|
||||
docker compose up -d db postgrest minio
|
||||
|
||||
# Wait for Postgres
|
||||
for i in $(seq 1 30); do
|
||||
if docker compose exec -T db pg_isready -U "${POSTGRES_USER}" -d "${POSTGRES_DB}" > /dev/null 2>&1; then
|
||||
echo "Postgres is ready"
|
||||
@@ -152,8 +111,7 @@ jobs:
|
||||
MINIMAX_BASE_URL: ${{ secrets.MINIMAX_BASE_URL }}
|
||||
FROM_EMAIL: ${{ secrets.FROM_EMAIL }}
|
||||
run: |
|
||||
POSTGREST_HOST_PORT=$(cat .postgrest-port)
|
||||
export NEXT_PUBLIC_API_URL="http://localhost:$POSTGREST_HOST_PORT"
|
||||
export NEXT_PUBLIC_API_URL="http://localhost:3010"
|
||||
npm run build
|
||||
|
||||
- name: Deploy
|
||||
@@ -191,8 +149,7 @@ jobs:
|
||||
run: |
|
||||
APP_DIR=/home/tyler/route-commerce
|
||||
mkdir -p $APP_DIR
|
||||
# Use the port chosen by Start Docker stack (persisted to .postgrest-port)
|
||||
POSTGREST_HOST_PORT=$(cat .postgrest-port)
|
||||
POSTGREST_HOST_PORT=3010
|
||||
export NEXT_PUBLIC_API_URL="http://localhost:$POSTGREST_HOST_PORT"
|
||||
|
||||
# Write env file from secrets (preserves existing .env for docker compose)
|
||||
|
||||
+1
-1
@@ -36,7 +36,7 @@ services:
|
||||
PGRST_OPENAPI_MODE: disabled
|
||||
PGRST_DB_EXTRA_SEARCH_PATH: public,extensions
|
||||
ports:
|
||||
- "127.0.0.1:${POSTGREST_HOST_PORT:-3011}:3001"
|
||||
- "127.0.0.1:${POSTGREST_HOST_PORT:-3010}:3001"
|
||||
|
||||
minio:
|
||||
image: minio/minio:latest
|
||||
|
||||
Reference in New Issue
Block a user