From 349611baed625ff033b8ab7dfbdf202d3bc5731c Mon Sep 17 00:00:00 2001 From: jacobHu Date: Wed, 30 Apr 2025 16:37:11 +0800 Subject: [PATCH 1/2] devbox adjust --- devbox/cli/devbox | 382 ++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 321 insertions(+), 61 deletions(-) diff --git a/devbox/cli/devbox b/devbox/cli/devbox index f2fbf69..8387482 100755 --- a/devbox/cli/devbox +++ b/devbox/cli/devbox @@ -121,6 +121,7 @@ devbox_init_guidance() { use_local_component=false use_custom_repository="" freeleaps_components="" + git_branch="main" # Ask user for Freeleaps.com username and password read -p "Enter your Freeleaps.com username: " freeleaps_username @@ -130,11 +131,18 @@ devbox_init_guidance() { if [[ $choose_local_component == "y" ]]; then use_local_component=true fi + + # Ask user for git branch + read -p "Enter git branch to checkout (default: main): " input_git_branch + if [[ -n $input_git_branch ]]; then + git_branch=$input_git_branch + fi add_arg "--freeleaps-username" "$freeleaps_username" add_arg "--freeleaps-password" "$freeleaps_password" add_arg "--use-local-component" "$use_local_component" add_arg "--use-custom-repository" "$use_custom_repository" + add_arg "--git-branch" "$git_branch" ;; 2) # Check if product_id is empty @@ -151,8 +159,15 @@ devbox_init_guidance() { read -s -p "Enter your Freeleaps.com password: " freeleaps_password echo + # Ask user for git branch + read -p "Enter git branch to checkout (default: main): " git_branch + if [[ -z $git_branch ]]; then + git_branch="main" + fi + add_arg "--freeleaps-username" "$freeleaps_username" add_arg "--freeleaps-password" "$freeleaps_password" + add_arg "--git-branch" "$git_branch" ENCODING_FREELEAPS_USERNAME=$(url_encode "$freeleaps_username") ENCODEING_FREELEAPS_PASSWORD=$(url_encode "$freeleaps_password") @@ -229,15 +244,16 @@ devbox_init_usage() { printf " --working-home -w [Optional] : Specifies the working home of DevBox CLI. Default: %s/devbox\n" "$HOME" printf " --devbox-container-name -n [Optional] : Specifies the DevBox container name. Default: devbox.\n" printf " --devbox-container-port -p [Optional] : Specifies the container port for DevBox SSH access. Default: 22222.\n" + printf " --devbox-nginx-port [Optional] : Specifies the host port for Nginx reverse proxy access. Default: 8080.\n" # add Nginx port description + printf " --devbox-backend-port -b [Optional] : Specifies the container port for DevBox backend access. Default: 8002.\n" printf " --devbox-image-repo -r [Optional] : Specifies the DevBox container image repository. Default: docker.io/freeleaps.\n" printf " --devbox-image-name -i [Optional] : Specifies the DevBox container image name. Default: devbox.\n" printf " --devbox-image-tag -t [Optional] : Specifies the DevBox container image tag. Default: latest.\n" - printf " --devbox-frontend-port -q [Optional] : Specifies the container port for DevBox frontend access. Default: 5173.\n" - printf " --devbox-backend-port -b [Optional] : Specifies the container port for DevBox backend access. Default: 8002.\n" printf " --freeleaps-username -u [Optional] : Specifies the Freeleaps.com repository username.\n" printf " --freeleaps-password -x [Optional] : Specifies the Freeleaps.com repository password.\n" printf " --use-local-component -l [Optional] : Check if using local component or online dev environment. Default: false.\n" printf " --use-custom-repository -c [Optional] : Specifies the custom git repository for source code.\n" + printf " --git-branch -g [Optional] : Specifies the git branch to checkout. Default: main.\n" printf " --freeleaps-components -m [Optional] : Specifies the Freeleaps.com components to start in the DevBox container.\n" printf " --force -f [Optional] : Force initialization even if resources already exist.\n\n" @@ -249,6 +265,8 @@ devbox_init_usage() { printf " devbox init --os linux --arch arm64 --freeleaps-username alice --freeleaps-password secret\n" printf " Initialize with custom container settings:\n" printf " devbox init --devbox-container-name custom-devbox --devbox-container-port 22222 --freeleaps-username alice --freeleaps-password secret\n" + printf " Initialize with a specific git branch:\n" + printf " devbox init --git-branch develop --freeleaps-username alice --freeleaps-password secret\n" else printf "devbox init - Initialize the local development environment based on DevBox container.\n\n" fi @@ -639,6 +657,7 @@ docker exec -i "$DEVBOX_NAME" bash < /dev/null + # Create the logs directory if it does not exist + mkdir -p /home/devbox/logs + + # Install Nginx and net-tools + echo "[INIT] \$(date '+%Y-%m-%d %H:%M:%S') Installing Nginx and net-tools..." + sudo apt-get update + sudo apt-get install -y nginx net-tools + + # Stop nginx if it started automatically after installation + if sudo service nginx status > /dev/null 2>&1; then + echo "[INIT] \$(date '+%Y-%m-%d %H:%M:%S') Stopping Nginx service after installation..." + sudo service nginx stop + fi + + # Configure Nginx + echo "[INIT] \$(date '+%Y-%m-%d %H:%M:%S') Configuring Nginx..." + if [ -f "/home/devbox/freeleaps/frontend/devbox_nginx.conf" ]; then + # overwrite the default configuration + sudo cp /home/devbox/freeleaps/frontend/devbox_nginx.conf /etc/nginx/nginx.conf + + if sudo nginx -t; then + echo "[INIT] \$(date '+%Y-%m-%d %H:%M:%S') Nginx configuration syntax check successful." + else + echo "[ERROR] \$(date '+%Y-%m-%d %H:%M:%S') Nginx configuration syntax error. Please check /home/devbox/freeleaps/frontend/devbox_nginx.conf." >&2 + exit 1 + fi + else + echo "[WARN] \$(date '+%Y-%m-%d %H:%M:%S') Nginx configuration file /home/devbox/freeleaps/frontend/devbox_nginx.conf not found. Skipping Nginx configuration." + fi + fi EOF @@ -837,14 +886,23 @@ stop_frontend_service() { DEVBOX_NAME=$(cat "$devbox_container_id_file_path") docker exec -i "$DEVBOX_NAME" bash </dev/null || true rm -f /home/devbox/.frontend.pid - else - echo "[FRONTEND] \$(date '+%Y-%m-%d %H:%M:%S') Frontend service is not running." + else + echo "[FRONTEND] \$(date '+%Y-%m-%d %H:%M:%S') Frontend process PID file not found or process not running." + fi + + echo "[NGINX] \$(date '+%Y-%m-%d %H:%M:%S') Stopping Nginx service..." + if sudo service nginx status > /dev/null 2>&1; then + sudo service nginx stop + echo "[NGINX] \$(date '+%Y-%m-%d %H:%M:%S') Nginx stopped." + else + echo "[NGINX] \$(date '+%Y-%m-%d %H:%M:%S') Nginx service is not running." fi EOF @@ -1133,28 +1191,36 @@ fi DEVBOX_NAME=$(cat "$devbox_container_id_file_path") -DEVBOX_FRONTEND_PORT=$(cat "$WORKING_HOME/.devbox-frontend-port") +DEVBOX_NGINX_HOST_PORT=$(cat "$WORKING_HOME/.devbox-nginx-port") # Nginx Host Port docker exec -i "$DEVBOX_NAME" bash < /dev/null 2>&1; then + nginx_running=true + fi + + frontend_running=false if [ -f /home/devbox/.frontend.pid ]; then frontend_pid=\$(cat /home/devbox/.frontend.pid) - if [ -n "\$frontend_pid" ]; then - # Check if the frontend service is running - if ps -p "\$frontend_pid" > /dev/null; then - echo - echo "============================================================================================" - echo - echo "[FRONTEND] [WARNING] Frontend service is running with PID: \$frontend_pid, if you want to restart, please stop it first or run devbox restart -e frontend." - echo - echo "============================================================================================" - echo - exit 1 - fi + if [ -n "\$frontend_pid" ] && ps -p "\$frontend_pid" > /dev/null; then + frontend_running=true fi fi - + + if [[ "\$nginx_running" == "true" || "\$frontend_running" == "true" ]]; then + echo + echo "============================================================================================" + echo + echo "[FRONTEND/NGINX] [WARNING] Frontend process (PID: \${frontend_pid:-N/A}) or Nginx is already running." + echo "[FRONTEND/NGINX] [WARNING] If you want to restart, please stop it first (devbox stop -e frontend) or run devbox restart -e frontend." + echo + echo "============================================================================================" + echo + exit 1 + fi + USE_LOCAL_COMPONENT_FLAG="/home/devbox/.use-local-component" USE_LOCAL_COMPONENT_VAL="false" @@ -1280,33 +1346,119 @@ docker exec -i "$DEVBOX_NAME" bash < /home/devbox/logs/frontend.logs 2>&1 & + PNPM_PID=\$! # get the PID of the pnpm run dev process + echo "\$PNPM_PID" > /home/devbox/.frontend.pid # save the PID of the pnpm run dev process + + echo "[FRONTEND] \$(date '+%Y-%m-%d %H:%M:%S') Frontend applications started (PID: \$PNPM_PID). Logs: /home/devbox/logs/frontend.logs" - echo "[FRONTEND] \$(date '+%Y-%m-%d %H:%M:%S') Frontend service started. Logs: /home/devbox/logs/frontend.logs" - - # Check the health of the frontend service: poll to detect HTTP status - MAX_ATTEMPTS=30 + # Check the health of the frontend services (check Nginx endpoint after starting it) + # Health check now needs to wait for Nginx to be up and proxying correctly + MAX_ATTEMPTS=25 ATTEMPT=0 - echo "[FRONTEND] \$(date '+%Y-%m-%d %H:%M:%S') Checking frontend service startup..." + APPS_READY=false + echo "[FRONTEND] \$(date '+%Y-%m-%d %H:%M:%S') Waiting for frontend applications to become ready..." + + # poll the internal port + VUE_PORT=5173 + NUXT_PORT=3001 + VUE_READY=false + NUXT_READY=false while [ \$ATTEMPT -lt \$MAX_ATTEMPTS ]; do - HTTP_CODE=\$(curl -s -o /dev/null -w "%{http_code}" "http://localhost:${DEVBOX_FRONTEND_PORT}/") - if [ "\$HTTP_CODE" -eq 200 ]; then - echo "[FRONTEND] \$(date '+%Y-%m-%d %H:%M:%S') Service started successfully (HTTP \$HTTP_CODE)" + # check the Vue port + if ! \$VUE_READY && curl --output /dev/null --silent --head --fail http://localhost:\${VUE_PORT}; then + echo "[FRONTEND] \$(date '+%Y-%m-%d %H:%M:%S') Vue app (port \${VUE_PORT}) seems ready." + VUE_READY=true + fi + # check the Nuxt port + if ! \$NUXT_READY && curl --output /dev/null --silent --head --fail http://localhost:\${NUXT_PORT}/home/; then + echo "[FRONTEND] \$(date '+%Y-%m-%d %H:%M:%S') Nuxt app (port \${NUXT_PORT}) seems ready." + NUXT_READY=true + fi - # Get the backend service PID by checking the process port with netstat -tulnp | grep ${DEVBOX_FRONTEND_PORT} - FRONTEND_PID=\$(netstat -tulnp 2>/dev/null | grep "${DEVBOX_FRONTEND_PORT}" | awk '{print \$7}' | awk -F'/' '{print \$1}') + if \$VUE_READY && \$NUXT_READY; then + APPS_READY=true + break + fi - echo "\$FRONTEND_PID" > /home/devbox/.frontend.pid + echo "[FRONTEND] \$(date '+%Y-%m-%d %H:%M:%S') Waiting for apps... Vue Ready: \$VUE_READY, Nuxt Ready: \$NUXT_READY (Attempt \$((ATTEMPT+1))/\$MAX_ATTEMPTS)" + ATTEMPT=\$((ATTEMPT+1)) + sleep 5 + done + + if [ "\$APPS_READY" = false ]; then + echo + echo "============================================================================================" + echo + echo "[FRONTEND] [ERROR] Frontend applications (Vue/Nuxt) did not become ready within the time limit." + echo "[FRONTEND] [ERROR] Please check the logs: /home/devbox/logs/frontend.logs" + echo + echo "============================================================================================" + echo + # stop the already started pnpm process + kill -9 \$PNPM_PID 2>/dev/null || true + rm -f /home/devbox/.frontend.pid + exit 1 + fi + + + # Start Nginx service + echo "[NGINX] \$(date '+%Y-%m-%d %H:%M:%S') Starting Nginx service..." + if sudo service nginx start; then + echo "[NGINX] \$(date '+%Y-%m-%d %H:%M:%S') Nginx started successfully." + sleep 2 # wait for Nginx to be fully started + else + echo + echo "============================================================================================" + echo + echo "[NGINX] [ERROR] Failed to start Nginx service. Check Nginx logs (/var/log/nginx/) and configuration." + echo + echo "============================================================================================" + echo + # stop the already started pnpm process + kill -9 \$PNPM_PID 2>/dev/null || true + rm -f /home/devbox/.frontend.pid + exit 1 + fi + + # Check Nginx health (check port 80 inside container) + MAX_ATTEMPTS_NGINX=10 + ATTEMPT_NGINX=0 + NGINX_READY=false + echo "[NGINX] \$(date '+%Y-%m-%d %H:%M:%S') Checking Nginx service health..." + while [ \$ATTEMPT_NGINX -lt \$MAX_ATTEMPTS_NGINX ]; do + HTTP_CODE=\$(curl -s -o /dev/null -w "%{http_code}" "http://localhost:80/") # check the Nginx internal port 80 + if [ "\$HTTP_CODE" -eq 200 ] || [ "\$HTTP_CODE" -eq 404 ]; then # 200 or 404 (if the root path proxy application is not fully started) are considered OK + echo "[NGINX] \$(date '+%Y-%m-%d %H:%M:%S') Nginx service responding (HTTP \$HTTP_CODE)" + NGINX_READY=true break else - echo "[FRONTEND] \$(date '+%Y-%m-%d %H:%M:%S') Waiting for frontend service... Attempt \$((ATTEMPT+1))" - ATTEMPT=\$((ATTEMPT+1)) - sleep 10 + echo "[NGINX] \$(date '+%Y-%m-%d %H:%M:%S') Waiting for Nginx service... Attempt \$((ATTEMPT_NGINX+1)) (HTTP \$HTTP_CODE)" + ATTEMPT_NGINX=\$((ATTEMPT_NGINX+1)) + sleep 3 fi done - + + if [ "\$NGINX_READY" = false ]; then + echo + echo "============================================================================================" + echo + echo "[NGINX] [ERROR] Nginx service startup failed or did not respond correctly." + echo "[NGINX] [ERROR] Please check Nginx logs (/var/log/nginx/) and frontend logs (/home/devbox/logs/frontend.logs)." + echo + echo "============================================================================================" + echo + # stop the already started pnpm process and Nginx + sudo service nginx stop 2>/dev/null || true + kill -9 \$PNPM_PID 2>/dev/null || true + rm -f /home/devbox/.frontend.pid + exit 1 + fi + + # if /tmp/pnpm-lock.yaml.bak exists, restore it if [ -f "/tmp/pnpm-lock.yaml.bak" ]; then @@ -1345,20 +1497,13 @@ docker exec -i "$DEVBOX_NAME" bash < /dev/null echo - echo "[FRONTEND] \$(date '+%Y-%m-%d %H:%M:%S') Frontend compilation and startup completed." + echo "[FRONTEND/NGINX] \$(date '+%Y-%m-%d %H:%M:%S') Frontend applications and Nginx proxy started successfully." + echo "[FRONTEND/NGINX] \$(date '+%Y-%m-%d %H:%M:%S') Access via host port: ${DEVBOX_NGINX_HOST_PORT}" + echo "[FRONTEND/NGINX] \$(date '+%Y-%m-%d %H:%M:%S') - Vue App: http://localhost:${DEVBOX_NGINX_HOST_PORT}/" + echo "[FRONTEND/NGINX] \$(date '+%Y-%m-%d %H:%M:%S') - Nuxt App: http://localhost:${DEVBOX_NGINX_HOST_PORT}/home/" echo # Check frontend git checkout status @@ -1449,6 +1594,10 @@ devbox_init_command() { local FREELEAPS_COMPONENTS="$args_freeleaps_components" # --freeleaps-components local USE_CUSTOM_REPOSITORY="$args_use_custom_repository" # --use-custom-repository + + local GIT_BRANCH="$args_git_branch" # --git-branch + + local DEVBOX_NGINX_PORT="$(get_arg '--devbox-nginx-port')" # --devbox-nginx-port # --force flag to overwrite existing resources local FORCE_INIT="${args_force}" @@ -1469,6 +1618,7 @@ devbox_init_command() { local FREELEAPS_COMPONENTS="$(get_arg '--freeleaps-components')" local USE_CUSTOM_REPOSITORY="$(get_arg '--use-custom-repository')" + local GIT_BRANCH="$(get_arg '--git-branch')" local FORCE_INIT="$(get_arg '--force')" @@ -1543,6 +1693,8 @@ devbox_init_command() { log_info " USE_LOCAL_COMPONENT= $USE_LOCAL_COMPONENT" log_info " FREELEAPS_COMPONENTS= ${start_components[@]}" log_info " FORCE_INIT = $FORCE_INIT" + log_info " DEVBOX_NGINX_PORT = $DEVBOX_NGINX_PORT (Host Port for Nginx)" + log_info " DEVBOX_FRONTEND_PORT = $DEVBOX_FRONTEND_PORT (Internal Vue3 Port)" echo # ------------------------------------------------------------------- @@ -1722,7 +1874,7 @@ devbox_init_command() { local devbox_full_image="${DEVBOX_REPO}/${DEVBOX_IMAGE}:${DEVBOX_TAG}" - # Check local and remote version. User doesn’t need to rebuild devbox if local version is consistent with remote version + # Check local and remote version. User doesn't need to rebuild devbox if local version is consistent with remote version if [[ -n "$DEVBOX_REPO" && -n "$DEVBOX_IMAGE" && -n "$DEVBOX_TAG" ]]; then if docker images --format '{{.Repository}}:{{.Tag}}' | grep -q "^${DEVBOX_REPO}/${DEVBOX_IMAGE}:${DEVBOX_TAG}\$"; then log_info "DevBox image $devbox_full_image already exists." @@ -1823,8 +1975,8 @@ devbox_init_command() { docker run -d \ --name "$DEVBOX_NAME" \ -p "${DEVBOX_PORT}:22" \ - -p "${DEVBOX_FRONTEND_PORT}:5173" \ - -p "${DEVBOX_BACKEND_PORT}:8002" \ + -p "0.0.0.0:${DEVBOX_NGINX_PORT}:80" \ + -p "0.0.0.0:${DEVBOX_BACKEND_PORT}:8002" \ -v "$WORKING_HOME:/home/devbox" \ -v /var/run/docker.sock:/var/run/docker.sock \ --network "$DEVBOX_FREELEAPS2_NETWORK" \ @@ -1839,6 +1991,7 @@ devbox_init_command() { echo "$container_id" > "$WORKING_HOME/.devbox-instance" echo "$DEVBOX_FRONTEND_PORT" > "$WORKING_HOME/.devbox-frontend-port" echo "$DEVBOX_BACKEND_PORT" > "$WORKING_HOME/.devbox-backend-port" + echo "$DEVBOX_NGINX_PORT" > "$WORKING_HOME/.devbox-nginx-port" DOVBOX_CLI_DIR=$(pwd) @@ -1862,6 +2015,16 @@ devbox_init_command() { log_info "Git cloning gitea.freeleaps.mathmast.com/products/freeleaps.git to $FREELEAPS_DIR" git clone --depth 5 $FRONTEND_GIT_URL + # Checkout the specified branch + if [[ -n "$GIT_BRANCH" && "$GIT_BRANCH" != "main" ]]; then + pushd "$FREELEAPS_DIR" > /dev/null + log_info "Checking out branch: $GIT_BRANCH" + if ! git checkout $GIT_BRANCH; then + log_warn "Failed to checkout branch $GIT_BRANCH, falling back to main branch" + git checkout main + fi + popd > /dev/null + fi else pushd "$FREELEAPS_DIR" > /dev/null # Check $WORKING_HOME/freeleaps exists and it is a git repository, if not git clone it @@ -1877,9 +2040,38 @@ devbox_init_command() { sudo chown -R ${uid}:${gid} "$WORKING_HOME" git clone --depth 5 "$FRONTEND_GIT_URL" + + # Checkout the specified branch + if [[ -n "$GIT_BRANCH" && "$GIT_BRANCH" != "main" ]]; then + pushd "$FREELEAPS_DIR" > /dev/null + log_info "Checking out branch: $GIT_BRANCH" + if ! git checkout $GIT_BRANCH; then + log_warn "Failed to checkout branch $GIT_BRANCH, falling back to main branch" + git checkout main + fi + popd > /dev/null + fi else log_info "Git pulling gitea.freeleaps.mathmast.com/products/freeleaps.git" - git pull + git fetch --all + + # Checkout the specified branch + if [[ -n "$GIT_BRANCH" ]]; then + log_info "Checking out branch: $GIT_BRANCH" + # try to checkout the local branch directly + if git checkout $GIT_BRANCH 2>/dev/null; then + log_info "Checked out local branch: $GIT_BRANCH" + git pull origin $GIT_BRANCH + # if the local branch does not exist, try to create and checkout the remote branch + elif git checkout -b $GIT_BRANCH origin/$GIT_BRANCH 2>/dev/null; then + log_info "Checked out remote branch: $GIT_BRANCH" + else + log_warn "Failed to checkout branch $GIT_BRANCH, falling back to main branch" + git checkout main + fi + else + git pull + fi fi popd > /dev/null @@ -1905,6 +2097,17 @@ devbox_init_command() { pushd "$WORKING_HOME" > /dev/null log_info "Git cloning custom repository: $ECHO_USE_CUSTOM_REPOSITORY" git clone --depth 5 "$USE_CUSTOM_REPOSITORY" + + # Checkout the specified branch + if [[ -n "$GIT_BRANCH" && "$GIT_BRANCH" != "main" ]]; then + pushd "$CUSTOM_DIR" > /dev/null + log_info "Checking out branch: $GIT_BRANCH" + if ! git checkout $GIT_BRANCH; then + log_warn "Failed to checkout branch $GIT_BRANCH, falling back to main branch" + git checkout main + fi + popd > /dev/null + fi else pushd "$CUSTOM_DIR" > /dev/null # Check $WORKING_HOME/custom exists and it is a git repository, if not git clone it @@ -1920,9 +2123,33 @@ devbox_init_command() { sudo chown -R ${uid}:${gid} "$WORKING_HOME" git clone --depth 5 "$USE_CUSTOM_REPOSITORY" + + # Checkout the specified branch + if [[ -n "$GIT_BRANCH" && "$GIT_BRANCH" != "main" ]]; then + pushd "$CUSTOM_DIR" > /dev/null + log_info "Checking out branch: $GIT_BRANCH" + if ! git checkout $GIT_BRANCH; then + log_warn "Failed to checkout branch $GIT_BRANCH, falling back to main branch" + git checkout main + fi + popd > /dev/null + fi else log_info "Git pulling custom repository" - git pull + git fetch + + # Checkout the specified branch + if [[ -n "$GIT_BRANCH" ]]; then + log_info "Checking out branch: $GIT_BRANCH" + if ! git checkout $GIT_BRANCH; then + log_warn "Failed to checkout branch $GIT_BRANCH, falling back to main branch" + git checkout main + else + git pull origin $GIT_BRANCH + fi + else + git pull + fi fi popd > /dev/null @@ -2152,15 +2379,21 @@ reset_freeleaps_repo echo "DevBox init completed successfully!" echo "DevBox Environment Details:" echo "1. Code repository is located at: ${WORKING_HOME}/freeleaps" - echo "2. Open up the frontend by visiting: http://localhost:${DEVBOX_FRONTEND_PORT}" + echo "2. Access frontend applications via Nginx proxy:" + echo " - Vue3 App (Default): http://localhost:${DEVBOX_NGINX_PORT}/" + echo " - Nuxt App (/home): http://localhost:${DEVBOX_NGINX_PORT}/home/" echo "3. Log files can be viewed at:" - echo " - Backend logs: ${WORKING_HOME}/logs/backend.logs" - echo " - Frontend logs: ${WORKING_HOME}/logs/frontend.logs" + echo " - Backend logs: ${WORKING_HOME}/logs/backend.logs" + echo " - Frontend logs: ${WORKING_HOME}/logs/frontend.logs (Contains output from pnpm run dev for both apps)" + echo " - Nginx logs inside container: /var/log/nginx/" echo "DevBox container ID: $WORKING_HOME/.devbox-instance" echo "Backend PID: $WORKING_HOME/.backend.pid" - echo "Frontend PID: $WORKING_HOME/.frontend.pid" + echo "Frontend Process PID: $WORKING_HOME/.frontend.pid (pnpm run dev process)" echo "===========================================================" echo + + # Save $GIT_BRANCH to .git-branch file + echo "$GIT_BRANCH" > "$WORKING_HOME/.git-branch" } # :command.function @@ -3169,7 +3402,7 @@ devbox_init_parse_requirements() { add_arg '--devbox-frontend-port' "$2" shift 2 else - printf "%s\n" "--devbox-frontend-port requires an argument: --devbox-frontend-port DEVBOX_FRONTEND_PORT" >&2 + printf "%s\n" "--devbox-frontend-port requires an argument: --devbox-frontend-port DEVBOX_FRONTEND_PORT (Internal Vue3 Port)" >&2 exit 1 fi ;; @@ -3283,6 +3516,26 @@ devbox_init_parse_requirements() { add_arg '--force' '1' shift ;; + # :flag.case + --git-branch | -g) + if [[ -n ${2+x} ]]; then + add_arg '--git-branch' "$2" + shift 2 + else + printf "%s\n" "--git-branch requires an argument: --git-branch GIT_BRANCH" >&2 + exit 1 + fi + ;; + --devbox-nginx-port) + # :flag.case_arg + if [[ -n ${2+x} ]]; then + add_arg '--devbox-nginx-port' "$2" + shift 2 + else + printf "%s\n" "--devbox-nginx-port requires an argument: --devbox-nginx-port DEVBOX_NGINX_PORT (Host Port)" >&2 + exit 1 + fi + ;; -?*) printf "invalid option: %s\n" "$key" >&2 exit 1 @@ -3361,6 +3614,13 @@ devbox_init_parse_requirements() { if [ -z "$(get_arg '--use-local-component')" ]; then add_arg '--use-local-component' "false" fi + + if [ -z "$(get_arg '--git-branch')" ]; then + add_arg '--git-branch' "main" + fi + if [ -z "$(get_arg '--devbox-nginx-port')" ]; then + add_arg '--devbox-nginx-port' "8888" + fi } From 1fd13a74ad3f7ea8af450e1dd4c1fe1127d7c4c2 Mon Sep 17 00:00:00 2001 From: jacobHu Date: Wed, 30 Apr 2025 16:43:03 +0800 Subject: [PATCH 2/2] add readme --- devbox/cli/readme.md | 51 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 devbox/cli/readme.md diff --git a/devbox/cli/readme.md b/devbox/cli/readme.md new file mode 100644 index 0000000..4d10387 --- /dev/null +++ b/devbox/cli/readme.md @@ -0,0 +1,51 @@ +# DevBox Frontend Development Environment (with Nginx Reverse Proxy) + +This document explains how to use the `devbox` script to set up a local development environment containing two frontend applications (Vue3 and Nuxt) with Nginx reverse proxy. + +## Purpose + +In standard development workflow, `pnpm run dev` launches two frontend applications simultaneously: + +1. **Vue3 Application (freeleaps):** Listens on `http://localhost:5173` inside the container by default. +2. **Nuxt Application (nuxt-front):** Listens on `http://localhost:3001` inside the container with base URL set to `/home/`. + +To access both applications through a **single port** from outside the container, we introduced Nginx as a reverse proxy. + +## Nginx Configuration + +Nginx runs inside the `devbox` container and routes requests to the correct internal frontend application based on the access path. + +* **Configuration File Location:** + * During init_compile_env initialization, the script looks for `/home/devbox/freeleaps/frontend/devbox_nginx.conf`. + * If found, this file will be copied to `/etc/nginx/nginx.conf` inside the container. +* **Proxy Rules:** + * Requests to `http://:/` will be proxied to `http://localhost:5173/` (Vue3 app) inside the container. + * Requests to `http://:/home/` will be proxied to `http://localhost:3001/home/` (Nuxt app) inside the container. + +## Port Configuration + +You can configure relevant ports through `devbox` command parameters: + +* **`--devbox-nginx-port `:** + * Specifies the port on the **host machine** for accessing the Nginx reverse proxy. + * **Default: `8888`**. + * This is the port you'll use to access frontend applications from your browser. + +## Git Branch Selection + +During environment initialization, you can specify which Git branch to check out: + +* **Interactive Mode:** + When running `./devbox`, the script will prompt you to enter a branch name (defaults to `main`). + +The script will attempt to check out the specified branch. If checkout fails (e.g., remote branch doesn't exist), it will fall back to the `main` branch. + +## Accessing Applications + +After successful environment startup, access the applications from your **host machine** browser: + +* **Vue3 Application:** `http://localhost:/` (e.g.: `http://localhost:8888/`) +* **Nuxt Application:** `http://localhost:/home/` (e.g.: `http://localhost:8888/home/`) + +Where `` is the port specified via `--devbox-nginx-port`, defaulting to `8888`. +