From 07a97afee5e16a8b5d536ecc7742311edadc9f9a Mon Sep 17 00:00:00 2001 From: Roy Duineveld Date: Thu, 9 Jul 2026 10:12:29 +0200 Subject: [PATCH 1/5] Install script --- install.sh | 105 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 105 insertions(+) create mode 100644 install.sh diff --git a/install.sh b/install.sh new file mode 100644 index 000000000..0e6234579 --- /dev/null +++ b/install.sh @@ -0,0 +1,105 @@ +#!/usr/bin/env bash +set -e + +echo '=====================================' +echo ' ____ _ _ ' +echo ' | _ \ __ _ _ __ (_) __| | ___ ____' +echo ' | |_) / _` | '\''_ \| |/ _` |/ _ \_ /' +echo ' | _ < (_| | |_) | | (_| | __// / ' +echo ' |_| \_\__,_| .__/|_|\__,_|\___/___|' +echo ' |_| ' +echo ' Welcome to the Rapidez installer!' +echo '=====================================' + +# Vars +DEFAULT_TRAEFIK_PORT=80 +DEFAULT_DB_PORT=3306 +INSTALL_DIR="${RAPIDEZ_HOME:-rapidez}" + +# Helpers +command_exists() { + command -v "$1" >/dev/null 2>&1 +} + +find_free_port() { + local port=$1 + + while nc -z localhost "$port" >/dev/null 2>&1; do + port=$((port + 1)) + done + + echo "$port" +} + +# Start! +if ! command_exists docker; then + echo "❌ Docker is not installed!" + echo "Please install Docker and try again" + exit 1 +fi + +if ! docker compose version >/dev/null 2>&1; then + echo "❌ Docker Compose is not available!" + echo "Please update Docker and try again" + exit 1 +fi + +echo "✓ Docker found" + +mkdir -p "$INSTALL_DIR" +cd "$INSTALL_DIR" + +composer create-project rapidez/rapidez:^5.0 . +composer require rapidez/reviews + +if [ ! -f docker-compose.yml ]; then + echo "⚠️ No docker-compose.yml found" + echo "Check the errors and try again" + exit 1 +fi + +TRAEFIK_PORT=$(find_free_port "$DEFAULT_TRAEFIK_PORT") +DB_PORT=$(find_free_port "$DEFAULT_DB_PORT") + +echo "✓ Free ports found:" +echo " HTTP: $TRAEFIK_PORT" +echo " MySQL: $DB_PORT" + +cp .env.example.traefik .env +sed -i.bak "s/^TRAEFIK_PORT=.*/TRAEFIK_PORT=$TRAEFIK_PORT/" .env && rm -f .env.bak +sed -i.bak "s/^DB_PORT=.*/DB_PORT=$DB_PORT/" .env && rm -f .env.bak +echo "✓ .env configured" + +docker exec rapidez php artisan key:generate +echo "✓ key generated" +docker exec rapidez php artisan rapidez:install --frontendonly +echo "✓ frontend dependencies copied" +docker exec rapidez yarn +echo "✓ frontend dependencies installed" +docker exec rapidez yarn run prod +echo "✓ frontend dependencies build" +docker exec rapidez php artisan storage:link +echo "✓ storage linked" +docker exec rapidez php artisan rapidez:index +echo "✓ products indexed" +docker exec rapidez php artisan vendor:publish --provider "Rapidez\Core\RapidezServiceProvider" +echo "✓ configs published" + +docker compose up -d + +echo "" +echo "🎉 Rapidez is ready!" +echo "" +echo "Rapidez frontend:" +echo "http://rapidez.localhost:$TRAEFIK_PORT" +echo "" +echo "Magento admin:" +echo "http://magento.localhost:$TRAEFIK_PORT/admin" +echo "" +echo "To stop everything:" +echo "docker compose down" +echo "" +echo "From here:" +echo "- Have a look, and make some changes in the templates: /resources/views/vendor/rapidez/" +echo "- Check the docs @ https://docs.rapidez.io" +echo "- Questions? Join Slack @ https://rapidez.io/slack" From 6c31dc5300a381e2ad7feaa94cd404ed3bd4d797 Mon Sep 17 00:00:00 2001 From: Roy Duineveld Date: Wed, 14 Oct 2026 08:25:09 +0200 Subject: [PATCH 2/5] Update install.sh Co-authored-by: Jade Geels --- install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install.sh b/install.sh index 0e6234579..48e2b5d9d 100644 --- a/install.sh +++ b/install.sh @@ -77,7 +77,7 @@ echo "✓ frontend dependencies copied" docker exec rapidez yarn echo "✓ frontend dependencies installed" docker exec rapidez yarn run prod -echo "✓ frontend dependencies build" +echo "✓ frontend dependencies built" docker exec rapidez php artisan storage:link echo "✓ storage linked" docker exec rapidez php artisan rapidez:index From 8d4b609011f2c59d3de6163c6b8fa976eee15810 Mon Sep 17 00:00:00 2001 From: Roy Duineveld Date: Wed, 14 Oct 2026 08:25:19 +0200 Subject: [PATCH 3/5] Update install.sh Co-authored-by: Jade Geels --- install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install.sh b/install.sh index 48e2b5d9d..54b0ceec7 100644 --- a/install.sh +++ b/install.sh @@ -83,7 +83,7 @@ echo "✓ storage linked" docker exec rapidez php artisan rapidez:index echo "✓ products indexed" docker exec rapidez php artisan vendor:publish --provider "Rapidez\Core\RapidezServiceProvider" -echo "✓ configs published" +echo "✓ configs, views, and translation files published" docker compose up -d From 1a7e99d79127ce9a6eaa0c996fd0fe3d30fd468d Mon Sep 17 00:00:00 2001 From: Roy Duineveld Date: Wed, 14 Oct 2026 08:31:27 +0200 Subject: [PATCH 4/5] Use pnpm --- install.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/install.sh b/install.sh index 54b0ceec7..36f2d2934 100644 --- a/install.sh +++ b/install.sh @@ -74,9 +74,9 @@ docker exec rapidez php artisan key:generate echo "✓ key generated" docker exec rapidez php artisan rapidez:install --frontendonly echo "✓ frontend dependencies copied" -docker exec rapidez yarn +docker exec rapidez pnpm install echo "✓ frontend dependencies installed" -docker exec rapidez yarn run prod +docker exec rapidez pnpm run prod echo "✓ frontend dependencies built" docker exec rapidez php artisan storage:link echo "✓ storage linked" From a309683196f9ef447d64443ab18681efcc90b444 Mon Sep 17 00:00:00 2001 From: Roy Duineveld Date: Wed, 14 Oct 2026 14:06:45 +0200 Subject: [PATCH 5/5] Fixes - Only Docker is required, Composer runs in a container - Start the containers before running commands in them - Wait for Elasticsearch and Magento before indexing - Set the Magento crypt key so customers can login - Keep the files owned by the current user - Check for conflicting containers and an existing directory --- install.sh | 285 ++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 205 insertions(+), 80 deletions(-) diff --git a/install.sh b/install.sh index 36f2d2934..d2d090197 100644 --- a/install.sh +++ b/install.sh @@ -1,105 +1,230 @@ #!/usr/bin/env bash -set -e - -echo '=====================================' -echo ' ____ _ _ ' -echo ' | _ \ __ _ _ __ (_) __| | ___ ____' -echo ' | |_) / _` | '\''_ \| |/ _` |/ _ \_ /' -echo ' | _ < (_| | |_) | | (_| | __// / ' -echo ' |_| \_\__,_| .__/|_|\__,_|\___/___|' -echo ' |_| ' -echo ' Welcome to the Rapidez installer!' -echo '=====================================' +# +# Rapidez installer, try Rapidez with a demo Magento installation +# +# curl -fsSL https://rapidez.io/install | bash +# +# Everything runs in Docker, that's the only requirement. +# Optional environment variables: +# RAPIDEZ_HOME The directory to install into (default: rapidez) +# RAPIDEZ_VERSION The rapidez/rapidez version (default: ^5.0) + +set -Eeuo pipefail +trap 'echo "" >&2; echo "❌ Something went wrong, check the errors above and try again" >&2' ERR # Vars +INSTALL_DIR="${RAPIDEZ_HOME:-rapidez}" +RAPIDEZ_VERSION="${RAPIDEZ_VERSION:-^5.0}" DEFAULT_TRAEFIK_PORT=80 DEFAULT_DB_PORT=3306 -INSTALL_DIR="${RAPIDEZ_HOME:-rapidez}" +CONTAINERS=(traefik elasticsearch magento nginx rapidez) +USER_ID="$(id -u)" +GROUP_ID="$(id -g)" # Helpers +banner() { + echo '=====================================' + echo ' ____ _ _ ' + echo ' | _ \ __ _ _ __ (_) __| | ___ ____' + echo ' | |_) / _` | '\''_ \| |/ _` |/ _ \_ /' + echo ' | _ < (_| | |_) | | (_| | __// / ' + echo ' |_| \_\__,_| .__/|_|\__,_|\___/___|' + echo ' |_| ' + echo ' Welcome to the Rapidez installer!' + echo '=====================================' +} + +step() { + echo "" + echo "→ $1" +} + +success() { + echo "✓ $1" +} + +fail() { + echo "" >&2 + echo "❌ $1" >&2 + shift + for line in "$@"; do + echo " $line" >&2 + done + exit 1 +} + command_exists() { command -v "$1" >/dev/null 2>&1 } +port_in_use() { + (echo >"/dev/tcp/127.0.0.1/$1") >/dev/null 2>&1 +} + find_free_port() { local port=$1 - while nc -z localhost "$port" >/dev/null 2>&1; do + while port_in_use "$port"; do port=$((port + 1)) done echo "$port" } -# Start! -if ! command_exists docker; then - echo "❌ Docker is not installed!" - echo "Please install Docker and try again" - exit 1 -fi +set_env() { + if grep -q "^$1=" .env; then + sed -i.bak "s|^$1=.*|$1=$2|" .env + rm -f .env.bak + else + echo "$1=$2" >>.env + fi +} -if ! docker compose version >/dev/null 2>&1; then - echo "❌ Docker Compose is not available!" - echo "Please update Docker and try again" - exit 1 -fi +# Run a command in the Rapidez container as the current user, +# so all files stay owned by you and are editable locally. +in_rapidez() { + docker compose exec -T --user "$USER_ID:$GROUP_ID" --env HOME=/tmp rapidez "$@" +} -echo "✓ Docker found" +wait_for() { + local name=$1 timeout=$2 start=$SECONDS + shift 2 + + echo " Waiting for $name..." + until "$@" >/dev/null 2>&1; do + if ((SECONDS - start > timeout)); then + fail "$name is not ready after $((timeout / 60)) minutes" \ + "Check the logs with: cd $PWD && docker compose logs" + fi + sleep 5 + done + success "$name is ready" +} -mkdir -p "$INSTALL_DIR" -cd "$INSTALL_DIR" +elasticsearch_ready() { + docker compose exec -T rapidez sh -c 'curl -sf -u "$ELASTICSEARCH_USER:$ELASTICSEARCH_PASS" http://elasticsearch:9200/_security/user/web' +} -composer create-project rapidez/rapidez:^5.0 . -composer require rapidez/reviews +magento_ready() { + # On the first start the Rapidez module is installed and everything is reindexed. + ! docker compose exec -T magento pgrep -f 'entrypoints/|bin/magento|magerun2' >/dev/null && + docker compose exec -T rapidez curl -sf -H 'Content-Type: application/json' \ + -d '{"query":"{ storeConfig { store_code } }"}' http://magento/graphql | grep -q store_code +} -if [ ! -f docker-compose.yml ]; then - echo "⚠️ No docker-compose.yml found" - echo "Check the errors and try again" - exit 1 -fi - -TRAEFIK_PORT=$(find_free_port "$DEFAULT_TRAEFIK_PORT") -DB_PORT=$(find_free_port "$DEFAULT_DB_PORT") - -echo "✓ Free ports found:" -echo " HTTP: $TRAEFIK_PORT" -echo " MySQL: $DB_PORT" - -cp .env.example.traefik .env -sed -i.bak "s/^TRAEFIK_PORT=.*/TRAEFIK_PORT=$TRAEFIK_PORT/" .env && rm -f .env.bak -sed -i.bak "s/^DB_PORT=.*/DB_PORT=$DB_PORT/" .env && rm -f .env.bak -echo "✓ .env configured" - -docker exec rapidez php artisan key:generate -echo "✓ key generated" -docker exec rapidez php artisan rapidez:install --frontendonly -echo "✓ frontend dependencies copied" -docker exec rapidez pnpm install -echo "✓ frontend dependencies installed" -docker exec rapidez pnpm run prod -echo "✓ frontend dependencies built" -docker exec rapidez php artisan storage:link -echo "✓ storage linked" -docker exec rapidez php artisan rapidez:index -echo "✓ products indexed" -docker exec rapidez php artisan vendor:publish --provider "Rapidez\Core\RapidezServiceProvider" -echo "✓ configs, views, and translation files published" - -docker compose up -d - -echo "" -echo "🎉 Rapidez is ready!" -echo "" -echo "Rapidez frontend:" -echo "http://rapidez.localhost:$TRAEFIK_PORT" -echo "" -echo "Magento admin:" -echo "http://magento.localhost:$TRAEFIK_PORT/admin" -echo "" -echo "To stop everything:" -echo "docker compose down" -echo "" -echo "From here:" -echo "- Have a look, and make some changes in the templates: /resources/views/vendor/rapidez/" -echo "- Check the docs @ https://docs.rapidez.io" -echo "- Questions? Join Slack @ https://rapidez.io/slack" +# Wrapped in a function so nothing runs when the download is interrupted. +main() { + banner + + step "Checking the requirements" + + if ! command_exists docker; then + fail "Docker is not installed!" "Please install Docker and try again: https://docs.docker.com/get-docker/" + fi + + if ! docker compose version >/dev/null 2>&1; then + fail "Docker Compose is not available!" "Please update Docker and try again" + fi + + if ! docker info >/dev/null 2>&1; then + fail "Docker is not running or you don't have permission to use it!" "Please start Docker and try again" + fi + + success "Docker found" + + for container in "${CONTAINERS[@]}"; do + if docker container inspect "$container" >/dev/null 2>&1; then + fail "There is already a Docker container named \"$container\"" \ + "Remove it first with: docker rm -f $container" + fi + done + + if [ -e "$INSTALL_DIR" ] && [ -n "$(ls -A "$INSTALL_DIR")" ]; then + fail "The directory \"$INSTALL_DIR\" already exists and isn't empty" \ + "Remove it or install somewhere else with: curl -fsSL https://rapidez.io/install | RAPIDEZ_HOME=other-directory bash" + fi + + step "Downloading Rapidez" + + mkdir -p "$INSTALL_DIR" + cd "$INSTALL_DIR" + + docker run --rm --user "$USER_ID:$GROUP_ID" --env COMPOSER_HOME=/tmp/composer \ + --volume "$PWD:/app" --workdir /app composer:2 \ + create-project --no-install --no-scripts --no-interaction "rapidez/rapidez:$RAPIDEZ_VERSION" . + + if [ ! -f docker-compose-traefik.yml ] || [ ! -f .env.example.traefik ]; then + fail "The Docker configuration is missing" "Check the errors above and try again" + fi + + TRAEFIK_PORT=$(find_free_port "$DEFAULT_TRAEFIK_PORT") + DB_PORT=$(find_free_port "$DEFAULT_DB_PORT") + + cp .env.example.traefik .env + set_env TRAEFIK_PORT "$TRAEFIK_PORT" + set_env DB_PORT "$DB_PORT" + + success "Rapidez downloaded and configured" + echo " HTTP port: $TRAEFIK_PORT" + echo " MySQL port: $DB_PORT" + + step "Starting the containers, the first time this takes a while" + + docker compose pull --ignore-buildable + docker compose up --detach --build + + success "Containers started" + + step "Installing the dependencies" + + in_rapidez composer require --no-interaction rapidez/reviews + success "PHP dependencies installed" + + in_rapidez php artisan key:generate --no-interaction + in_rapidez php artisan rapidez:install --frontendonly + in_rapidez php artisan vendor:publish --provider="Rapidez\Core\RapidezServiceProvider" + in_rapidez php artisan storage:link + success "Configs, views and translations published" + + in_rapidez pnpm install + in_rapidez pnpm run prod + success "Frontend dependencies installed and built" + + # The webserver runs as another user and needs to write here. + chmod -R a+rwX storage bootstrap/cache + + step "Indexing the products, Magento needs a few minutes to start the first time" + + wait_for "Elasticsearch" 600 elasticsearch_ready + wait_for "Magento" 1200 magento_ready + + # Used to validate the customer tokens from Magento. + set_env CRYPT_KEY "$(docker compose exec -T magento php -r '$env = include "app/etc/env.php"; echo $env["crypt"]["key"];')" + + docker compose exec -T rapidez php artisan rapidez:index + success "Products indexed" + + local port_suffix="" + if [ "$TRAEFIK_PORT" != "80" ]; then + port_suffix=":$TRAEFIK_PORT" + fi + + echo "" + echo "🎉 Rapidez is ready!" + echo "" + echo "Rapidez frontend:" + echo "http://rapidez.localhost$port_suffix" + echo "" + echo "Magento admin (user: exampleuser, password: examplepassword123):" + echo "http://magento.localhost$port_suffix/admin" + echo "" + echo "Stop or start everything from the $INSTALL_DIR directory with:" + echo "docker compose stop / docker compose start" + echo "" + echo "From here:" + echo "- Have a look and make some changes in the templates: $PWD/resources/views/vendor/rapidez" + echo "- Check the docs @ https://docs.rapidez.io" + echo "- Questions? Join Slack @ https://rapidez.io/slack" +} + +main "$@"