Skip to content

Instantly share code, notes, and snippets.

@costa
Last active March 9, 2020 00:32
Show Gist options
  • Save costa/4bb6416e22381f37095424172aeefd18 to your computer and use it in GitHub Desktop.
Save costa/4bb6416e22381f37095424172aeefd18 to your computer and use it in GitHub Desktop.
docker dev env script outfit for GCE, source it in your ~/.bash_profile and use dev-init, dev and dev-tunnel commands it provides
# NOTE pre-requisite: ~/.ssh/google_compute_engine is a GCE access key, see https://cloud.google.com/compute/docs/instances/connecting-to-instance
# NOTE google compute zone must be pre-set somehow: e.g. see in https://cloud.google.com/sdk/gcloud/reference/compute/scp
dev() {
if [ -z "$1" ]
then echo "USAGE: dev <docker host command...> # FROM A PROJECT DIRECTORY, DEV_DOCKER_MACHINE needs to be set, AFTER dev-init...!" 1>&2
return 999
fi
machine_name=$DEV_DOCKER_MACHINE
if [ -z "$machine_name" ]
then
echo "export DEV_DOCKER_MACHINE=<your dev instance> # and pre-set zone somehow as well" 1>&2
return 999
fi
if [ "`pwd`" == "$HOME" ]
then
echo "ERROR: to be run from some project directory" 1>&2
return 999
fi
proj_name=$( basename `pwd` )
ssh_cmd="ssh -i ~/.ssh/google_compute_engine -o BatchMode=yes -o UserKnownHostsFile=/dev/null -o CheckHostIP=no -o StrictHostKeyChecking=no"
host="$( gcloud compute instances describe $machine_name --format='value(networkInterfaces[0].accessConfigs[0].natIP)' )"
host_user="$( whoami )"
host_path="/home/$host_user/proj/$proj_name"
echo "$proj_name (DO NOT make local file changes until this finishes!)"
while ! $ssh_cmd $host "( mkdir -p $host_path && cd $host_path && sudo chown -R $host_user: . )"
do sleep 3
done
while ! rsync -vrlptDz --del -e "$ssh_cmd" . $host_user@$host:$host_path/
do sleep 3
done
$ssh_cmd $host "( cd $host_path && $@ )" && \
while ! rsync -vrlptDz --del -e "$ssh_cmd" $host_user@$host:$host_path/ .; do sleep 3; done
}
dev-tunnel() {
if [ -z "$3" ] || [ -n "$4" ]
then echo "USAGE: dev-tunnel <local port> <service name> <service port> # FROM A PROJECT DIRECTORY, AFTER dev sudo docker-compose...!" 1>&2
return 999
fi
machine_name=$DEV_DOCKER_MACHINE
if [ -z "$machine_name" ]
then echo "export DEV_DOCKER_MACHINE=<your dev instance> # and pre-set zone somehow as well" 1>&2
return 999
fi
proj_name="$( basename `pwd` )"
ssh_cmd="ssh -i ~/.ssh/google_compute_engine -o BatchMode=yes -o UserKnownHostsFile=/dev/null -o CheckHostIP=no -o StrictHostKeyChecking=no"
host="$( gcloud compute instances describe $machine_name --format='value(networkInterfaces[0].accessConfigs[0].natIP)' )"
host_user="$( whoami )"
host_path="/home/$host_user/proj/$proj_name"
lport=${1:-8880}
svc=${2:-web}
port=${3:-80}
ip=$( $ssh_cmd $host "( cd $host_path && sudo docker-compose ps | grep _${svc}_ | cut -d' ' -f1 | xargs -n 1 sudo docker inspect --format='{{range .NetworkSettings.Networks}}{{.IPAddress}} {{end}}' | cut -d' ' -f1 )" ) # TODO escape me, also, couldn't find a way to print the first element in map range (go templates!)
if [ -z "$ip" ]
then echo "Error getting the service's local IP, maybe dead." 1>&2
return 3
fi
$ssh_cmd $host_user@$host -L $lport:$ip:$port -N
}
# NOTE docker-compose version is hard-coded to 1.14.0 (too lazy to be bothered)
dev-init() {
machine_name="$1"
if [ -z "$machine_name" ]
then echo "USAGE: dev-init <machine name> # GOOGLE_PROJECT needs to be set, default gcloud zone needs to be set" 1>&2
return 999
fi
if [ -z "$GOOGLE_PROJECT" ]
then echo "ERROR: GOOGLE_PROJECT needs to be set, also make sure default gcloud zone is set" 1>&2
return 999
fi
echo "INFO Booting the machine..."
while ! gcloud compute instances create $machine_name --image ubuntu-1604-xenial-v20170619a --image-project ubuntu-os-cloud --boot-disk-size ${GOOGLE_DISK_SIZE:-256} --machine-type ${GOOGLE_MACHINE_TYPE:-n1-standard-2} --project $GOOGLE_PROJECT --scopes https://www.googleapis.com/auth/cloud-platform
do sleep 3
done
host="$( gcloud compute instances describe $machine_name --format='value(networkInterfaces[0].accessConfigs[0].natIP)' )"
ssh_cmd="ssh -i ~/.ssh/google_compute_engine -o BatchMode=yes -o UserKnownHostsFile=/dev/null -o CheckHostIP=no -o StrictHostKeyChecking=no"
while ! $ssh_cmd $host "echo 'vm.max_map_count=262144' | sudo tee -a /etc/sysctl.conf"
do sleep 3
done
echo "INFO Installing docker* with apt..."
while ! $ssh_cmd $host 'curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -'
do sleep 3
done
while ! $ssh_cmd $host 'sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"'
do sleep 3
done
while ! $ssh_cmd $host 'sudo apt-get -y update && sudo apt-get -y install docker-ce' # NOTE docker-compose supplied by apt is outdated, hence below :(
do sleep 3
done
while ! $ssh_cmd $host 'sudo bash -c "curl -fsSL https://github.com/docker/compose/releases/download/1.17.0/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose && chmod +x /usr/local/bin/docker-compose"'
do sleep 3
done
echo "INFO Setting up mail..."
while ! $ssh_cmd $host 'curl -fsSL https://gist.githubusercontent.com/costa/a325e7fdc5a803e1e5425fd36a784fe7/raw/cc88de0689cdf41c0dbba46195c9d38a73d83c48/gcloud-machine-sendgrid-mail-setup.sh | sudo sh'
do sleep 3
done
# TODO swapppp
# sudo fallocate -l 30G /swapfile
# sudo chmod 600 /swapfile
# sudo mkswap /swapfile
# sudo swapon /swapfile
# echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab
while ! $ssh_cmd $host mkdir proj
do sleep 3
done
echo "Very good ($ echo 'export DEV_DOCKER_MACHINE=$machine_name' >> ~/.bashrc), now do try to (recommended) $ $ssh_cmd $host 'sudo apt-get remove --auto-remove -y sshguard; sudo reboot'"
}
dev-once() {
machine_name=test-`date +"%Y%m%d%H%M%S"`-dev
dev-init $machine_name && \
DEV_DOCKER_MACHINE=$machine_name dev "bash -xc '$* && yes | gcloud compute instance delete $machine_name'&"
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment