Replace custom code-server (9GB) with upstream LinuxServer image (~1GB)

Drop the custom Dockerfile.code-server that bundled Claude Code CLI,
Python/MkDocs tooling, and build-essential on top of codercom base.
Switch to the already-mirrored linuxserver/code-server image instead.

- Both compose files: use code-server:latest, LinuxServer env vars
  (PUID/PGID/DEFAULT_WORKSPACE), port 8443, /config mount layout
- Nginx configs + templates: proxy to :8443 instead of :8080
- API env default: CODE_SERVER_URL updated to :8443
- build-and-push.sh: remove --include-code-server flag
- upgrade.sh: remove code-server conditional rebuild + registry fallback
- install.sh: add --ignore-pull-failures for optional missing images
- .env.example, CCP templates, bunker-ops template: updated

Bunker Admin
This commit is contained in:
bunker-admin 2026-03-25 20:10:36 -06:00
parent f2284a9cdf
commit 0c634e100f
13 changed files with 40 additions and 88 deletions

View File

@ -237,8 +237,7 @@ MKDOCS_DOCS_PATH=/mkdocs/docs
# --- Code Server --- # --- Code Server ---
CODE_SERVER_PORT=8888 CODE_SERVER_PORT=8888
CODE_SERVER_URL=http://code-server:8080 CODE_SERVER_URL=http://code-server-changemaker:8443
USER_NAME=coder
# --- Homepage --- # --- Homepage ---
HOMEPAGE_PORT=3010 HOMEPAGE_PORT=3010

View File

@ -195,7 +195,7 @@ const envSchema = z.object({
SMS_DEVICE_MONITOR_INTERVAL_MS: z.coerce.number().default(30000), SMS_DEVICE_MONITOR_INTERVAL_MS: z.coerce.number().default(30000),
// Docs / Code Server // Docs / Code Server
CODE_SERVER_URL: z.string().default('http://code-server-changemaker:8080'), CODE_SERVER_URL: z.string().default('http://code-server-changemaker:8443'),
CODE_SERVER_PORT: z.coerce.number().default(8888), CODE_SERVER_PORT: z.coerce.number().default(8888),
MKDOCS_PREVIEW_URL: z.string().default('http://mkdocs-changemaker:8000'), MKDOCS_PREVIEW_URL: z.string().default('http://mkdocs-changemaker:8000'),
MKDOCS_PORT: z.coerce.number().default(4003), MKDOCS_PORT: z.coerce.number().default(4003),

View File

@ -171,7 +171,7 @@ MEDIA_API_PORT={{ cml_media_api_port }}
MEDIA_API_PUBLIC_URL=http://media-api:{{ cml_media_api_port }} MEDIA_API_PUBLIC_URL=http://media-api:{{ cml_media_api_port }}
# --- Docs / Code Server --- # --- Docs / Code Server ---
CODE_SERVER_URL=http://code-server-changemaker:8080 CODE_SERVER_URL=http://code-server-changemaker:8443
CODE_SERVER_PORT=8888 CODE_SERVER_PORT=8888
MKDOCS_PREVIEW_URL=http://mkdocs-changemaker:8000 MKDOCS_PREVIEW_URL=http://mkdocs-changemaker:8000
MKDOCS_PORT=4003 MKDOCS_PORT=4003

View File

@ -252,8 +252,7 @@ MKDOCS_SITE_SERVER_PORT={{math ports.embed "+" 14}}
MKDOCS_PREVIEW_URL=http://{{containerPrefix}}-mkdocs:8000 MKDOCS_PREVIEW_URL=http://{{containerPrefix}}-mkdocs:8000
MKDOCS_DOCS_PATH=/mkdocs/docs MKDOCS_DOCS_PATH=/mkdocs/docs
CODE_SERVER_PORT={{math ports.embed "+" 7}} CODE_SERVER_PORT={{math ports.embed "+" 7}}
CODE_SERVER_URL=http://{{containerPrefix}}-code-server:8080 CODE_SERVER_URL=http://{{containerPrefix}}-code-server:8443
USER_NAME=coder
BASE_DOMAIN=https://{{domain}} BASE_DOMAIN=https://{{domain}}
# Gitea # Gitea

View File

@ -345,7 +345,7 @@ server {
server_name code.{{domain}}; server_name code.{{domain}};
location / { location / {
set $upstream_code http://{{containerPrefix}}-code-server:8080; set $upstream_code http://{{containerPrefix}}-code-server:8443;
proxy_pass $upstream_code; proxy_pass $upstream_code;
proxy_http_version 1.1; proxy_http_version 1.1;
proxy_set_header Host $host; proxy_set_header Host $host;

View File

@ -120,7 +120,7 @@ server {
server { server {
listen 8888; listen 8888;
location / { location / {
set $upstream_code http://{{containerPrefix}}-code-server:8080; set $upstream_code http://{{containerPrefix}}-code-server:8443;
proxy_pass $upstream_code; proxy_pass $upstream_code;
proxy_hide_header X-Frame-Options; proxy_hide_header X-Frame-Options;
proxy_hide_header Content-Security-Policy; proxy_hide_header Content-Security-Policy;

View File

@ -511,25 +511,25 @@ services:
# PLATFORM SERVICES (kept from v1) # PLATFORM SERVICES (kept from v1)
# ========================================================================= # =========================================================================
# Code Server — Browser IDE # Code Server — Browser IDE (LinuxServer upstream, no custom build)
code-server: code-server:
image: ${GITEA_REGISTRY:-gitea.bnkops.com/admin}/changemaker-code-server:${IMAGE_TAG:-latest} image: ${GITEA_REGISTRY:-gitea.bnkops.com/admin}/code-server:latest
container_name: code-server-changemaker container_name: code-server-changemaker
command: /home/coder/project
environment: environment:
- DOCKER_USER=${USER_NAME:-coder} - PUID=${USER_ID:-1000}
user: "${USER_ID:-1000}:${GROUP_ID:-1000}" - PGID=${GROUP_ID:-1000}
- TZ=${TZ:-UTC}
- DEFAULT_WORKSPACE=/config/workspace
volumes: volumes:
- ./configs/code-server/.config:/home/coder/.config - ./configs/code-server:/config
- ./configs/code-server/.local:/home/coder/.local - ./nginx:/config/workspace/nginx
- ./nginx:/home/coder/project/nginx - ./configs:/config/workspace/configs
- ./configs:/home/coder/project/configs - ./scripts:/config/workspace/scripts
- ./scripts:/home/coder/project/scripts - ./mkdocs:/config/workspace/mkdocs
- ./mkdocs:/home/coder/project/mkdocs - ./docker-compose.yml:/config/workspace/docker-compose.yml
- ./docker-compose.yml:/home/coder/project/docker-compose.yml
# NOTE: .env intentionally excluded — secrets must not be accessible via Code Server # NOTE: .env intentionally excluded — secrets must not be accessible via Code Server
ports: ports:
- "127.0.0.1:${CODE_SERVER_PORT:-8888}:8080" - "127.0.0.1:${CODE_SERVER_PORT:-8888}:8443"
restart: unless-stopped restart: unless-stopped
logging: *default-logging logging: *default-logging
networks: networks:

View File

@ -526,30 +526,27 @@ services:
# PLATFORM SERVICES (kept from v1) # PLATFORM SERVICES (kept from v1)
# ========================================================================= # =========================================================================
# Code Server — Browser IDE # Code Server — Browser IDE (LinuxServer upstream, no custom build)
code-server: code-server:
image: ${GITEA_REGISTRY:-gitea.bnkops.com/admin}/changemaker-code-server:${IMAGE_TAG:-local} image: ${GITEA_REGISTRY:-gitea.bnkops.com/admin}/code-server:latest
build:
context: .
dockerfile: Dockerfile.code-server
container_name: code-server-changemaker container_name: code-server-changemaker
command: /home/coder/project
environment: environment:
- DOCKER_USER=${USER_NAME:-coder} - PUID=${USER_ID:-1000}
user: "${USER_ID:-1000}:${GROUP_ID:-1000}" - PGID=${GROUP_ID:-1000}
- TZ=${TZ:-UTC}
- DEFAULT_WORKSPACE=/config/workspace
volumes: volumes:
- ./configs/code-server/.config:/home/coder/.config - ./configs/code-server:/config
- ./configs/code-server/.local:/home/coder/.local - ./api:/config/workspace/api
- ./api:/home/coder/project/api - ./admin:/config/workspace/admin
- ./admin:/home/coder/project/admin - ./nginx:/config/workspace/nginx
- ./nginx:/home/coder/project/nginx - ./configs:/config/workspace/configs
- ./configs:/home/coder/project/configs - ./scripts:/config/workspace/scripts
- ./scripts:/home/coder/project/scripts - ./mkdocs:/config/workspace/mkdocs
- ./mkdocs:/home/coder/project/mkdocs - ./docker-compose.yml:/config/workspace/docker-compose.yml
- ./docker-compose.yml:/home/coder/project/docker-compose.yml
# NOTE: .env intentionally excluded — secrets must not be accessible via Code Server # NOTE: .env intentionally excluded — secrets must not be accessible via Code Server
ports: ports:
- "127.0.0.1:${CODE_SERVER_PORT:-8888}:8080" - "127.0.0.1:${CODE_SERVER_PORT:-8888}:8443"
restart: unless-stopped restart: unless-stopped
logging: *default-logging logging: *default-logging
networks: networks:

View File

@ -315,8 +315,7 @@ Self-hosted Git repository. Optional service.
| Variable | Default | Description | | Variable | Default | Description |
|----------|---------|-------------| |----------|---------|-------------|
| `CODE_SERVER_PORT` | `8888` | Code Server web UI port. | | `CODE_SERVER_PORT` | `8888` | Code Server web UI port. |
| `CODE_SERVER_URL` | `http://code-server:8080` | Internal container URL. | | `CODE_SERVER_URL` | `http://code-server-changemaker:8443` | Internal container URL. |
| `USER_NAME` | `coder` | User account inside the Code Server container. |
--- ---

View File

@ -114,7 +114,7 @@ server {
add_header Content-Security-Policy "frame-ancestors 'self' app.${DOMAIN}" always; add_header Content-Security-Policy "frame-ancestors 'self' app.${DOMAIN}" always;
location / { location / {
set $upstream_code http://code-server-changemaker:8080; set $upstream_code http://code-server-changemaker:8443;
proxy_pass $upstream_code; proxy_pass $upstream_code;
proxy_set_header Host $host; proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Real-IP $remote_addr;

View File

@ -10,7 +10,6 @@
# Options: # Options:
# --services a,b,c Comma-separated list of services to build # --services a,b,c Comma-separated list of services to build
# (default: api admin media-api nginx) # (default: api admin media-api nginx)
# --include-code-server Also build and push code-server (~9GB, slow)
# --no-push Build only, skip push (verify builds work) # --no-push Build only, skip push (verify builds work)
# --tag TAG Override commit SHA tag (default: git rev-parse --short HEAD) # --tag TAG Override commit SHA tag (default: git rev-parse --short HEAD)
# --registry URL Override registry (default: gitea.bnkops.com/admin) # --registry URL Override registry (default: gitea.bnkops.com/admin)
@ -30,7 +29,6 @@ REGISTRY="${GITEA_REGISTRY:-gitea.bnkops.com/admin}"
COMMIT_SHA="$(git -C "$PROJECT_DIR" rev-parse --short HEAD 2>/dev/null || echo "local")" COMMIT_SHA="$(git -C "$PROJECT_DIR" rev-parse --short HEAD 2>/dev/null || echo "local")"
TAG="${COMMIT_SHA}" TAG="${COMMIT_SHA}"
SERVICES="api admin media-api nginx" SERVICES="api admin media-api nginx"
INCLUDE_CODE_SERVER=false
NO_PUSH=false NO_PUSH=false
DRY_RUN=false DRY_RUN=false
@ -52,7 +50,6 @@ run() { if [[ "$DRY_RUN" == "true" ]]; then echo -e "${CYAN}[DRY-RUN]${NC} $
while [[ $# -gt 0 ]]; do while [[ $# -gt 0 ]]; do
case "$1" in case "$1" in
--services) SERVICES="${2//,/ }"; shift 2 ;; --services) SERVICES="${2//,/ }"; shift 2 ;;
--include-code-server) INCLUDE_CODE_SERVER=true; shift ;;
--no-push) NO_PUSH=true; shift ;; --no-push) NO_PUSH=true; shift ;;
--tag) TAG="$2"; shift 2 ;; --tag) TAG="$2"; shift 2 ;;
--registry) REGISTRY="$2"; shift 2 ;; --registry) REGISTRY="$2"; shift 2 ;;
@ -64,11 +61,6 @@ while [[ $# -gt 0 ]]; do
esac esac
done done
# Add code-server if requested
if [[ "$INCLUDE_CODE_SERVER" == "true" ]]; then
SERVICES="$SERVICES code-server"
fi
echo -e "${BOLD}Changemaker Lite — Build & Push${NC}" echo -e "${BOLD}Changemaker Lite — Build & Push${NC}"
echo " Registry: $REGISTRY" echo " Registry: $REGISTRY"
echo " Tag: $TAG" echo " Tag: $TAG"
@ -119,15 +111,6 @@ build_service() {
--load \ --load \
"${PROJECT_DIR}/nginx" "${PROJECT_DIR}/nginx"
;; ;;
code-server)
warn "Building code-server (~9GB) — this will take a while..."
run docker buildx build \
--file "${PROJECT_DIR}/Dockerfile.code-server" \
--tag "${image}" \
--tag "${image_latest}" \
--load \
"${PROJECT_DIR}"
;;
*) *)
error "Unknown service: $svc" error "Unknown service: $svc"
return 1 return 1

View File

@ -256,7 +256,9 @@ if [[ "$START_SERVICES" =~ ^[Yy]$ ]]; then
echo "" echo ""
cd "$INSTALL_DIR" cd "$INSTALL_DIR"
if ! docker compose pull 2>&1; then # --ignore-pull-failures: optional services may not have images in the
# registry yet — don't abort the whole install for those.
if ! docker compose pull --ignore-pull-failures 2>&1; then
echo "" echo ""
error "Failed to pull images from the registry." error "Failed to pull images from the registry."
echo "" echo ""

View File

@ -21,7 +21,7 @@ MIN_DISK_MB=2048
# Source-built containers (always rebuilt) # Source-built containers (always rebuilt)
SOURCE_CONTAINERS="api admin media-api" SOURCE_CONTAINERS="api admin media-api"
# Conditionally rebuilt if Dockerfile changed # Conditionally rebuilt if Dockerfile changed
CONDITIONAL_CONTAINERS="nginx code-server" CONDITIONAL_CONTAINERS="nginx"
# App containers stopped during upgrade # App containers stopped during upgrade
APP_CONTAINERS="api admin media-api nginx" APP_CONTAINERS="api admin media-api nginx"
# Infrastructure containers (must stay up) # Infrastructure containers (must stay up)
@ -884,24 +884,6 @@ if [[ "$USE_REGISTRY" == "true" ]]; then
fi fi
fi fi
# code-server: pull from registry if available; never build during upgrade
# (code-server is 9GB+ and takes 30+ min to build — run build-and-push.sh separately)
CS_IMAGE="${REGISTRY}/changemaker-code-server"
if docker image inspect "${CS_IMAGE}:${REGISTRY_TAG}" &>/dev/null 2>&1; then
info "code-server:${REGISTRY_TAG} already present, skipping"
elif docker compose pull code-server 2>/dev/null; then
success "code-server pulled from registry"
else
# Try :latest, then retag any existing local image so compose up doesn't build
for fallback_tag in latest local; do
if docker image inspect "${CS_IMAGE}:${fallback_tag}" &>/dev/null 2>&1; then
docker tag "${CS_IMAGE}:${fallback_tag}" "${CS_IMAGE}:${REGISTRY_TAG}" 2>/dev/null || true
info "Tagged code-server:${fallback_tag} → :${REGISTRY_TAG}"
break
fi
done
fi
else else
# --- Source build path (original behaviour) --- # --- Source build path (original behaviour) ---
info "Rebuilding source containers: $SOURCE_CONTAINERS" info "Rebuilding source containers: $SOURCE_CONTAINERS"
@ -920,15 +902,6 @@ else
info "nginx unchanged, skipping rebuild" info "nginx unchanged, skipping rebuild"
fi fi
;; ;;
code-server)
if echo "$CHANGED_FILES" | grep -q "^Dockerfile.code-server"; then
info "Rebuilding code-server (Dockerfile changed)..."
docker compose build code-server
success "code-server rebuilt"
else
info "code-server unchanged, skipping rebuild"
fi
;;
esac esac
done done
fi fi