Last active
February 13, 2022 13:02
-
-
Save zanbaldwin/239adf21e2175e4eb17a2ff0e2a0da8a to your computer and use it in GitHub Desktop.
Quick and dirty script to pull a specific version of the PHP Docker image, much less hassle than having multiple PHP versions installed locally. You won't be able to install any extensions though because you won't be root (remove the --user flag if you're okay with creating files in your working tree belonging to root).
This file contains hidden or 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
#!/bin/sh | |
if [ $# -eq 0 ]; then | |
echo 2>&1 "You must specify the PHP version as the first argument." | |
exit 1 | |
fi | |
################################################################################### | |
### ENVIRONMENT HELPER ### | |
### --------------------------------------------------------------------------- ### | |
### Run this script to create a one-off container based on the PHP service for ### | |
### CLI work. It will auto-detect if you have Composer installed on your host; ### | |
### if so it will mount Composer as a binary inside the container and also ### | |
### Composer's cache directory to reduce the amount of downloading required. ### | |
### ### | |
### Useful if you have differing PHP versions between host and container. ### | |
################################################################################### | |
# Standardize Paths | |
realpath() { | |
# Can't be bothered to refactor this. If you're not using Bash on macOS then | |
# I'm not going to bother making sure this is compatible. | |
[[ $1 = /* ]] && echo "$1" || echo "${PWD}/${1#./}" | |
} | |
readlink -f "$0" >/dev/null 2>&1 | |
if [ $? -ne 0 ]; then | |
DIR="$(dirname "$(realpath "$0")")" | |
else | |
DIR="$(dirname "$(readlink -f "$0")")" | |
fi | |
# Check for Docker Permissions | |
DOCKER="${DOCKER:-"docker"}" | |
command -v "${DOCKER}" >/dev/null 2>&1 || { | |
echo >&2 "$(tput setaf 1)Docker Client \"${DOCKER}\" not available on \$PATH.$(tput sgr0)"; | |
exit 1; | |
} | |
INFO=$("${DOCKER}" info >/dev/null 2>&1) | |
if [ $? -ne 0 ]; then | |
echo >&2 "$(tput setaf 1)Docker Daemon unavailable.$(tput sgr0)" | |
if [ "$(id -u 2>/dev/null)" -ne "0" ]; then | |
echo >&2 "$(tput setaf 1)Perhaps retry as root?$(tput sgr0)" | |
fi | |
exit 1 | |
fi | |
################################################################################ | |
### DETECTING COMPOSER BINARY AND CACHE DIRECTORIES ### | |
### ------------------------------------------------------------------------ ### | |
### The following is a little unweildy because it will: ### | |
### - Attempt to detect the globally-installed Composer binary, but fallback ### | |
### onto a "composer.phar" file installed inside the "bin/" project ### | |
### directory. ### | |
### - Set appropriate "COMPOSER_HOME" env variable (falling back to a tmpfs ### | |
### folder in case Composer doesn't exist so that the non-root user can ### | |
### still create it if needed). ### | |
### - Figure out Composer's home (cache directory) and load it as a volume, ### | |
### falling back to creating one inside the "var/" project directory if it ### | |
### can't find it. ### | |
################################################################################ | |
COMPOSER="" | |
# Use this default when no Composer binary is added, because without it set it will try to create on the root filesystem | |
# which the non-root user cannot create directories in. | |
COMPOSER_HOME="/tmp/composer" | |
# Set the default cache directory to be inside the "var/" project directory (project-specific rather than global). | |
COMPOSER_HOST_CACHE="/tmp/.composer" | |
# Try loading the local, project-specific composer.phar first (in case we're on macOS which won't allow mounting | |
# /private (/usr, /var, etc). If it does not exist, try mounting the globally installed Composer binary. | |
COMPOSER_BINARY="$(command -v composer 2>/dev/null)" | |
if [ -f "${COMPOSER_BINARY}" ]; then | |
# Assuming that PHP is installed on the host machine, try determine Composer's global home (cache) directory. | |
COMPOSER_HOST_HOMEDIR="$(php "${COMPOSER_BINARY}" global config home 2>/dev/null)" | |
if [ $? -eq 0 ] && [ -d "${COMPOSER_HOST_HOMEDIR}" ]; then | |
COMPOSER_HOST_CACHE="${COMPOSER_HOST_HOMEDIR}" | |
elif [ ! -d "${COMPOSER_HOST_CACHE}" ]; then | |
# Create the cache directory now as the host machine user, rather than let Docker create the volume | |
# bind as the root user (because then permissions would be all out of whack). | |
echo "$(tput setaf 2)Creating Composer cache directory...$(tput sgr0)" | |
mkdir -p "${COMPOSER_HOST_CACHE}" | |
fi | |
COMPOSER="--volume \"${COMPOSER_BINARY}:/bin/composer:ro\" --volume \"${COMPOSER_HOST_CACHE}:${COMPOSER_HOME}\" -e \"COMPOSER_HOME=${COMPOSER_HOME}\"" | |
fi | |
PHP_VERSION="$1-alpine" | |
shift | |
COMMAND="sh" | |
# This little snippet wraps every command-line argument (after "bin/env") in quotes so that arguments with spaces in | |
# them (such as `bin/env bin/console oauth2:client:create "My Client Name"`) do not get turned into separate arguments | |
# (such as `bin/env bin/console oauth2:client:create "My" "Client" "Name"`). | |
if [ $# -gt 0 ]; then | |
COMMAND="" | |
for ARG in "$@"; do | |
COMMAND="${COMMAND} \"${ARG}\"" | |
done | |
fi | |
SCRIPT="\"${DOCKER}\" run --rm -it --volume=\"$(pwd):/srv\" --workdir=\"/srv\" --user=\"$(id -u):$(id -g)\" ${COMPOSER} -e \"TERM=xterm\" "php:${PHP_VERSION}" ${COMMAND}" | |
"${SHELL:-"sh"}" -c "${SCRIPT}" | |
exit $? |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment