-
-
Save stevobengtson/7b6e4d8f4a47e21c8f13b3e61418af91 to your computer and use it in GitHub Desktop.
Sail script to use in Symfony projects
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env bash | |
UNAMEOUT="$(uname -s)" | |
# Verify operating system is supported... | |
case "${UNAMEOUT}" in | |
Linux*) MACHINE=linux;; | |
Darwin*) MACHINE=mac;; | |
*) MACHINE="UNKNOWN" | |
esac | |
if [ "$MACHINE" == "UNKNOWN" ]; then | |
echo "Unsupported operating system [$(uname -s)]. LTW supports macOS, Linux, and Windows (WSL2)." >&2 | |
exit 1 | |
fi | |
# Determine if stdout is a terminal... | |
if test -t 1; then | |
# Determine if colors are supported... | |
ncolors=$(tput colors) | |
if test -n "$ncolors" && test "$ncolors" -ge 8; then | |
BOLD="$(tput bold)" | |
YELLOW="$(tput setaf 3)" | |
GREEN="$(tput setaf 2)" | |
NC="$(tput sgr0)" | |
fi | |
fi | |
# Function that prints the available commands... | |
function display_help { | |
echo "LTW Docker" | |
echo | |
echo "${YELLOW}Usage:${NC}" >&2 | |
echo " ltw COMMAND [options] [arguments]" | |
echo | |
echo "Unknown commands are passed to the docker-compose binary." | |
echo | |
echo "${YELLOW}docker-compose Commands:${NC}" | |
echo " ${GREEN}ltw up${NC} Start the application" | |
echo " ${GREEN}ltw up -d${NC} Start the application in the background" | |
echo " ${GREEN}ltw stop${NC} Stop the application" | |
echo " ${GREEN}ltw restart${NC} Restart the application" | |
echo " ${GREEN}ltw ps${NC} Display the status of all containers" | |
echo | |
echo "${YELLOW}Console Commands:${NC}" | |
echo " ${GREEN}ltw console ...${NC} Run an Console command" | |
echo " ${GREEN}ltw console queue:work${NC}" | |
echo | |
echo "${YELLOW}PHP Commands:${NC}" | |
echo " ${GREEN}ltw php ...${NC} Run a snippet of PHP code" | |
echo " ${GREEN}ltw php -v${NC}" | |
echo | |
echo "${YELLOW}Composer Commands:${NC}" | |
echo " ${GREEN}ltw composer ...${NC} Run a Composer command" | |
echo " ${GREEN}ltw composer require laravel/sanctum${NC}" | |
echo | |
echo "${YELLOW}Node Commands:${NC}" | |
echo " ${GREEN}ltw node ...${NC} Run a Node command" | |
echo " ${GREEN}ltw node --version${NC}" | |
echo | |
echo "${YELLOW}NPM Commands:${NC}" | |
echo " ${GREEN}ltw npm ...${NC} Run a npm command" | |
echo " ${GREEN}ltw npx${NC} Run a npx command" | |
echo " ${GREEN}ltw npm run prod${NC}" | |
echo | |
echo "${YELLOW}Yarn Commands:${NC}" | |
echo " ${GREEN}ltw yarn ...${NC} Run a Yarn command" | |
echo " ${GREEN}ltw yarn run prod${NC}" | |
echo | |
echo "${YELLOW}Database Commands:${NC}" | |
echo " ${GREEN}ltw mysql${NC} Start a MySQL CLI session within the 'mysql' container" | |
echo " ${GREEN}ltw mariadb${NC} Start a MySQL CLI session within the 'mariadb' container" | |
echo " ${GREEN}ltw psql${NC} Start a PostgreSQL CLI session within the 'pgsql' container" | |
echo " ${GREEN}ltw redis${NC} Start a Redis CLI session within the 'redis' container" | |
echo | |
echo "${YELLOW}Debugging:${NC}" | |
echo " ${GREEN}ltw debug ...${NC} Run an Console command in debug mode" | |
echo " ${GREEN}ltw debug queue:work${NC}" | |
echo | |
echo "${YELLOW}Running Tests:${NC}" | |
echo " ${GREEN}ltw test${NC} Run the PHPUnit tests via the Console test command" | |
echo " ${GREEN}ltw phpunit ...${NC} Run PHPUnit" | |
echo " ${GREEN}ltw pest ...${NC} Run Pest" | |
echo " ${GREEN}ltw pint ...${NC} Run Pint" | |
echo " ${GREEN}ltw dusk${NC} Run the Dusk tests (Requires the laravel/dusk package)" | |
echo " ${GREEN}ltw dusk:fails${NC} Re-run previously failed Dusk tests (Requires the laravel/dusk package)" | |
echo | |
echo "${YELLOW}Container CLI:${NC}" | |
echo " ${GREEN}ltw shell${NC} Start a shell session within the application container" | |
echo " ${GREEN}ltw bash${NC} Alias for 'ltw shell'" | |
echo " ${GREEN}ltw root-shell${NC} Start a root shell session within the application container" | |
echo " ${GREEN}ltw root-bash${NC} Alias for 'ltw root-shell'" | |
echo " ${GREEN}ltw tinker${NC} Start a new PSYSH session" | |
echo | |
echo "${YELLOW}Sharing:${NC}" | |
echo " ${GREEN}ltw share${NC} Share the application publicly via a temporary URL" | |
echo | |
echo "${YELLOW}Binaries:${NC}" | |
echo " ${GREEN}ltw bin ...${NC} Run Composer binary scripts from the vendor/bin directory" | |
echo | |
exit 1 | |
} | |
# Proxy the "help" command... | |
if [ $# -gt 0 ]; then | |
if [ "$1" == "help" ] || [ "$1" == "-h" ] || [ "$1" == "-help" ] || [ "$1" == "--help" ]; then | |
display_help | |
fi | |
else | |
display_help | |
fi | |
# Source the ".env" file so Symfony's environment variables are available... | |
if [ ! -z "$APP_ENV" ] && [ -f ./.env.$APP_ENV ]; then | |
source ./.env.$APP_ENV; | |
elif [ -f ./.env ]; then | |
source ./.env; | |
fi | |
# Define environment variables... | |
export APP_PORT=${APP_PORT:-80} | |
export APP_SERVICE=${APP_SERVICE:-"app"} | |
export DB_PORT=${DB_PORT:-3306} | |
export LTW_FILES=${LTW_FILES:-""} | |
export LTW_SHARE_DASHBOARD=${LTW_SHARE_DASHBOARD:-4040} | |
export LTW_SHARE_SERVER_HOST=${LTW_SHARE_SERVER_HOST:-"localhost"} | |
export LTW_SHARE_SERVER_PORT=${LTW_SHARE_SERVER_PORT:-8000} | |
export LTW_SHARE_SUBDOMAIN=${LTW_SHARE_SUBDOMAIN:-""} | |
export LTW_SHARE_DOMAIN=${LTW_SHARE_DOMAIN:-""} | |
# Function that outputs ltw is not running... | |
function ltw_is_not_running { | |
echo "${BOLD}ltw is not running.${NC}" >&2 | |
echo "" >&2 | |
echo "${BOLD}You may start ltw using the following commands:${NC} './bin/ltw up' or './bin/ltw up -d'" >&2 | |
exit 1 | |
} | |
# Define Docker Compose command prefix... | |
docker compose &> /dev/null | |
if [ $? == 0 ]; then | |
DOCKER_COMPOSE=(docker compose) | |
else | |
DOCKER_COMPOSE=(docker-compose) | |
fi | |
if [ -n "$LTW_FILES" ]; then | |
# Convert LTW_FILES to an array... | |
IFS=':' read -ra LTW_FILES <<< "$LTW_FILES" | |
for FILE in "${LTW_FILES[@]}"; do | |
if [ -f "$FILE" ]; then | |
DOCKER_COMPOSE+=(-f "$FILE") | |
else | |
echo "${BOLD}Unable to find Docker Compose file: '${FILE}'${NC}" >&2 | |
exit 1 | |
fi | |
done | |
fi | |
EXEC="yes" | |
if [ -z "$LTW_SKIP_CHECKS" ]; then | |
# Ensure that Docker is running... | |
if ! docker info > /dev/null 2>&1; then | |
echo "${BOLD}Docker is not running.${NC}" >&2 | |
exit 1 | |
fi | |
# Determine if ltw is currently up... | |
if "${DOCKER_COMPOSE[@]}" ps "$APP_SERVICE" 2>&1 | grep 'Exit\|exited'; then | |
echo "${BOLD}Shutting down old ltw processes...${NC}" >&2 | |
"${DOCKER_COMPOSE[@]}" down > /dev/null 2>&1 | |
EXEC="no" | |
elif [ -z "$("${DOCKER_COMPOSE[@]}" ps -q)" ]; then | |
EXEC="no" | |
fi | |
fi | |
ARGS=() | |
# Proxy PHP commands to the "php" binary on the application container... | |
if [ "$1" == "php" ]; then | |
shift 1 | |
if [ "$EXEC" == "yes" ]; then | |
ARGS+=(exec) | |
[ ! -t 0 ] && ARGS+=(-T) | |
ARGS+=("$APP_SERVICE" "php" "$@") | |
else | |
ltw_is_not_running | |
fi | |
# Proxy vendor binary commands on the application container... | |
elif [ "$1" == "bin" ]; then | |
shift 1 | |
if [ "$EXEC" == "yes" ]; then | |
ARGS+=(exec) | |
[ ! -t 0 ] && ARGS+=(-T) | |
ARGS+=("$APP_SERVICE" ./vendor/bin/"$@") | |
else | |
ltw_is_not_running | |
fi | |
# Proxy Composer commands to the "composer" binary on the application container... | |
elif [ "$1" == "composer" ]; then | |
shift 1 | |
if [ "$EXEC" == "yes" ]; then | |
ARGS+=(exec) | |
[ ! -t 0 ] && ARGS+=(-T) | |
ARGS+=("$APP_SERVICE" "composer" "$@") | |
else | |
ltw_is_not_running | |
fi | |
# Proxy Console commands to the "console" binary on the application container... | |
elif [ "$1" == "console" ] || [ "$1" == "con" ]; then | |
shift 1 | |
if [ "$EXEC" == "yes" ]; then | |
ARGS+=(exec) | |
[ ! -t 0 ] && ARGS+=(-T) | |
ARGS+=("$APP_SERVICE" php bin/console "$@") | |
else | |
ltw_is_not_running | |
fi | |
# Proxy the "debug" command to the "php console" binary on the application container with xdebug enabled... | |
elif [ "$1" == "debug" ]; then | |
shift 1 | |
if [ "$EXEC" == "yes" ]; then | |
ARGS+=(exec -e XDEBUG_SESSION=1) | |
[ ! -t 0 ] && ARGS+=(-T) | |
ARGS+=("$APP_SERVICE" php bin/console "$@") | |
else | |
ltw_is_not_running | |
fi | |
# Proxy the "test" or "phpunit" command to the "php bin/phpunit" command... | |
elif [ "$1" == "test" ] || [ "$1" == "phpunit" ]; then | |
shift 1 | |
if [ "$EXEC" == "yes" ]; then | |
ARGS+=(exec) | |
[ ! -t 0 ] && ARGS+=(-T) | |
ARGS+=("$APP_SERVICE" php bin/phpunit "$@") | |
else | |
ltw_is_not_running | |
fi | |
# Initiate a PSYSH session within the application container... | |
elif [ "$1" == "tinker" ] ; then | |
shift 1 | |
if [ "$EXEC" == "yes" ]; then | |
ARGS+=(exec) | |
[ ! -t 0 ] && ARGS+=(-T) | |
ARGS+=("$APP_SERVICE" php vendor/bin/psysh) | |
else | |
ltw_is_not_running | |
fi | |
# Proxy Node commands to the "node" binary on the application container... | |
elif [ "$1" == "node" ]; then | |
shift 1 | |
if [ "$EXEC" == "yes" ]; then | |
ARGS+=(exec) | |
[ ! -t 0 ] && ARGS+=(-T) | |
ARGS+=("$APP_SERVICE" node "$@") | |
else | |
ltw_is_not_running | |
fi | |
# Proxy NPM commands to the "npm" binary on the application container... | |
elif [ "$1" == "npm" ]; then | |
shift 1 | |
if [ "$EXEC" == "yes" ]; then | |
ARGS+=(exec) | |
[ ! -t 0 ] && ARGS+=(-T) | |
ARGS+=("$APP_SERVICE" npm "$@") | |
else | |
ltw_is_not_running | |
fi | |
# Proxy NPX commands to the "npx" binary on the application container... | |
elif [ "$1" == "npx" ]; then | |
shift 1 | |
if [ "$EXEC" == "yes" ]; then | |
ARGS+=(exec) | |
[ ! -t 0 ] && ARGS+=(-T) | |
ARGS+=("$APP_SERVICE" npx "$@") | |
else | |
ltw_is_not_running | |
fi | |
# Proxy YARN commands to the "yarn" binary on the application container... | |
elif [ "$1" == "yarn" ]; then | |
shift 1 | |
if [ "$EXEC" == "yes" ]; then | |
ARGS+=(exec) | |
[ ! -t 0 ] && ARGS+=(-T) | |
ARGS+=("$APP_SERVICE" yarn "$@") | |
else | |
ltw_is_not_running | |
fi | |
# Initiate a MySQL or MariaDB CLI terminal session within the "database" container... | |
elif [ "$1" == "mysql" ] || [ "$1" == "mariadb" ]; then | |
shift 1 | |
if [ "$EXEC" == "yes" ]; then | |
ARGS+=(exec) | |
[ ! -t 0 ] && ARGS+=(-T) | |
ARGS+=(database bash -c) | |
ARGS+=("MYSQL_PWD=\${MYSQL_PASSWORD} mysql -u \${MYSQL_USER} \${MYSQL_DATABASE}") | |
else | |
ltw_is_not_running | |
fi | |
# Initiate a PostgreSQL CLI terminal session within the "database" container... | |
elif [ "$1" == "psql" ]; then | |
shift 1 | |
if [ "$EXEC" == "yes" ]; then | |
ARGS+=(exec) | |
[ ! -t 0 ] && ARGS+=(-T) | |
ARGS+=(database bash -c) | |
ARGS+=("PGPASSWORD=\${PGPASSWORD} psql -U \${POSTGRES_USER} \${POSTGRES_DB}") | |
else | |
ltw_is_not_running | |
fi | |
# Initiate a Bash shell within the application container... | |
elif [ "$1" == "shell" ] || [ "$1" == "bash" ]; then | |
shift 1 | |
if [ "$EXEC" == "yes" ]; then | |
ARGS+=(exec) | |
[ ! -t 0 ] && ARGS+=(-T) | |
ARGS+=("$APP_SERVICE" bash "$@") | |
else | |
ltw_is_not_running | |
fi | |
# Initiate a root user Bash shell within the application container... | |
elif [ "$1" == "root-shell" ] || [ "$1" == "root-bash" ]; then | |
shift 1 | |
if [ "$EXEC" == "yes" ]; then | |
ARGS+=(exec) | |
[ ! -t 0 ] && ARGS+=(-T) | |
ARGS+=("$APP_SERVICE" bash "$@") | |
else | |
ltw_is_not_running | |
fi | |
# Initiate a Redis CLI terminal session within the "redis" container... | |
elif [ "$1" == "redis" ] ; then | |
shift 1 | |
if [ "$EXEC" == "yes" ]; then | |
ARGS+=(exec) | |
[ ! -t 0 ] && ARGS+=(-T) | |
ARGS+=(redis redis-cli) | |
else | |
ltw_is_not_running | |
fi | |
# Share the site... | |
elif [ "$1" == "share" ]; then | |
shift 1 | |
if [ "$EXEC" == "yes" ]; then | |
docker run --init --rm -p "$LTW_SHARE_DASHBOARD":4040 -t beyondcodegmbh/expose-server:latest share http://host.docker.internal:"$APP_PORT" \ | |
--server-host="$LTW_SHARE_SERVER_HOST" \ | |
--server-port="$LTW_SHARE_SERVER_PORT" \ | |
--auth="$LTW_SHARE_TOKEN" \ | |
--subdomain="$LTW_SHARE_SUBDOMAIN" \ | |
--domain="$LTW_SHARE_DOMAIN" \ | |
"$@" | |
exit | |
else | |
ltw_is_not_running | |
fi | |
# Pass unknown commands to the "docker-compose" binary... | |
else | |
ARGS+=("$@") | |
fi | |
echo "Running: " "${DOCKER_COMPOSE[@]}" "${ARGS[@]}" | |
# Run Docker Compose with the defined arguments... | |
"${DOCKER_COMPOSE[@]}" "${ARGS[@]}" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment