Skip to content

Test, build, push (to DockerHub) and deploy a long running "hello-world" Docker Image to Google Compute Engine (gce).

License

Notifications You must be signed in to change notification settings

JeffDeCola/hello-go-deploy-gce

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

HELLO GO DEPLOY GCE

Tag Latest Go Reference Go Report Card codeclimate Maintainability codeclimate Issue Count Docker Pulls MIT License jeffdecola.com

Deploy a "hello-world" docker image to Google Compute Engine (gce).

Other Services

Table of Contents

Documentation and Reference

OVERVIEW

Every 2 seconds this App will print,

    INFO[0000] Let's Start this!
    Hello everyone, count is: 1
    Hello everyone, count is: 2
    Hello everyone, count is: 3
    etc...

PREREQUISITES

You will need the following go packages,

go get -u -v github.com/sirupsen/logrus
go get -u -v github.com/cweill/gotests/...

This repo contains the packer gce image build scripts,

git clone git@github.com:JeffDeCola/my-packer-image-builds.git

SOFTWARE STACK

RUN

To run.sh,

cd hello-go-deploy-gce-code
go run main.go

To create-binary.sh,

cd hello-go-deploy-gce-code/bin
go build -o hello-go ../main.go
./hello-go

This binary will not be used during a docker build since it creates it's own.

STEP 1 - TEST

To create unit _test files,

cd hello-go-deploy-gce-code
gotests -w -all main.go

To run unit-tests.sh,

go test -cover ./... | tee test/test_coverage.txt
cat test/test_coverage.txt

STEP 2 - BUILD (DOCKER IMAGE VIA DOCKERFILE)

This docker image is built in two stages. In stage 1, rather than copy a binary into a docker image (because that can cause issues), the Dockerfile will build the binary in the docker image. In stage 2, the Dockerfile will copy this binary and place it into a smaller docker image based on alpine, which is around 13MB.

To build.sh with a Dockerfile,

cd hello-go-deploy-gce-code/build
docker build -f Dockerfile -t jeffdecola/hello-go-deploy-gce .

You can check and test this docker image,

docker images jeffdecola/hello-go-deploy-gce
docker run --name hello-go-deploy-gce -dit jeffdecola/hello-go-deploy-gce
docker exec -i -t hello-go-deploy-gce /bin/bash
docker logs hello-go-deploy-gce
docker rm -f hello-go-deploy-gce

STEP 3 - PUSH (TO DOCKERHUB)

You must be logged in to DockerHub,

docker login

To push.sh,

docker push jeffdecola/hello-go-deploy-gce

Check the hello-go-deploy-gce docker image at DockerHub.

STEP 4 - DEPLOY (TO GCE)

There are three steps to deploy on gce,

  • STEP 4.1 - Build a gce image
  • STEP 4.2 - Create an instance template (HW resources)
  • STEP 4.3 - Create an instance group (Launch VM in region)

For this example, I will add two running services,

  • The dockerhub image runs at boot hello-go-deploy-gce
  • A binary /home/jeff/hello-go executable runs at boot

To keep things simple, the files are located in my my-packer-image-builds repo.

STEP 4.1 BUILD A CUSTOM MACHINE IMAGE USING PACKER

You will need to set the following environment variables (I added mine in ~/.bashrc),

export GCP_JEFFS_SERVICE_ACCOUNT_PATH=[path to your google platform .json file]
export GCP_JEFFS_PROJECT_ID=[your project id]

To validate your packer template file template.pkr.hcl,

cd my-packer-image-builds/google-compute-engine-images/jeffs-gce-image-ubuntu-2204
packer validate \
    -var "image_name=hello-go-deploy-gce" \
    -var "account_file=$GCP_JEFFS_SERVICE_ACCOUNT_PATH" \
    -var "project_id=$GCP_JEFFS_PROJECT_ID" \
    template.pkr.hcl

To build-image.sh on gce,

cd my-packer-image-builds/google-compute-engine-images/jeffs-gce-image-ubuntu-2204
packer build \
    -var "image_name=hello-go-deploy-gce" \
    -var "account_file=$GCP_JEFFS_SERVICE_ACCOUNT_PATH" \
    -var "project_id=$GCP_JEFFS_PROJECT_ID" \
    template.pkr.hcl

Check that the image was created at gce,

gcloud config set project $GCP_JEFFS_PROJECT_ID
gcloud compute images list --no-standard-images

STEP 4.2 CREATE AN INSTANCE TEMPLATE

The instance template contains the HW resources the instance group needs to create the VM instance.

To create-instance-template,

cd my-packer-image-builds/google-compute-engine-images/jeffs-gce-image-ubuntu-2204
sh create-instance-template.sh "jeffs-hello-go-deploy-gce-image" "hello-go-deploy-gce"

Check the instance template was created,

gcloud compute instance-templates list

STEP 4.3 CREATE AN INSTANCE GROUP

The instance group controls the show. It launches and scales your VM instances as needed.

To create-instance-group,

cd my-packer-image-builds/google-compute-engine-images/jeffs-gce-image-ubuntu-2204
sh create-instance-group.sh "jeffs-hello-go-deploy-gce-instance-template" "hello-go-deploy-gce"

Check that the instance group and VM instance were created,

gcloud compute instance-groups list
gcloud compute instances list

CHECK SERVICES ARE RUNNING

To ssh into your gce VM, I placed my public keys in gce metadata ssh keys, which automatically places them in the authorized_keys files on my VM,

ssh -i ~/.ssh/google_compute_engine jeff@<IP>

Check the docker service is running,

docker ps
docker logs -f --tail 10 -f hello-go-deploy-gce

Check that your hello-go.service is running,

# Remember, it kicks off /home/jeff/hello-go
systemctl list-unit-files | grep hello.go
sudo systemctl status hello-go
journalctl -f
sudo systemctl stop hello-go
cat /lib/systemd/system/hello-go.service
sudo -s

Last, if you have multiple VMS, and since you put the same ssh keys in /home/jeff/.ssh when you built the image with packer, your VMs can talk to each other using gce's internal DNS.

ssh <USERNAME>@<HOSTNAME>.us-west1-a.c.<PROJECT>.internal

CONTINUOUS INTEGRATION & DEPLOYMENT

Refer to ci-README.md on how I automated the above steps using concourse.