Skip to content

Instantly share code, notes, and snippets.

@focusaurus
Created October 17, 2018 03:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save focusaurus/5f148b5601e6ad7ce09552f712c59aeb to your computer and use it in GitHub Desktop.
Save focusaurus/5f148b5601e6ad7ce09552f712c59aeb to your computer and use it in GitHub Desktop.
Script to drop into myproject/bin and go to town with docker
#!/usr/bin/env bash
# Please Use Google Shell Style: https://google.github.io/styleguide/shell.xml
# ---- Start unofficial bash strict mode boilerplate
# http://redsymbol.net/articles/unofficial-bash-strict-mode/
set -o errexit # always exit on error
set -o errtrace # trap errors in functions as well
set -o pipefail # don't ignore exit codes when piping output
set -o posix # more strict failures in subshells
# set -x # enable debugging
IFS="$(printf "\n\t")"
# ---- End unofficial bash strict mode boilerplate
##### Usage #####
# First run:
#
# $ ./bin/docker-run.sh
#
# This will build the docker image then run a shell.
# Once the image is built, it will be run directly without a rebuild.
# If at any time you want to force a rebuild
#
# $ ./bin/docker-run.sh --build
##### How this script works #####
# This script can be dropped into a project and provide docker tooling
# to build a custom docker image for development on that project
# and get you a shell in there to do development tasks.
# It is all-in one for docker build and docker run.
#
# It is designed to have the project source code mounted into the docker image
# so that the host and the container always share the identical source code and
# project scripts. Only the development tools themselves live in the docker image.
# There is no ADD/COPY during the docker build and no docker-only volumes used.
#
# It is designed such that the user/group IDs match between the container and
# the host so there are no filesystem permission denied errors.
#
# The image it builds will by default match the name of this script's
# grandparent directory, meaning it's designed to live at
# myproject/bin/docker-run.sh
# and will tag the image as "myproject"
#
# It includes sections of Dockerfile syntax as shell variables which it will
# concatenate into a full Dockerfile sent to docker build over stdin.
# Snippets are provided for debian and alpine base images.
#
# It also mounts SSH_AUTH_SOCK so you can use git with ssh inside the
# container if you like.
#
# Bits you are intended to customize for each particular project are tagged with
# "CUSTOMIZE THIS" below.
docker_build() {
##### CUSTOMIZE THIS: to your base docker image #####
from="alpine"
# use this for debian/ubuntu, delete otherwise
# shellcheck disable=SC2034
user_section_debian=$(
cat <<'EOF'
ARG USER
ARG USER_ID=1000
ARG GROUP_ID=1000
RUN addgroup --gid ${GROUP_ID} ${USER} || true
RUN adduser --disabled-password --gid ${GROUP_ID} --uid ${USER_ID} --gecos ${USER} ${USER} || true
EOF
)
##### CUSTOMIZE THIS with any additional packages you need #####
# shellcheck disable=SC2034
package_section_debian=$(
cat <<'EOF'
RUN set -eux; \
apt-get -q -y update; \
apt-get -q -y install less git
EOF
)
# shellcheck disable=SC2034
user_section_alpine=$(
cat <<EOF
ARG USER
ARG USER_ID=1000
ARG GROUP_ID=1000
RUN addgroup -g \${GROUP_ID} \${USER}; \
adduser -D -G "\${USER}" -u "\${USER_ID}" -g "\${USER}" "\${USER}";
EOF
)
##### CUSTOMIZE THIS with any additional packages you need #####
# shellcheck disable=SC2034
package_section_alpine=$(
cat <<'EOF'
RUN set -eux; apk -v --update add bash less git;
EOF
)
##### CUSTOMIZE THIS! #####
main_section=$(
cat <<'EOF'
ENV PATH /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/host/node_modules/.bin
WORKDIR /host
USER \${USER}
EXPOSE 9999
CMD ["bash"]
EOF
)
echo "FROM ${from}
${user_section_alpine}
${package_section_alpine}
${main_section}" | docker build \
--tag "$1" \
--build-arg "USER=${USER}" \
--build-arg "USER_ID=$(id -u)" \
--build-arg "GROUP_ID=$(id -g)" \
-
}
docker_run() {
exec docker run --rm --interactive --tty \
--attach stdin --attach stdout --attach stderr \
--volume "${PWD}:/host" \
--volume $SSH_AUTH_SOCK:/ssh-agent \
--env SSH_AUTH_SOCK=/ssh-agent \
--user "$(id -u)" \
--publish 9999:9999 \
"$1" "${2-bash}"
}
main() {
cd "$(dirname "${BASH_SOURCE[0]}")/.."
image=$(basename "${PWD}")
case "$1" in
--build)
docker_build "${image}"
;;
*)
if ! docker inspect "${image}" &>/dev/null; then
docker_build "${image}"
fi
docker_run "${image}"
;;
esac
}
main "$@"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment