diff --git a/docker-compose.override.yaml b/docker-compose.override.yaml new file mode 100644 index 000000000..5efeeb69a --- /dev/null +++ b/docker-compose.override.yaml @@ -0,0 +1,12 @@ +# Overrides for dev environment +# This should automatically override the docker-compose.yaml file +# `docker-compose -f docker-compose.yaml -f docker-compose.prod.yaml up` +services: + frontend: + build: + context: ./frontend + container_name: frontend + volumes: + - ./frontend/src:/app/src + - ./frontend/.next:/app/.next + - ./frontend/node_modules:/app/node_modules diff --git a/docker-compose.prod.yaml b/docker-compose.prod.yaml new file mode 100644 index 000000000..9ce8ba8a7 --- /dev/null +++ b/docker-compose.prod.yaml @@ -0,0 +1,10 @@ +# Overrides for prod environment +# Merge this into the main docker-compose.yaml file using +# `docker-compose -f docker-compose.yaml -f docker-compose.prod.yaml up` +services: + frontend: + build: + context: ./frontend + container_name: frontend + volumes: + - ./frontend/src:/app/src diff --git a/docker-compose.yaml b/docker-compose.yaml index bc74ff3a2..5b76cf76e 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -1,3 +1,4 @@ +# Base compose file version: "3.8" services: api: @@ -106,10 +107,6 @@ services: env_file: .env ports: - "3000:3000" - volumes: - - ./frontend/src:/app/src - - ./frontend/.next:/app/.next - - ./frontend/node_modules:/app/node_modules environment: NEXT_PUBLIC_API_URL: ${NEXT_PUBLIC_API_URL} NEXT_PUBLIC_APP_ENV: ${NEXT_PUBLIC_APP_ENV} diff --git a/docs/installation.mdx b/docs/installation.mdx index 0204901e4..8cd348f79 100644 --- a/docs/installation.mdx +++ b/docs/installation.mdx @@ -31,12 +31,12 @@ Run the command below to start Tracecat and all related services. git clone git@github.com:TracecatHQ/tracecat.git cd tracecat chmod +x services.sh -bash services.sh start +bash services.sh start --env prod ``` - You can run `bash services.sh start --tail` to view the logs of all services - in real-time. + You can run `bash services.sh start --env prod --tail` to view the logs of all + services in real-time. You'll be prompted to enter your public facing Runner URL (you can set one up using ngrok), OpenAI API key, and Resend API key. @@ -95,7 +95,7 @@ You can view the API docs at `http://localhost:8000/docs` and the runner docs at To spin down all services, run the following command: ```bash -bash services.sh stop +bash services.sh stop --env prod ``` If you'd like to spin down specific services, you can pass additional options as such: @@ -109,6 +109,11 @@ bash services.sh stop --supabase # or -s, Stops Supabase services Running `bash services.sh start` will restart all services if they are already running. +## Runtime environment configuration + +Note that we've been passing `--env prod` flag to the `services.sh` script. This is to avoid having to install `npm` and `pnpm` on the host machine. +If you'd like to make code contributions or run the services in development mode, use `--env dev` instead or don't pass an environment flag (runs as `dev` by default). + ## Troubldshooting ### Docker networking diff --git a/services.sh b/services.sh index 69057ebfc..d72a81723 100755 --- a/services.sh +++ b/services.sh @@ -15,10 +15,18 @@ else NC='\033[0m' # No Color fi -# Initial COMMAND setup for docker compose -DOCKER_COMPOSE_UP_FLAGS="" +# Start services flags +DOCKER_COMPOSE_UP_FLAGS= +DOCKER_COMPOSE_COMMAND= TAIL_LOGS=false BUILD_SERVICES=false +ENVIRONMENT="dev" +REBUILD_NO_CACHE=false + +# Stop services flags +# Remove all by default +REMOVE_INTERNAL=true +REMOVE_SUPABASE=true dotenv_replace() { local env_var_name=$1 @@ -38,6 +46,22 @@ dotenv_replace() { eval sed $sed_option "s$delimiter^${env_var_name}=.*$delimiter${env_var_name}=${new_value}$delimiter" $file_path } +set_docker_compose_command() { + case $ENVIRONMENT in + dev) + DOCKER_COMPOSE_COMMAND="docker compose" + ;; + prod) + DOCKER_COMPOSE_COMMAND="docker compose -f docker-compose.yaml -f docker-compose.prod.yaml" + ;; + *) + echo -e "${RED}Invalid environment '${ENVIRONMENT}' specified. Please use 'dev' or 'prod'.${NC}" + exit 1 + ;; + esac + echo -e "${YELLOW}Using command '$DOCKER_COMPOSE_COMMAND'.${NC}" +} + # Function to handle start command start_services() { # Check for --tail flag in subsequent arguments. If not present, start services in detached mode. @@ -50,7 +74,6 @@ start_services() { DOCKER_COMPOSE_UP_FLAGS+=" --build" fi - echo -e "${YELLOW}Starting Tracecat application setup...${NC}" runner_url="" @@ -148,9 +171,27 @@ start_services() { echo -e "${GREEN}Anonymous key successfully extracted and added to the .env file.${NC}" fi + # 1. Stop the services if they are already running + if $DOCKER_COMPOSE_COMMAND down --remove-orphans; then + echo -e "${GREEN}Tracecat services stopped successfully.${NC}" + else + echo -e "${RED}Failed to stop Tracecat services. Please check the logs for more details.${NC}" + exit 1 + fi + # 2. Rebuild the services if the --build flag is set + if $REBUILD_NO_CACHE; then + if $DOCKER_COMPOSE_COMMAND build --no-cache; then + echo -e "${GREEN}Tracecat services rebuilt successfully.${NC}" + else + echo -e "${RED}Failed to rebuild Tracecat services. Please check the logs for more details.${NC}" + exit 1 + fi + fi + + # 3. Start the services echo -e "${YELLOW}Starting Tracecat services with docker compose flags '$DOCKER_COMPOSE_UP_FLAGS'.${NC}" - if docker compose down --remove-orphans && docker compose up $DOCKER_COMPOSE_UP_FLAGS; then + if $DOCKER_COMPOSE_COMMAND up $DOCKER_COMPOSE_UP_FLAGS; then echo -e "${GREEN}Tracecat local development setup started successfully.${NC}" echo -e "${BLUE}API URL:${NC} http://localhost:8000" echo -e "${BLUE}Runner URL:${NC} http://localhost:8001" @@ -158,13 +199,12 @@ start_services() { echo -e "${BLUE}External Runner URL:${NC} $runner_url" else echo -e "${RED}Failed to restart Tracecat services. Please check the logs for more details.${NC}" + exit 1 fi echo -e "${GREEN}Tracecat local development setup is complete.${NC}" } -# Remove all by default -REMOVE_INTERNAL=true -REMOVE_SUPABASE=true + # Function to handle stop command stop_services() { if [ $REMOVE_INTERNAL = true ]; then @@ -194,36 +234,30 @@ shift # Remove the first argument, leaving any additional arguments # Execute based on the action case $ACTION in start) - # Parse additional arguments - for arg in "$@" - do - case $arg in - --tail|-t) - TAIL_LOGS=true - ;; - esac - case $arg in - --build|-b) - BUILD_SERVICES=true - ;; + while (( "$#" )); do + case "$1" in + -t | --tail ) TAIL_LOGS=true; shift ;; + -b | --build ) BUILD_SERVICES=true; shift ;; + -n | --no-cache ) REBUILD_NO_CACHE=true; shift ;; + -e | --env ) ENVIRONMENT="$2"; shift 2 ;; + * ) echo -e "${RED}Unknown flag '$1', Stopping.${NC}"; exit 1 ;; esac done + echo -e "${YELLOW}Environment: $ENVIRONMENT${NC}" + set_docker_compose_command start_services ;; stop) - for arg in "$@" - do - case $arg in - --supabase|-s) - REMOVE_INTERNAL=false - ;; - esac - case $arg in - --internal|-i) - REMOVE_SUPABASE=false - ;; + while (( "$#" )); do + case "$1" in + -s | --supabase ) REMOVE_INTERNAL=false; shift ;; + -i | --internal ) REMOVE_SUPABASE=false; shift ;; + -e | --env ) ENVIRONMENT="$2"; shift 2 ;; + * ) echo -e "${RED}Unknown flag '$1', Stopping.${NC}"; exit 1 ;; esac done + echo -e "${YELLOW}Environment: $ENVIRONMENT${NC}" + set_docker_compose_command stop_services ;; *)