So once in a while I try new platform to host my blog. So far i’ve tried Heroku+Jekyll, VPS+Nginx, Netlify+Hugo.
Every option has its Cons and Pros but this post is about: App Engine + Cloud Build + Hugo.
Requirements
https
supportgit push
style deploys- support for various static site compilers
- cheap
- fast
Note: if you’re looking for the simplest setup it’s the Netlify, IMO.
App Engine + Cloud Build
satisfies the requirements above:
- provides
https
support out of the box(once the domain is google managed). - Cloud Build can be configured with source repository to compile and deploy the site.
- cheap, as App Engine standard is free as long as your site doesn’t go over the free quota
- fast, unlike Heroku, initial response times for App Engine instances are, observably, faster(TODO: measure)
- customizable build process: easy to tune build and depoyment process with
cloudbuild.yaml
steps.
There are some cons as well:
- more complex machinery: App Engine is an application runtime thus comes with quite a few of bells and whistles that are unnecessary for static sites.
- build times are slower: ie a deploy on my VPS setup is <5 seconds. Cloud Build takes 2 minutes.
- configuration is limited or requires additional coding.
Prerequisites
- create a GCP project or use an existing one.
- configure domain and TLS. Google’s managed domains are auto provisioned with Free TLS certificates.
- set the daily spend quotas, just to be safe…
- configure IAM permissions so Cloud Build is capable deploying App Engine apps: find [email protected] and add “App Engine Admin”, “App Engine Deployer” roles.
- configure App Engine for the static app see
App.yaml
below - create a build trigger for a connected source repository
- edit the build trigger and specify the path to the
cloudbuild.yaml
in your source repository. In my case it’sdeploy/cloudbuild.yaml
- configure site comilation step; see the
cloudbuild.yaml
below - configure App Engine deployment step; see the
cloudbuild.yaml
below
Deployment
git push origin
- ???
- Profit!!!
References
app.yaml
A runtime suitable for static content.
runtime: python27
api_version: 1
threadsafe: true
instance_class: F1
# disable automatic scaling to avoid incurring costs
automatic_scaling:
target_cpu_utilization: 0.65
min_instances: 0
max_instances: 1
min_pending_latency: 30ms # default value
max_pending_latency: automatic
max_concurrent_requests: 50
# See the reference for more details
# https://cloud.google.com/appengine/docs/standard/python/config/appref
handlers:
## static content routing
- url: /
static_files: public/index.html
upload: public/*
# hugo generates pages in directories so check for index.html first
- url: /(.*)/
static_files: public/\1/index.html
upload: public/*
- url: /
static_dir: public/
error_handlers:
- file: default_error.html
cloudbuild.yaml
Build steps using Hugo to compile the site.
substitutions:
_HUGO_VERSION: "0.52"
images:
- 'gcr.io/$PROJECT_ID/hugo-${_HUGO_VERSION}:latest'
# https://cloud.google.com/cloud-build/docs/build-config
steps:
# the step needed only only when creating/updating Hugo image
- id: 'budil hugo img'
name: 'gcr.io/cloud-builders/docker'
args: [
'build',
'--build-arg', 'HUGO_VERSION=${_HUGO_VERSION}',
'-t', 'gcr.io/$PROJECT_ID/hugo-${_HUGO_VERSION}:latest',
'--cache-from', 'gcr.io/$PROJECT_ID/hugo-${_HUGO_VERSION}:latest',
'-f', 'deploy/hugo.Dockerfile', 'deploy/'
]
- id: 'hugo build site'
name: 'gcr.io/$PROJECT_ID/hugo-${_HUGO_VERSION}:latest'
entrypoint: 'sh'
args:
- -c
- |
hugo -s ./src
mv public/ deploy/
- id: 'gcloud deploy app'
name: gcr.io/cloud-builders/gcloud-slim
dir: deploy/
args: ['--project=$PROJECT_ID', 'app', 'deploy', 'app.yaml']
options:
machineType: 'N1_HIGHCPU_32'
timeout: '120s'
hugo.Dockerfile
Required to build hugo docker image.
FROM alpine:3.5 as build
ARG HUGO_VERSION=0.52
ENV HUGO_BINARY=hugo_${HUGO_VERSION}_Linux-64bit.tar.gz
# Install Hugo
RUN set -x && \
apk add --update wget ca-certificates && \
wget -q https://github.com/spf13/hugo/releases/download/v${HUGO_VERSION}/${HUGO_BINARY} && \
tar xzf ${HUGO_BINARY} && \
rm -r ${HUGO_BINARY} && \
mv hugo /usr/bin && \
apk del wget ca-certificates && \
rm /var/cache/apk/*
ENTRYPOINT ["/usr/bin/hugo"]
GCP Free Quotas
- 28 instance hours per day
- 120 build-minutes per day
- 5 GB Cloud Storage
- Shared memcache
- 1000 search operations per day, 10 MB search indexing
- 100 emails per day