#!/usr/bin/env sh # Build and start the MyOffice demo stack (SPA + API + Postgres + pgAdmin). # Usage: # ./build.sh # front 32080, back 32081, pgAdmin 32082 # ./build.sh 32080 32081 32082 # override ports # ./build.sh build | up | down | logs # ./build.sh rebuild # --no-cache images + recreate containers # ./build.sh reset # wipe DB volumes, rebuild, start set -eu cd "$(dirname "$0")" COMPOSE_FILE=docker-compose.demo.yml ACTION=all FRONT_PORT=32080 BACK_PORT=32081 PGADMIN_PORT=32082 is_port() { echo "$1" | grep -Eq '^[0-9]{1,5}$' && [ "$1" -ge 1 ] && [ "$1" -le 65535 ] } origin_for() { if [ "$1" = "80" ]; then echo "http://localhost" else echo "http://localhost:$1" fi } show_up_info() { echo "" echo "Demo is up:" echo " Frontend $1" echo " Backend $2" echo " pgAdmin $3 (admin@example.com / admin; DB auto-connected)" echo " Postgres internal host=postgres user/pass/db=myoffice" echo "" echo "Demo logins: user_UAH@user_UAH.userUAH / user_UAH (also USD, EUR)" } if [ "${1:-}" = "build" ] || [ "${1:-}" = "up" ] || [ "${1:-}" = "down" ] || [ "${1:-}" = "logs" ] || [ "${1:-}" = "all" ] || [ "${1:-}" = "rebuild" ] || [ "${1:-}" = "reset" ]; then ACTION=$1 shift fi if [ "${1:-}" != "" ]; then is_port "$1" || { echo "Invalid front port '$1'. Example: ./build.sh 32080 32081 32082" >&2; exit 1; } FRONT_PORT=$1 shift fi if [ "${1:-}" != "" ]; then is_port "$1" || { echo "Invalid back port '$1'. Example: ./build.sh 32080 32081 32082" >&2; exit 1; } BACK_PORT=$1 shift fi if [ "${1:-}" != "" ]; then is_port "$1" || { echo "Invalid pgAdmin port '$1'. Example: ./build.sh 32080 32081 32082" >&2; exit 1; } PGADMIN_PORT=$1 shift fi if [ "${1:-}" != "" ] && [ "$ACTION" != "down" ] && [ "$ACTION" != "logs" ]; then echo "Too many arguments. Usage: ./build.sh [build|up|down|logs|rebuild|reset] [frontPort] [backPort] [pgAdminPort]" >&2 exit 1 fi FRONT_ORIGIN=$(origin_for "$FRONT_PORT") API_PUBLIC_URL="http://localhost:$BACK_PORT" PGADMIN_URL=$(origin_for "$PGADMIN_PORT") export MYOFFICE_WEB_PORT=$FRONT_PORT export MYOFFICE_API_PORT=$BACK_PORT export MYOFFICE_PGADMIN_PORT=$PGADMIN_PORT export MYOFFICE_FRONTEND_HOST=$FRONT_ORIGIN export MYOFFICE_API_PUBLIC_URL=$API_PUBLIC_URL export MYOFFICE_CORS_0=$FRONT_ORIGIN if [ "$FRONT_PORT" = "80" ]; then export MYOFFICE_CORS_1=http://127.0.0.1 else export MYOFFICE_CORS_1="http://127.0.0.1:$FRONT_PORT" fi export COMPOSE_DOCKER_CLI_BUILD=1 export DOCKER_BUILDKIT=1 case "$ACTION" in build) docker compose -f "$COMPOSE_FILE" build ;; up) mkdir -p data/demo/postgres data/demo/pgadmin docker compose -f "$COMPOSE_FILE" up -d --build --force-recreate --remove-orphans show_up_info "$FRONT_ORIGIN" "$API_PUBLIC_URL" "$PGADMIN_URL" ;; down) docker compose -f "$COMPOSE_FILE" down ;; logs) docker compose -f "$COMPOSE_FILE" logs -f ;; rebuild) echo "Rebuilding images with --no-cache (api + web)..." docker compose -f "$COMPOSE_FILE" build --no-cache --pull docker compose -f "$COMPOSE_FILE" up -d --force-recreate --remove-orphans show_up_info "$FRONT_ORIGIN" "$API_PUBLIC_URL" "$PGADMIN_URL" ;; reset) echo "Stopping stack and wiping ./data/demo/postgres and ./data/demo/pgadmin..." docker compose -f "$COMPOSE_FILE" down rm -rf data/demo/postgres data/demo/pgadmin mkdir -p data/demo/postgres data/demo/pgadmin docker volume rm myoffice-demo_myoffice_pgdata myoffice-demo_myoffice_pgadmin 2>/dev/null || true echo "Rebuilding images with --no-cache..." docker compose -f "$COMPOSE_FILE" build --no-cache --pull docker compose -f "$COMPOSE_FILE" up -d --force-recreate --remove-orphans show_up_info "$FRONT_ORIGIN" "$API_PUBLIC_URL" "$PGADMIN_URL" echo "" echo "DB was reset. Login with password user_UAH (not user1_UAH)." echo "Data folders: Docker/data/demo/postgres , Docker/data/demo/pgadmin" ;; all) mkdir -p data/demo/postgres data/demo/pgadmin docker compose -f "$COMPOSE_FILE" up -d --build --force-recreate --remove-orphans show_up_info "$FRONT_ORIGIN" "$API_PUBLIC_URL" "$PGADMIN_URL" ;; *) echo "Unknown action '$ACTION'. Use: build, up, down, logs, rebuild, reset, or no args." >&2 exit 1 ;; esac