Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/tidy-pugs-clap.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@repo/docs": patch
---

Fix the dynamic-config installer writing a bind address into `APP_PORT`, which broke Coolify on restart with `strconv.ParseUint: parsing "0.0.0.0:3000": invalid syntax`. `APP_PORT` is now a plain port number (default `3000`), user input is validated, and port `8000` is rejected since it is reserved for the Traefik dashboard entrypoint.
3 changes: 2 additions & 1 deletion apps/docs/.cspell.json
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@
"armv",
"libc",
"nextjs",
"twimg"
"twimg",
"strconv"
]
}
11 changes: 9 additions & 2 deletions apps/docs/content/docs/style/installation/dynamic-config.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,16 @@ The steps below show how to do the same changes manually.
Edit `/data/coolify/source/.env` and set Coolify's dashboard port to `3000` so the dashboard stays reachable even if Traefik is down:

```
APP_PORT=0.0.0.0:3000
APP_PORT=3000
```

<Callout type="warn">
`APP_PORT` must be a plain port number. Coolify's compose also uses it in
`expose:`, which rejects a bind address, so a value like `0.0.0.0:3000` makes
the restart fail with `strconv.ParseUint: parsing "0.0.0.0:3000": invalid
syntax`.
</Callout>

### 2. Update Traefik Compose

Edit `/data/coolify/proxy/docker-compose.yml`.
Expand Down Expand Up @@ -203,7 +210,7 @@ More information about custom themes can be found in the [Theming](/docs/style/t
To revert:

1. Delete `/data/coolify/proxy/dynamic/coolify-tweaks.yml`
2. Reset `APP_PORT` in `/data/coolify/source/.env` to your previous value (default Coolify uses `0.0.0.0:8000`).
2. Reset `APP_PORT` in `/data/coolify/source/.env` to your previous value (default Coolify uses `8000`).
3. Remove:

```yaml
Expand Down
71 changes: 67 additions & 4 deletions apps/docs/public/scripts/install/dynamic-config.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
## Do not modify this file. You will lose the ability to install!
##
## Environment variables that can be set:
## APP_PORT_DEFAULT - Default bind address for Coolify dashboard (default: 0.0.0.0:3000)
## APP_PORT_DEFAULT - Default host port for the Coolify dashboard (default: 3000)
## COOLIFY_TWEAKS_CSS_URL - Override the Tweaks CSS URL
## SKIP_BACKUP - Set to "true" to skip backup of docker-compose, and .env

Expand All @@ -22,7 +22,8 @@ DYNAMIC_DIR="$PROXY_DIR/dynamic"
COMPOSE_FILE="$PROXY_DIR/docker-compose.yml"
CURRENT_USER=$USER

APP_PORT_DEFAULT="${APP_PORT_DEFAULT:-0.0.0.0:3000}"
APP_PORT_DEFAULT="${APP_PORT_DEFAULT:-3000}"
TRAEFIK_DASHBOARD_PORT="8000"
SKIP_BACKUP="${SKIP_BACKUP:-${1:-false}}"

COOLIFY_TWEAKS_DEFAULT_CSS_URL="https://coolify-tweaks-api.techwithanirudh.com/release/latest/?asset=main.css"
Expand Down Expand Up @@ -91,6 +92,20 @@ getAJoke() {
fi
}

# Coolify's compose uses APP_PORT in both `ports:` and `expose:`. `expose:`
# only accepts a bare port number, so anything like "0.0.0.0:3000" makes
# docker compose fail with: strconv.ParseUint: parsing "0.0.0.0:3000".
strip_bind_address() {
printf '%s' "${1##*:}"
}

is_valid_port() {
case "$1" in
'' | *[!0-9]*) return 1 ;;
esac
[ "$1" -ge 1 ] && [ "$1" -le 65535 ]
}

update_env_var() {
local key="$1"
local value="$2"
Expand Down Expand Up @@ -181,8 +196,56 @@ else
echo " - Skipping .env backup"
fi

read -r -p " - APP_PORT [${APP_PORT_DEFAULT}] = " NEW_APP_PORT
NEW_APP_PORT="${NEW_APP_PORT:-$APP_PORT_DEFAULT}"
APP_PORT_DEFAULT="$(strip_bind_address "$APP_PORT_DEFAULT")"
if ! is_valid_port "$APP_PORT_DEFAULT"; then
echo -e "${RED} - APP_PORT_DEFAULT must be a port number between 1 and 65535.${RESET}"
exit 1
fi

CURRENT_APP_PORT=$(grep -m1 '^APP_PORT=' "$ENV_FILE" | cut -d= -f2- || true)
if [ -n "$CURRENT_APP_PORT" ]; then
SANITIZED_CURRENT_APP_PORT="$(strip_bind_address "$CURRENT_APP_PORT")"

if ! is_valid_port "$CURRENT_APP_PORT"; then
echo -e "${YELLOW} - Current APP_PORT is '${CURRENT_APP_PORT}', which Coolify cannot start with."
echo -e " It must be a plain port number, so it will be replaced.${RESET}"
fi

if [ "$SANITIZED_CURRENT_APP_PORT" = "$TRAEFIK_DASHBOARD_PORT" ]; then
# Stock Coolify ships APP_PORT=8000, the port this installer hands to
# Traefik. Offering it back would suggest a value the loop always rejects.
echo " - Coolify is on ${TRAEFIK_DASHBOARD_PORT}, which Traefik takes over; suggesting ${APP_PORT_DEFAULT} instead."
elif is_valid_port "$SANITIZED_CURRENT_APP_PORT"; then
# Keep an already-configured port so re-running does not silently move it.
APP_PORT_DEFAULT="$SANITIZED_CURRENT_APP_PORT"
fi
fi

echo " - APP_PORT must be a plain port number (no bind address), e.g. 3000."

while true; do
read -r -p " - APP_PORT [${APP_PORT_DEFAULT}] = " NEW_APP_PORT || NEW_APP_PORT=""
NEW_APP_PORT="${NEW_APP_PORT:-$APP_PORT_DEFAULT}"

SANITIZED_APP_PORT="$(strip_bind_address "$NEW_APP_PORT")"
if [ "$SANITIZED_APP_PORT" != "$NEW_APP_PORT" ]; then
echo -e "${YELLOW} - Dropping the bind address: using '${SANITIZED_APP_PORT}' instead of '${NEW_APP_PORT}'.${RESET}"
NEW_APP_PORT="$SANITIZED_APP_PORT"
fi

if ! is_valid_port "$NEW_APP_PORT"; then
echo -e "${RED} - '${NEW_APP_PORT}' is not a valid port. Enter a number between 1 and 65535.${RESET}"
continue
fi

if [ "$NEW_APP_PORT" = "$TRAEFIK_DASHBOARD_PORT" ]; then
echo -e "${RED} - Port ${TRAEFIK_DASHBOARD_PORT} is reserved for the Traefik dashboard entrypoint. Pick another port.${RESET}"
continue
fi

break
done

Comment thread
coderabbitai[bot] marked this conversation as resolved.
update_env_var "APP_PORT" "$NEW_APP_PORT"

# Step 3: Patch Traefik configuration
Expand Down
8 changes: 6 additions & 2 deletions apps/style/src/components/sidebar/_index.scss
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,12 @@ nav > ul > li > ul > li {
display: flex;
}

nav[x-data]:has(a[title="Dashboard"]) > div[class*="flex pt-6 pb-4 pl-2"] > div,
nav[x-data]:has(a[title="Dashboard"]) > div[class*="flex pt-4 pb-4 pl-2"] > div {
nav[x-data]:has(a[title="Dashboard"])
> div[class*="flex pt-6 pb-4 pl-2"]
> div,
nav[x-data]:has(a[title="Dashboard"])
> div[class*="flex pt-4 pb-4 pl-2"]
> div {
display: flex;
}
}
Expand Down
32 changes: 24 additions & 8 deletions apps/style/src/components/sidebar/_theme-switcher.scss
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@
scale: 1 !important;
translate: 0 !important;

&::after { content: none !important; }
&::after {
content: none !important;
}
}

& > div {
Expand Down Expand Up @@ -37,17 +39,31 @@
}

& > div button svg {
& > * { display: none; }
& > * {
display: none;
}
}

& > div button[title="Light"] svg { @include icon("sun-fill", "fill"); }
& > div button[title="System default"] svg { @include icon("monitor-fill", "fill"); }
& > div button[title="Dark"] svg { @include icon("moon-fill", "fill"); }
& > div button[title="Light"] svg {
@include icon("sun-fill", "fill");
}
& > div button[title="System default"] svg {
@include icon("monitor-fill", "fill");
}
& > div button[title="Dark"] svg {
@include icon("moon-fill", "fill");
}
}

// Cycle button (collapsed)
li:has(div.menu-item[title="Theme"]) button.menu-item {
.menu-item-icon[x-show*="light"] { @include icon("sun-fill", "fill"); }
.menu-item-icon[x-show*="system"] { @include icon("monitor-fill", "fill"); }
.menu-item-icon[x-show*="dark"] { @include icon("moon-fill", "fill"); }
.menu-item-icon[x-show*="light"] {
@include icon("sun-fill", "fill");
}
.menu-item-icon[x-show*="system"] {
@include icon("monitor-fill", "fill");
}
.menu-item-icon[x-show*="dark"] {
@include icon("moon-fill", "fill");
}
}
Loading