~/theoboursy.fr/gopher

Go web app · Google Cloud

Hall of Gopher

A Go image gallery. Visitors upload a photo with their name, a Cloud Function crops every image to the same size, and a live slider shows the processed gallery, updating without a page reload. It runs on Cloud Run behind an ultra-optimized multi-stage Docker build.

Dockerfile the interesting bit

One Dockerfile, three stages

A single multi-stage Dockerfile covers the whole lifecycle. The build stage compiles a static Go binary with CGO_ENABLED=0 and stripped symbols. The dev stage runs it with air for hot reload. The prod stage starts from scratch and copies in only the binary, the CA certificates and the assets.

The result is a tiny image with no OS underneath and a near-zero cold start, which is exactly what a scale-to-zero Cloud Run service wants.

FROM scratch AS prod
COPY --from=build /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/
COPY --from=build /server /server
COPY app/templates/ /templates/
COPY app/static/ /static/
ENTRYPOINT ["/server"]
function.go

Upload, crop, display

An upload lands in a Cloud Storage bucket under img/before/. That triggers a Go Cloud Function which center-crops the image and writes it to img/after/, so every picture in the gallery shares the same clean format.

  • GCS event trigger
  • center crop 800x600
  • JPEG quality 85
main.go

Live gallery, no reload

The home page polls a JSON API and slides new images in as they are processed, each labelled with its uploader. Signed URLs are cached for 30 minutes to avoid flicker, and a QR code links straight back to the gallery.

  • /api/images
  • signed URLs, 30 min
  • QR code
.gitlab-ci.yml

Cloud Run and GitLab CI

Cloud Build ships the image to Artifact Registry and GitLab CI deploys it to Cloud Run. As a study-project requirement there is no Terraform here, just container images and Cloud Run service config.