From 3f3580e25e405cff5320fc665ccbba19f5301b45 Mon Sep 17 00:00:00 2001 From: Tianyong Qiu Date: Wed, 12 Feb 2025 00:37:14 +0800 Subject: [PATCH] Update for optimize all start/stop/restart logic and docker compose configuration --- devbox/devbox.local/devbox | 1008 +++++++---------- .../docker-compose.dev.arm64.new.yaml | 16 +- 2 files changed, 406 insertions(+), 618 deletions(-) diff --git a/devbox/devbox.local/devbox b/devbox/devbox.local/devbox index ba530e4..e2731dc 100644 --- a/devbox/devbox.local/devbox +++ b/devbox/devbox.local/devbox @@ -687,153 +687,6 @@ check_docker_running() { return 1 } -start_local_gitea(){ - echo "[INFO] Starting Gitea container..." - - GITEA_CONTAINER_NAME="freeleaps2-gitea" - GITEA_IMAGE="gitea/gitea:latest" - - # If a container with the same name exists, remove it - if docker ps -a --format '{{.Names}}' | grep -q "^${GITEA_CONTAINER_NAME}\$"; then - echo "==> Removing existing Gitea container..." - docker stop "${GITEA_CONTAINER_NAME}" &>/dev/null || true - docker rm "${GITEA_CONTAINER_NAME}" &>/dev/null || true - fi - - # Pull the Gitea image - echo "==> Pulling Gitea image: ${GITEA_IMAGE}" - if ! docker pull "${GITEA_IMAGE}"; then - echo "ERROR: Failed to pull Gitea image: ${GITEA_IMAGE}" - exit 1 - fi - - # Run the Gitea container mapping port 3000 - gitea_container_id=$(docker run -d --name "${GITEA_CONTAINER_NAME}" \ - -v "${WORKING_HOME}/gitea:/data" \ - -e "DISABLE_REGISTRATION=true" \ - -e "REQUIRE_SIGNIN_VIEW=true" \ - -p 3000:3000 "${GITEA_IMAGE}" ) - - if [[ -z "${gitea_container_id}" ]]; then - echo "ERROR: Failed to start Gitea container." - exit 1 - fi - - echo "Gitea container started successfully: ${gitea_container_id}" - - # Allow Gitea some time to initialize - sleep 20 - - # Check Gitea health via curl - if curl -s -o /dev/null -w "%{http_code}" http://localhost:3000 &>/dev/null; then - echo "Gitea health check passed." - else - echo "ERROR: Gitea health check failed." - exit 1 - fi - - echo "$gitea_container_id" > "$WORKING_HOME/.gitea-instance" - - echo "[INFO] Completed Gitea container..." -} - -start_local_mongodb() { - echo "==> Starting MongoDB service..." - - MONGO_CONTAINER_NAME="freeleaps2-mongodb" - MONGO_IMAGE="mongo:latest" - - # if a container with the same name exists, remove it - if docker ps -a --format '{{.Names}}' | grep -q "^${MONGO_CONTAINER_NAME}\$"; then - echo "==> Removing existing MongoDB container..." - docker stop "$MONGO_CONTAINER_NAME" &>/dev/null || true - docker rm "$MONGO_CONTAINER_NAME" &>/dev/null || true - fi - - echo "==> Pulling MongoDB image: $MONGO_IMAGE" - if ! docker pull "$MONGO_IMAGE"; then - echo "ERROR: Failed to pull MongoDB image: $MONGO_IMAGE" - exit 1 - fi - - echo "==> Starting MongoDB container..." - mongo_container_id=$(docker run -d --name "$MONGO_CONTAINER_NAME" -p 27017:27017 "$MONGO_IMAGE" mongod --bind_ip_all) - if [[ -z "$mongo_container_id" ]]; then - echo "ERROR: Failed to start MongoDB container." - exit 1 - fi - echo "MongoDB container started successfully: $mongo_container_id" - - sleep 10 - - MAX_ATTEMPTS=10 - ATTEMPT=0 - while [ $ATTEMPT -lt $MAX_ATTEMPTS ]; do - if docker exec "$MONGO_CONTAINER_NAME" mongosh --eval "db.adminCommand('ping')" 2>/dev/null | grep -q '{ ok: 1 }'; then - echo "MongoDB health check passed." - break - fi - echo "Waiting for MongoDB to be ready... (Attempt $((ATTEMPT+1)))" - sleep 10 - ATTEMPT=$((ATTEMPT+1)) - done - - - if [ $ATTEMPT -eq $MAX_ATTEMPTS ]; then - echo "ERROR: MongoDB health check failed." - exit 1 - fi - - echo "$mongo_container_id" > "$WORKING_HOME/.mongodb-instance" - echo "==> Completed MongoDB container..." -} - -start_local_rabbitMQ(){ - echo "[INFO] Starting RabbitMQ container..." - - RABBITMQ_CONTAINER_NAME="freeleaps2" - RABBITMQ_IMAGE="rabbitmq:latest" - - # If a container with the same name exists, remove it - if docker ps -a --format '{{.Names}}' | grep -q "^${RABBITMQ_CONTAINER_NAME}\$"; then - echo "==> Removing existing RabbitMQ container..." - docker stop "${RABBITMQ_CONTAINER_NAME}" &>/dev/null || true - docker rm "${RABBITMQ_CONTAINER_NAME}" &>/dev/null || true - fi - - # Pull the RabbitMQ image - echo "==> Pulling RabbitMQ image: ${RABBITMQ_IMAGE}" - if ! docker pull "${RABBITMQ_IMAGE}"; then - echo "ERROR: Failed to pull RabbitMQ image: ${RABBITMQ_IMAGE}" - exit 1 - fi - - # Run the RabbitMQ container mapping port 5672 - rabbitmq_container_id=$(docker run -d --name "${RABBITMQ_CONTAINER_NAME}" -p 5672:5672 "${RABBITMQ_IMAGE}") - - if [[ -z "${rabbitmq_container_id}" ]]; then - echo "ERROR: Failed to start RabbitMQ container." - exit 1 - fi - - echo "RabbitMQ container started successfully: ${rabbitmq_container_id}" - - # Allow RabbitMQ some time to initialize - sleep 20 - - # Check RabbitMQ health via rabbitmqctl - if docker exec "${RABBITMQ_CONTAINER_NAME}" rabbitmqctl status &>/dev/null; then - echo "RabbitMQ health check passed." - else - echo "ERROR: RabbitMQ health check failed." - exit 1 - fi - - echo "$rabbitmq_container_id" > "$WORKING_HOME/.rabbitmq-instance" - - echo "[INFO] Completed RabbitMQ container..." -} - # Define the local components and their corresponding ports local_components_ports_keys=("devsvc" "notification" "content" "central_storage" "authentication") local_components_ports_values=("8007" "8003" "8013" "8005" "8004") @@ -900,6 +753,8 @@ devbox_init_command() { local NOTIFICATION_IMAGE="$args_notification_image_image" # --notification-image-image local NOTIFICATION_TAG="$args_notification_image_tag" # --notification-image-tag + local CUSTOM_GIT_REPO="$args_custom_git_repo" # --custom-git-repo + # --force flag to overwrite existing resources local FORCE_INIT="${args_force}" @@ -931,6 +786,7 @@ devbox_init_command() { local NOTIFICATION_REPO="$(get_arg '--notification-image-repo')" local NOTIFICATION_IMAGE="$(get_arg '--notification-image-name')" local NOTIFICATION_TAG="$(get_arg '--notification-image-tag')" + local CUSTOM_GIT_REPO="$(get_arg '--custom-git-repo')" local FORCE_INIT="$(get_arg '--force')" @@ -1167,10 +1023,12 @@ devbox_init_command() { echo "==> [INIT] Starting Freeleaps services... Use Local component $USE_LOCAL_COMPONENT" +export ARCH="$ARCH" +export WORKING_HOME="$WORKING_HOME" if [[ "$(lower "$USE_LOCAL_COMPONENT")" == "true" ]]; then echo ' ===> Using local components for Freeleaps services.' - export ARCH="$ARCH" + export DEVSVC_IMAGE_TAG="$DEVSVC_TAG" export CONTENT_IMAGE_TAG="$CONTENT_TAG" export CENTRAL_STORAGE_IMAGE_TAG="$CENTRAL_STORAGE_TAG" @@ -1218,6 +1076,9 @@ else echo "$rabbitmq_container_id" > "$WORKING_HOME/.rabbitmq-instance" fi +# Save $USE_LOCAL_COMPONENT false/true to $WORKING_HOME/.use-local-component +echo "$USE_LOCAL_COMPONENT" > "$WORKING_HOME/.use-local-component" + pushd $WORKING_HOME # Make a user input (Y/N) to continue pull freeleaps.com code and start if N then exit @@ -1261,23 +1122,23 @@ if [[ "\$(lower "\$USE_LOCAL_COMPONENT")" == "true" ]]; then cat << 'EOFinner' > /home/.devbox/freeleaps/apps/.env # Online endpoint info export MONGODB_NAME=freeleaps2 - export MONGODB_URI=mongodb://\$DEFAULT_IP:27017/ + export MONGODB_URI=mongodb://freeleaps2-mongodb:27017/ export MONGODB_PORT=27017 export BLOB_STORE_CONNECTION_STR="DefaultEndpointsProtocol=https;AccountName=freeleaps1static;AccountKey=SIk7S3RviJxl1XhGiDZKA3cvzfxNrSbsBMfJ3EbKTsKPeMwhy8FTLpJliRLzQVE6uaSX8giDYw2h+ASt5MmHxQ==;EndpointSuffix=core.windows.net" export RABBITMQ_HOSTNAME=freeleaps2 - export RABBITMQ_HOST=\$DEFAULT_IP + export RABBITMQ_HOST=freeleaps2-rabbitmq export RABBITMQ_PORT=5672 export FREELEAPS_ENV=dev export STRIPE_API_KEY=sk_test_51Ogsw5B0IyqaSJBrwczlr820jnmvA1qQQGoLZ2XxOsIzikpmXo4pRLjw4XVMTEBR8DdVTYySiAv1XX53Zv5xqynF00GfMqttFd export STRIPE_WEBHOOK_SECRET=whsec_S6ZWjSAdR5Cpsn2USH6ZRBqbdBIENjTC export STRIPE_ACCOUNT_WEBHOOK_SECRET=whsec_PgPnkWGhEUiQfnV8aIb5Wmruz7XETJLm - export SITE_URL_ROOT=http://\$DEFAULT_IP/ - export FREELEAPS_DEVSVC_ENDPOINT=http://\$DEFAULT_IP:8007/api/devsvc/ - export FREELEAPS_CONTENT_ENDPOINT=http://\$DEFAULT_IP:8013/api/content/ - export FREELEAPS_NOTIFICATION_ENDPOINT=http://\$DEFAULT_IP:8003/api/notification/ - export FREELEAPS_CENTRAL_STORAGE_ENDPOINT=http://\$DEFAULT_IP:8005/api/central_storage/ - export FREELEAPS_AUTHENTICATION_ENDPOINT=http://\$DEFAULT_IP:8004/api/auth/ - export FREELEAPS_AILAB_ENDPOINT=https://as010-w2-re-vm.mathmast.com:8009/api/ + export SITE_URL_ROOT=http://localhost + export FREELEAPS_DEVSVC_ENDPOINT=http://localhost:8007/api/devsvc/ + export FREELEAPS_CONTENT_ENDPOINT=http://localhost:8013/api/content/ + export FREELEAPS_NOTIFICATION_ENDPOINT=http://localhost:8003/api/notification/ + export FREELEAPS_CENTRAL_STORAGE_ENDPOINT=http://localhost:8005/api/central_storage/ + export FREELEAPS_AUTHENTICATION_ENDPOINT=http://localhost:8004/api/auth/ + export FREELEAPS_AILAB_ENDPOINT=https://localhost:8009/api/ export KAFKA_SERVER_URL='' export EMAIL_FROM=freeleaps@freeleaps.com EOFinner @@ -1463,6 +1324,7 @@ echo "Freeleaps services started successfully" EOF + # ------------------------------------------------------------------- # 10. Final notification # ------------------------------------------------------------------- @@ -1505,6 +1367,7 @@ devbox_deinit_command() { if [[ "$CLEAR_LOGS" == "true" ]]; then echo "==> Clearing logs in $WORKING_HOME/logs..." rm -rf "$WORKING_HOME/logs"/* 2>/dev/null || true + ls -l "$WORKING_HOME/logs" else echo "==> Skipping log clearing." fi @@ -1577,6 +1440,9 @@ devbox_deinit_command() { fi done + # Remove the use-local-component file + rm -f "$WORKING_HOME/.use-local-component" + echo "==> DevBox deinitialization completed." } @@ -1585,6 +1451,7 @@ devbox_start_command() { local COMPONENT="$(get_arg '--component')" local WORKING_HOME="$(get_arg '--working-home' "${HOME}/.devbox")" + local FREELEAPS_ENDPOINT="$(get_arg '--freeleaps-endpoint')" # Check if the DevBox container is running local devbox_container_id_file_path="${WORKING_HOME}/.devbox-instance" @@ -1610,16 +1477,59 @@ devbox_start_command() { echo "==> DevBox container is already running." fi - # If no component is specified, start all components - if [[ -z "$COMPONENT" ]]; then - COMPONENTS=("mongodb" "rabbitmq" "backend" "frontend" "devsvc" "content" "central_storage" "authentication") + # Check if use local component + if [[ -f "$WORKING_HOME/.use-local-component" ]]; then + USE_LOCAL_COMPONENT=$(cat "$WORKING_HOME/.use-local-component") else - COMPONENTS=("$COMPONENT") + USE_LOCAL_COMPONENT="false" fi + if [[ "$USE_LOCAL_COMPONENT" == "true" ]]; then + # If no component is specified, start all components + if [[ -z "$COMPONENT" ]]; then + COMPONENTS=("mongodb" "rabbitmq" "devbox" "devsvc" "notification" "content" "central_storage" "authentication") + else + COMPONENTS=("$COMPONENT") + fi + else + # If no component is specified, start all components + if [[ -z "$COMPONENT" ]]; then + COMPONENTS=("mongodb" "rabbitmq" "devbox") + else + if [[ "$COMPONENT" == "devsvc" || "$COMPONENT" == "notification" || "$COMPONENT" == "content" || "$COMPONENT" == "central_storage" || "$COMPONENT" == "authentication" ]]; then + echo "ERROR: Remote component $COMPONENT cannot be restarted." + exit 1 + fi + + COMPONENTS=("$COMPONENT") + fi + fi + + # Start the specified components for comp in "${COMPONENTS[@]}"; do case "$comp" in + "gitea") + echo "==> Starting Gitea..." + # Check if Gitea container file path + local gitea_container_id_file_path="${WORKING_HOME}/.gitea-instance" + if [[ ! -f "$gitea_container_id_file_path" ]]; then + echo "ERROR: Gitea container is not running. Please run 'devbox init' first." + else + local gitea_container_id=$(cat "$gitea_container_id_file_path") + if ! docker ps --no-trunc --format '{{.ID}}' | grep -q "^${gitea_container_id}\$"; then + echo "==> Gitea container is not running, starting container..." + # Start the container + if ! docker start "${gitea_container_id}"; then + echo "ERROR: Failed to start Gitea container." + exit 1 + fi + echo "==> Gitea container started successfully." + else + echo "==> Gitea container is already running." + fi + fi + ;; "mongodb") echo "==> Starting MongoDB..." # Check if MongoDB container file path @@ -1662,174 +1572,28 @@ devbox_start_command() { fi fi ;; - "backend") - echo "==> Starting backend service..." - # start the backend service - docker exec -i "$devbox_container_id" bash < /dev/null; then - echo "Backend service is already running." -else - # Remove the .backend.pid file - rm -f /home/.devbox/.backend.pid - - echo '============================================' - echo 'Start to run start_webapi.sh' - echo '============================================' - pushd /home/.devbox/freeleaps/apps - ./start_webapi.sh > /home/.devbox/logs/backend.logs 2>&1 & - BACKEND_PID=\$! - - # Save BACKEND_PID to a file \${WORKING_HOME}/.frontend.pid: Stores the process id of frontend process. - echo "\$BACKEND_PID" > /home/.devbox/.backend.pid - - echo '============================================' - echo 'Check if the WebAPI service started successfully' - echo '============================================' - - sleep 30 - - # 30 attempts, 5 seconds each, total wait time 2.5 minutes - MAX_ATTEMPTS=30 - ATTEMPT=0 - - # Check if \$DEVBOX_BACKEND_PORT exists - DEVBOX_BACKEND_PORT=\$(cat /home/.devbox/.devbox-backend-port) - if [ -z "\$DEVBOX_BACKEND_PORT" ]; then - echo "ERROR: DEVBOX_BACKEND_PORT is not set." - export DEVBOX_BACKEND_PORT=8002 - fi - - echo "Waiting for WebAPI service to become healthy..." - - while [ \$ATTEMPT -lt \$MAX_ATTEMPTS ]; do - HTTP_CODE=\$(curl -s -o /dev/null -w "%{http_code}" "http://localhost:\$DEVBOX_BACKEND_PORT/docs") - # Check HTTP Code 200 - if [ "\$HTTP_CODE" -eq 200 ]; then - echo "Backend Swagger UI is available at \$URL (HTTP \$HTTP_CODE)" - break - else - echo "Waiting for Swagger UI to become available... Attempt \$((ATTEMPT+1))" - ATTEMPT=\$((ATTEMPT+1)) - sleep 5 # Wait 5 seconds - fi - done - - if [ \$ATTEMPT -eq \$MAX_ATTEMPTS ]; then - echo "ERROR: WebAPI failed to start after \$MAX_ATTEMPTS attempts" - exit 1 - fi -fi -EOF - - ;; - "frontend") - echo "==> Starting frontend service..." - # Start the frontend service - docker exec -i "$devbox_container_id" bash < /dev/null; then - echo "Frontend service is already running." - exit 0 - fi - fi - - # Remove the .frontend.pid file before starting the frontend service - rm -f /home/.devbox/.frontend.pid - fi - echo '============================================' - echo ' Start frontend service locally' - echo '============================================' - pushd /home/.devbox/freeleaps/frontend - - # Check if npm is installed and pnpm is installed and is npm run dev result is generated - if ! command -v npm &>/dev/null; then - echo "ERROR: npm is not installed." - exit 1 - fi - - if ! command -v pnpm &>/dev/null; then - echo "ERROR: pnpm is not installed." - exit 1 - fi - - if [ ! -f "package.json" ]; then - echo "ERROR: package.json not found." - exit 1 - fi - - # Start the frontend service with nohup in order to keep it running after the SSH session is closed - # Save the process ID of the frontend service - - nohup npm run dev > /home/.devbox/logs/frontend.logs 2>&1 & - FRONTEND_PID=\$! - - echo "npm run dev has been started with PID: \$FRONTEND_PID" - echo "\$FRONTEND_PID" > /home/.devbox/.frontend.pid - - # Wait for the frontend service to start - sleep 10 - - # 30 attempts, 10 seconds each, total wait time 5 minutes - MAX_ATTEMPTS=30 - ATTEMPT=0 - - DEVBOX_FRONTEND_PORT=\$(cat /home/.devbox/.devbox-frontend-port) - # get DEVBOX_FRONTEND_PORT from environment variables - if [ -z "\$DEVBOX_FRONTEND_PORT" ]; then - echo "ERROR: DEVBOX_FRONTEND_PORT is not set." - export DEVBOX_FRONTEND_PORT=5173 - fi - - echo "Waiting for Frontend service to start..." - while [ \$ATTEMPT -lt \$MAX_ATTEMPTS ]; do - HTTP_CODE=\$(curl -s -o /dev/null -w "%{http_code}" "http://localhost:\$DEVBOX_FRONTEND_PORT/") - # Check HTTP Code 200 - if [ "\$HTTP_CODE" -eq 200 ]; then - echo "Frontend is available (HTTP \$HTTP_CODE)" - break + "devbox") + echo "==> Starting DevBox..." + # Check if DevBox container file path + local devbox_container_id_file_path="${WORKING_HOME}/.devbox-instance" + if [[ ! -f "$devbox_container_id_file_path" ]]; then + echo "ERROR: DevBox container is not running. Please run 'devbox init' first." else - echo "Waiting for Frontend to become available... (http://localhost:\$DEVBOX_FRONTEND_PORT), (HTTP \$HTTP_CODE) Attempt \$((ATTEMPT+1))" - ATTEMPT=\$((ATTEMPT+1)) - sleep 10 + local devbox_container_id=$(cat "$devbox_container_id_file_path") + if ! docker ps --no-trunc --format '{{.ID}}' | grep -q "^${devbox_container_id}\$"; then + echo "==> DevBox container is not running, starting container..." + # Start the container + if ! docker start "${devbox_container_id}"; then + echo "ERROR: Failed to start DevBox container." + exit 1 + fi + echo "==> DevBox container started successfully." + else + echo "==> DevBox container is already running." + fi fi - done - - if [ \$ATTEMPT -eq \$MAX_ATTEMPTS ]; then - echo "ERROR: Frontend failed to start after \$MAX_ATTEMPTS attempts" - exit 1 - fi -EOF ;; - "devsvc" | "content" | "central_storage" | "authentication") + "devsvc" | "notification" | "content" | "central_storage" | "authentication") echo "==> Starting $comp service..." # Check if the component container file exists local component_container_id_file_path="${WORKING_HOME}/.${comp}-instance" @@ -1857,11 +1621,92 @@ EOF esac done - # If the frontend component is started, print the URL - if [[ " ${COMPONENTS[@]} " =~ " frontend " ]]; then - echo "==> Frontend started. You can access the Freeleaps web application at: http://localhost:5173" + if [[ "$FREELEAPS_ENDPOINT" == "true" ]]; then + # Start the backend and frontend services + docker exec -i "$devbox_container_id" bash < /home/.devbox/logs/backend.logs 2>&1 & +BACKEND_PID=\$! + +# Save BACKEND_PID to a file \${WORKING_HOME}/.backend.pid: Stores the process id of backend process. +echo "\$BACKEND_PID" > /home/.devbox/.backend.pid + +# Check if the backend service started successfully +sleep 10 +if ! ps -p "\$BACKEND_PID" &>/dev/null; then + echo "ERROR: Backend service failed to start." + exit 1 +fi + +# Start the frontend service + +echo '============================================' +echo ' Start frontend service locally' +echo '============================================' +pushd /home/.devbox/freeleaps/frontend + +npm run dev > /home/.devbox/logs/frontend.logs 2>&1 & +FRONTEND_PID=\$! + +echo "\$FRONTEND_PID" > /home/.devbox/.frontend.pid + +# Check if the frontend service started successfully +sleep 10 +if ! ps -p "\$FRONTEND_PID" &>/dev/null; then + echo "ERROR: Frontend service failed to start." + exit 1 +fi + +# Test backend and frontend services +echo "Testing backend and frontend services..." + +# Test the backend service +echo "Testing backend service..." +curl -s -o /dev/null -w "%{http_code}" "http://localhost:\$SERVICE_API_ACCESS_PORT/docs" +if [ "\$?" -ne 0 ]; then + echo "ERROR: Backend service is not available." + exit 1 +fi + +# Test the frontend service + +echo "Testing frontend service..." +curl -s -o /dev/null -w "%{http_code}" "http://localhost:5173/" +if [ "\$?" -ne 0 ]; then + echo "ERROR: Frontend service is not available." + exit 1 +fi + +echo "Backend and frontend services started successfully." +EOF fi + + echo "==> DevBox services started successfully." } @@ -1873,7 +1718,7 @@ devbox_stop_command() { # If the DevBox container is not running, exit if [[ -z "$COMPONENT" ]]; then - COMPONENTS=("mongodb" "rabbitmq" "backend" "frontend" "devsvc" "content" "central_storage" "authentication") + COMPONENTS=("mongodb" "rabbitmq" "devbox" "devsvc" "notification" "content" "central_storage" "authentication") else COMPONENTS=("$COMPONENT") fi @@ -1901,27 +1746,21 @@ devbox_stop_command() { echo "==> RabbitMQ container is not running." fi ;; - "backend") - echo "==> Stopping backend service..." + "devbox") + echo "==> Stopping devbox..." if [[ -f "${WORKING_HOME}/.devbox-instance" ]]; then local container_id container_id=$(cat "${WORKING_HOME}/.devbox-instance") docker stop "$container_id" &>/dev/null || true + # Remove the frontend and backend pid files + rm -f "${WORKING_HOME}/.backend.pid" + rm -f "${WORKING_HOME}/.frontend.pid" else echo "==> Backend service is not running." fi ;; - "frontend") - echo "==> Stopping frontend service..." - if [[ -f "${WORKING_HOME}/.devbox-instance" ]]; then - local container_id - container_id=$(cat "${WORKING_HOME}/.devbox-instance") - docker stop "$container_id" &>/dev/null || true - else - echo "==> Frontend service is not running." - fi - ;; - "devsvc" | "content" | "central_storage" | "authentication") + + "devsvc" | "notification" | "content" | "central_storage" | "authentication") echo "==> Stopping $comp service..." if [[ -f "${WORKING_HOME}/.${comp}-instance" ]]; then local container_id @@ -1962,10 +1801,9 @@ devbox_status_command() { exit 1 fi - # If no component is specified, check all components if [[ -z "$COMPONENT" ]]; then - COMPONENTS=("mongodb" "rabbitmq" "backend" "frontend" "devsvc" "content" "central_storage" "authentication") + COMPONENTS=("mongodb" "rabbitmq" "devbox" "devsvc" "notification" "content" "central_storage" "authentication") else COMPONENTS=("$COMPONENT") fi @@ -2003,107 +1841,36 @@ devbox_status_command() { fi ;; - "backend") - echo "==> Checking backend service status..." + "devbox") + echo "==> Checking devbox service status..." if [[ -f "${WORKING_HOME}/.devbox-instance" ]]; then local container_id container_id=$(cat "${WORKING_HOME}/.devbox-instance") if docker ps --no-trunc --format '{{.ID}}' | grep -q "^${container_id}\$"; then - if [[ -f "${WORKING_HOME}/.backend.pid" ]]; then - local backend_pid - backend_pid=$(cat "${WORKING_HOME}/.backend.pid") - if docker exec -i "$container_id" ps -p "$backend_pid" &>/dev/null; then - echo "[RESULT]: Backend service is running." - else - echo "[RESULT]: Backend service is not running." - fi - else - echo "[RESULT]: Backend service is not running." - fi + echo "[RESULT]: devbox container is running." else - echo "[RESULT]: Backend service is not running." - fi - fi - ;; - - "frontend") - echo "==> Checking frontend service status..." - if [[ -f "${WORKING_HOME}/.devbox-instance" ]]; then - local container_id - container_id=$(cat "${WORKING_HOME}/.devbox-instance") - if docker ps --no-trunc --format '{{.ID}}' | grep -q "^${container_id}\$"; then - if [[ -f "${WORKING_HOME}/.frontend.pid" ]]; then - local frontend_pid - frontend_pid=$(cat "${WORKING_HOME}/.frontend.pid") - if docker exec -i "$container_id" ps -p "$frontend_pid" &>/dev/null; then - echo "[RESULT]: Frontend service is running." - else - echo "[RESULT]: Frontend service is not running." - fi - else - echo "[RESULT]: Frontend service is not running." - fi - else - echo "[RESULT]: Frontend service is not running." - fi - fi - ;; - "devsvc") - echo "==> Checking devsvc service status..." - if [[ -f "${WORKING_HOME}/.devsvc-instance" ]]; then - local container_id - container_id=$(cat "${WORKING_HOME}/.devsvc-instance") - if docker ps --no-trunc --format '{{.ID}}' | grep -q "^${container_id}\$"; then - echo "[RESULT]: devsvc container is running." - else - echo "[RESULT]: devsvc container is not running." + echo "[RESULT]: devbox container is not running." fi else - echo "[RESULT]: devsvc container is not running." + echo "[RESULT]: devbox container is not running." fi ;; - "content") - echo "==> Checking content service status..." - if [[ -f "${WORKING_HOME}/.content-instance" ]]; then + + "devsvc" | "notification" | "content" | "central_storage" | "authentication") + echo "==> Checking $comp service status..." + if [[ -f "${WORKING_HOME}/.${comp}-instance" ]]; then local container_id - container_id=$(cat "${WORKING_HOME}/.content-instance") + container_id=$(cat "${WORKING_HOME}/.${comp}-instance") if docker ps --no-trunc --format '{{.ID}}' | grep -q "^${container_id}\$"; then - echo "[RESULT]: content container is running." + echo "[RESULT]: $comp service is running." else - echo "[RESULT]: content container is not running." + echo "[RESULT]: $comp service is not running." fi else - echo "[RESULT]: content container is not running." - fi - ;; - "central_storage") - echo "==> Checking central_storage service status..." - if [[ -f "${WORKING_HOME}/.central_storage-instance" ]]; then - local container_id - container_id=$(cat "${WORKING_HOME}/.central_storage-instance") - if docker ps --no-trunc --format '{{.ID}}' | grep -q "^${container_id}\$"; then - echo "[RESULT]: central_storage container is running." - else - echo "[RESULT]: central_storage container is not running." - fi - else - echo "[RESULT]: central_storage container is not running." - fi - ;; - "authentication") - echo "==> Checking authentication service status..." - if [[ -f "${WORKING_HOME}/.authentication-instance" ]]; then - local container_id - container_id=$(cat "${WORKING_HOME}/.authentication-instance") - if docker ps --no-trunc --format '{{.ID}}' | grep -q "^${container_id}\$"; then - echo "[RESULT]: authentication container is running." - else - echo "[RESULT]: authentication container is not running." - fi - else - echo "[RESULT]: authentication container is not running." + echo "[RESULT]: $comp service is not running." fi ;; + *) echo "ERROR: Unknown component: $comp" exit 1 @@ -2118,6 +1885,7 @@ devbox_restart_command() { echo "==> Restarting DevBox services..." local COMPONENT="$(get_arg '--component')" local WORKING_HOME="$(get_arg '--working-home' "${HOME}/.devbox")" + local FREELEAPS_ENDPOINT="$(get_arg '--freeleaps-endpoint')" # Check devbox container file path local devbox_container_id_file_path="${WORKING_HOME}/.devbox-instance" @@ -2141,15 +1909,42 @@ devbox_restart_command() { sleep 20 fi - if [[ -z "$COMPONENT" ]]; then - COMPONENTS=("mongodb" "rabbitmq" "backend" "frontend" "devsvc" "content" "central_storage" "authentication") + # Check if current environment is using local components + USE_LOCAL_COMPONENT=$(cat "${WORKING_HOME}/.use-local-component" 2>/dev/null || true) + if [[ "$USE_LOCAL_COMPONENT" == "true" ]]; then + echo "==> Using local components..." + if [[ -z "$COMPONENT" ]]; then + COMPONENTS=("gitea" "mongodb" "rabbitmq" "devbox" "devsvc" "notification" "content" "central_storage" "authentication") + else + COMPONENTS=("$COMPONENT") + fi else - COMPONENTS=("$COMPONENT") + echo "==> Using remote components..." + if [[ -z "$COMPONENT" ]]; then + COMPONENTS=("mongodb" "rabbitmq" "devbox") + else + if [[ "$COMPONENT" == "devsvc" || "$COMPONENT" == "notification" || "$COMPONENT" == "content" || "$COMPONENT" == "central_storage" || "$COMPONENT" == "authentication" ]]; then + echo "ERROR: Remote component $COMPONENT cannot be restarted." + exit 1 + fi + + COMPONENTS=("$COMPONENT") + fi fi # Stop the specified components for comp in "${COMPONENTS[@]}"; do case "$comp" in + "gitea") + echo "==> Stopping Gitea..." + if [[ -f "${WORKING_HOME}/.gitea-instance" ]]; then + local container_id + container_id=$(cat "${WORKING_HOME}/.gitea-instance") + docker stop "$container_id" &>/dev/null || true + else + echo "==> Gitea container is not running." + fi + ;; "mongodb") echo "==> Stopping MongoDB..." if [[ -f "${WORKING_HOME}/.mongodb-instance" ]]; then @@ -2170,27 +1965,22 @@ devbox_restart_command() { echo "==> RabbitMQ container is not running." fi ;; - "backend") - echo "==> Stopping backend service..." + "devbox") + echo "==> Stopping devbox service..." if [[ -f "${WORKING_HOME}/.devbox-instance" ]]; then local container_id container_id=$(cat "${WORKING_HOME}/.devbox-instance") docker stop "$container_id" &>/dev/null || true + + # Remove the frontend and backend pid files + rm -f "${WORKING_HOME}/.backend.pid" + rm -f "${WORKING_HOME}/.frontend.pid" else - echo "==> Backend service is not running." + echo "==> Devbox is not running." fi ;; - "frontend") - echo "==> Stopping frontend service..." - if [[ -f "${WORKING_HOME}/.devbox-instance" ]]; then - local container_id - container_id=$(cat "${WORKING_HOME}/.devbox-instance") - docker stop "$container_id" &>/dev/null || true - else - echo "==> Frontend service is not running." - fi - ;; - "devsvc" | "content" | "central_storage" | "authentication") + + "devsvc" | "notification" | "content" | "central_storage" | "authentication") echo "==> Stopping $comp service..." if [[ -f "${WORKING_HOME}/.${comp}-instance" ]]; then local container_id @@ -2210,6 +2000,16 @@ devbox_restart_command() { # Start the specified components for comp in "${COMPONENTS[@]}"; do case "$comp" in + "gitea") + echo "==> Restarting Gitea..." + if [[ -f "${WORKING_HOME}/.gitea-instance" ]]; then + local container_id + container_id=$(cat "${WORKING_HOME}/.gitea-instance") + docker start "$container_id" &>/dev/null || true + else + echo "==> Gitea container is not running." + fi + ;; "mongodb") echo "==> Restarting MongoDB..." if [[ -f "${WORKING_HOME}/.mongodb-instance" ]]; then @@ -2230,164 +2030,17 @@ devbox_restart_command() { echo "==> RabbitMQ container is not running." fi ;; - "backend") - echo "==> Restarting backend service..." + "devbox") + echo "==> Restarting devbox service..." if [[ -f "${WORKING_HOME}/.devbox-instance" ]]; then local container_id container_id=$(cat "${WORKING_HOME}/.devbox-instance") docker start "$container_id" &>/dev/null || true - - # Start backend service in the container - docker exec -i "$devbox_container_id" bash < /dev/null; then - echo "Backend service is already running." -else - echo '============================================' - echo 'Start to run start_webapi.sh' - echo '============================================' - pushd /home/.devbox/freeleaps/apps - ./start_webapi.sh > /home/.devbox/logs/backend.logs 2>&1 & - BACKEND_PID=\$! - - # Save BACKEND_PID to a file \${WORKING_HOME}/.frontend.pid: Stores the process id of frontend process. - echo "\$BACKEND_PID" > /home/.devbox/.backend.pid - - echo '============================================' - echo 'Check if the WebAPI service started successfully' - echo '============================================' - - sleep 30 - - # 30 attempts, 5 seconds each, total wait time 2.5 minutes - MAX_ATTEMPTS=30 - ATTEMPT=0 - - # Check if \$DEVBOX_BACKEND_PORT exists - if [ -z "\$DEVBOX_BACKEND_PORT" ]; then - echo "WARNING: DEVBOX_BACKEND_PORT is not set." - export DEVBOX_BACKEND_PORT=8002 - fi - - echo "DEVBOX_BACKEND_PORT: \$DEVBOX_BACKEND_PORT" - echo "Waiting for WebAPI service to become healthy..." - - while [ \$ATTEMPT -lt \$MAX_ATTEMPTS ]; do - HTTP_CODE=\$(curl -s -o /dev/null -w "%{http_code}" "http://localhost:\$DEVBOX_BACKEND_PORT/docs") - # Check HTTP Code 200 - if [ "\$HTTP_CODE" -eq 200 ]; then - echo "Backend Swagger UI is available at \$URL (HTTP \$HTTP_CODE)" - break - else - echo "Waiting for Swagger UI to become available... Attempt \$((ATTEMPT+1))" - ATTEMPT=\$((ATTEMPT+1)) - sleep 5 # Wait 5 seconds - fi - done - - if [ \$ATTEMPT -eq \$MAX_ATTEMPTS ]; then - echo "ERROR: WebAPI failed to start after \$MAX_ATTEMPTS attempts" - exit 1 - fi -fi -EOF - else - echo "==> Backend service is not running." + echo "==> Devbox is not running." fi ;; - "frontend") - echo "==> Restarting frontend service..." - if [[ -f "${WORKING_HOME}/.devbox-instance" ]]; then - local container_id - container_id=$(cat "${WORKING_HOME}/.devbox-instance") - docker start "$container_id" &>/dev/null || true - - # Start frontend service in the container - docker exec -i "$DEVBOX_NAME" bash < /dev/null; then - echo "Frontend service is already running." - exit 0 - else - # Remove the frontend.pid file - rm -f /home/.devbox/.frontend.pid - fi - fi - - echo '============================================' - echo ' Start frontend service locally' - echo '============================================' - pushd /home/.devbox/freeleaps/frontend - - # Check if npm is installed and pnpm is installed and is npm run dev result is generated - if ! command -v npm &>/dev/null; then - echo "ERROR: npm is not installed." - exit 1 - fi - - if ! command -v pnpm &>/dev/null; then - echo "ERROR: pnpm is not installed." - exit 1 - fi - - if [ ! -f "package.json" ]; then - echo "ERROR: package.json not found." - exit 1 - fi - - # Start the frontend service with nohup in order to keep it running after the SSH session is closed - # Save the process ID of the frontend service - nohup npm run dev > /home/.devbox/logs/frontend.logs 2>&1 & - FRONTEND_PID=\$! - - echo "npm run dev has been started with PID: \$FRONTEND_PID" - echo "\$FRONTEND_PID" > /home/.devbox/.frontend.pid - - # Wait for the frontend service to start - sleep 30 - - # 30 attempts, 10 seconds each, total wait time 5 minutes - MAX_ATTEMPTS=30 - ATTEMPT=0 - - # Check if \$DEVBOX_FRONTEND_PORT exists - if [ -z "\$DEVBOX_FRONTEND_PORT" ]; then - echo "ERROR: DEVBOX_FRONTEND_PORT is not set." - export DEVBOX_FRONTEND_PORT=5173 - fi - - echo "Waiting for Frontend service to start..." - while [ \$ATTEMPT -lt \$MAX_ATTEMPTS ]; do - HTTP_CODE=\$(curl -s -o /dev/null -w "%{http_code}" "http://localhost:\$DEVBOX_FRONTEND_PORT/") - # Check HTTP Code 200 - if [ "\$HTTP_CODE" -eq 200 ]; then - echo "Frontend is available (HTTP \$HTTP_CODE)" - break - else - echo "Waiting for Frontend to become available... (http://localhost:\$DEVBOX_FRONTEND_PORT), (HTTP \$HTTP_CODE) Attempt \$((ATTEMPT+1))" - ATTEMPT=\$((ATTEMPT+1)) - sleep 10 - fi - done - - if [ \$ATTEMPT -eq \$MAX_ATTEMPTS ]; then - echo "ERROR: Frontend failed to start after \$MAX_ATTEMPTS attempts" - exit 1 - fi -EOF - else - echo "==> Frontend service is not running." - fi - ;; - "devsvc" | "content" | "central_storage" | "authentication") + "devsvc" | "notification" | "content" | "central_storage" | "authentication") echo "==> Restarting $comp service..." if [[ -f "${WORKING_HOME}/.${comp}-instance" ]]; then local container_id @@ -2404,6 +2057,90 @@ EOF esac done +if [[ "$FREELEAPS_ENDPOINT" == "true" ]]; then + # Start the backend and frontend services + docker exec -i "$devbox_container_id" bash < /home/.devbox/logs/backend.logs 2>&1 & +BACKEND_PID=\$! + +# Save BACKEND_PID to a file \${WORKING_HOME}/.backend.pid: Stores the process id of backend process. +echo "\$BACKEND_PID" > /home/.devbox/.backend.pid + +# Check if the backend service started successfully +sleep 10 +if ! ps -p "\$BACKEND_PID" &>/dev/null; then + echo "ERROR: Backend service failed to start." + exit 1 +fi + +# Start the frontend service + +echo '============================================' +echo ' Start frontend service locally' +echo '============================================' +pushd /home/.devbox/freeleaps/frontend + +npm run dev > /home/.devbox/logs/frontend.logs 2>&1 & +FRONTEND_PID=\$! + +echo "\$FRONTEND_PID" > /home/.devbox/.frontend.pid + +# Check if the frontend service started successfully +sleep 10 +if ! ps -p "\$FRONTEND_PID" &>/dev/null; then + echo "ERROR: Frontend service failed to start." + exit 1 +fi + +# Test backend and frontend services +echo "Testing backend and frontend services..." + +# Test the backend service +echo "Testing backend service..." +curl -s -o /dev/null -w "%{http_code}" "http://localhost:\$SERVICE_API_ACCESS_PORT/docs" +if [ "\$?" -ne 0 ]; then + echo "ERROR: Backend service is not available." + exit 1 +fi + +# Test the frontend service + +echo "Testing frontend service..." +curl -s -o /dev/null -w "%{http_code}" "http://localhost:5173/" +if [ "\$?" -ne 0 ]; then + echo "ERROR: Frontend service is not available." + exit 1 +fi + +echo "Backend and frontend services started successfully." +EOF + fi + echo "==> DevBox services restarted successfully." } @@ -2863,18 +2600,6 @@ devbox_init_parse_requirements() { esac done - # :command.required_flags_filter - - if [[ -z "$(get_arg '--freeleaps-username')" ]]; then - - printf "missing required flag: --freeleaps-username FREELEAPS_USERNAME\n" >&2 - exit 1 - fi - if [[ -z "$(get_arg '--freeleaps-password')" ]]; then - printf "missing required flag: --freeleaps-password FREELEAPS_PASSWORD\n" >&2 - exit 1 - fi - # :command.default_assignments if [ -z "$(get_arg '--os')" ]; then @@ -3049,6 +2774,7 @@ devbox_start_parse_requirements() { devbox_start_usage exit ;; + *) break @@ -3078,6 +2804,19 @@ devbox_start_parse_requirements() { fi ;; + --freeleaps-endpoint) + + # :flag.case_arg + if [[ -n ${2+x} ]]; then + add_arg '--freeleaps-endpoint' "$2" + shift + shift + else + printf "%s\n" "--freeleaps-endpoint requires an argument: --freeleaps-endpoint FREELEAPS_ENDPOINT" >&2 + exit 1 + fi + ;; + -?*) printf "invalid option: %s\n" "$key" >&2 exit 1 @@ -3094,6 +2833,11 @@ devbox_start_parse_requirements() { esac done + # :command.default_assignments + if [ -z "$(get_arg '--freeleaps-endpoint')" ]; then + add_arg '--freeleaps-endpoint' "false" + fi + } # :command.parse_requirements @@ -3180,6 +2924,20 @@ devbox_status_parse_requirements() { while [[ $# -gt 0 ]]; do key="$1" case "$key" in + # :flag.case + --component) + + # :flag.case_arg + if [[ -n ${2+x} ]]; then + add_arg '--component' "$2" + shift + shift + else + printf "%s\n" "--component requires an argument: --component COMPONENT" >&2 + exit 1 + fi + ;; + -?*) printf "invalid option: %s\n" "$key" >&2 @@ -3225,6 +2983,31 @@ devbox_restart_parse_requirements() { while [[ $# -gt 0 ]]; do key="$1" case "$key" in + # :flag.case + --component) + + # :flag.case_arg + if [[ -n ${2+x} ]]; then + add_arg '--component' "$2" + shift + shift + else + printf "%s\n" "--component requires an argument: --component COMPONENT" >&2 + exit 1 + fi + ;; + --freeleaps-endpoint) + + # :flag.case_arg + if [[ -n ${2+x} ]]; then + add_arg '--freeleaps-endpoint' "$2" + shift + shift + else + printf "%s\n" "--freeleaps-endpoint requires an argument: --freeleaps-endpoint FREELEAPS_ENDPOINT" >&2 + exit 1 + fi + ;; -?*) printf "invalid option: %s\n" "$key" >&2 @@ -3242,6 +3025,11 @@ devbox_restart_parse_requirements() { esac done + # :command.default_assignments + if [ -z "$(get_arg '--freeleaps-endpoint')" ]; then + add_arg '--freeleaps-endpoint' "false" + fi + } diff --git a/devbox/devbox.local/docker-compose.dev.arm64.new.yaml b/devbox/devbox.local/docker-compose.dev.arm64.new.yaml index 734a663..5667519 100644 --- a/devbox/devbox.local/docker-compose.dev.arm64.new.yaml +++ b/devbox/devbox.local/docker-compose.dev.arm64.new.yaml @@ -11,7 +11,7 @@ services: - DISABLE_REGISTRATION=true - REQUIRE_SIGNIN_VIEW=true volumes: - - freeleaps2-gitea-data:/data + - ${WORKING_HOME}/freeleaps2-gitea/:/data networks: - devbox_freeleaps2-network @@ -25,7 +25,7 @@ services: ports: - "27017:27017" volumes: - - freeleaps2-mongodb-data:/data/db + - ${WORKING_HOME}/freeleaps2-mongodb-data:/data/db networks: - devbox_freeleaps2-network @@ -39,7 +39,7 @@ services: - "5672:5672" - "15672:15672" volumes: - - freeleaps2-rabbitmq-data:/var/lib/rabbitmq + - ${WORKING_HOME}/freeleaps2-rabbitmq-data:/var/lib/rabbitmq networks: - devbox_freeleaps2-network @@ -72,7 +72,7 @@ services: uvicorn webapi.main:app --reload --port=8007 --host=0.0.0.0 volumes: - type: bind - source: /var/lib/docker/app/devsvc/log + source: ${WORKING_HOME}/logs/devsvc target: /app/log/devsvc networks: - devbox_freeleaps2-network @@ -106,7 +106,7 @@ services: - devbox_freeleaps2-network volumes: - type: bind - source: /var/lib/docker/app/central_storage/log + source: ${WORKING_HOME}/logs/central_storage target: /app/log/central_storage authentication: @@ -140,7 +140,7 @@ services: - devbox_freeleaps2-network volumes: - type: bind - source: /var/lib/docker/app/authentication/log + source: ${WORKING_HOME}/logs/authentication target: /app/log/authentication content: @@ -171,7 +171,7 @@ services: - devbox_freeleaps2-network volumes: - type: bind - source: /var/lib/docker/app/content/log + source: ${WORKING_HOME}/logs/content target: /app/log/content notification: @@ -207,7 +207,7 @@ services: - devbox_freeleaps2-network volumes: - type: bind - source: /var/lib/docker/app/notification/log + source: ${WORKING_HOME}/logs/notification target: /app/log/notification volumes: