Fixing A Broken Deployment to Google App Engine

It’s been ten years since I created the first version of benpatterson.io.

In 2014, I took a web development on Udacity that was taught by Steve Huffman of Reddit fame. He taught authentication, salting passwords, the difference between GET and POST requests, basic html and css, caching techniques. It was a fantastic introduction to web dev. To pass the course, students deployed simple python servers to Google App Engine. When I started to look for work, I opted to use code from that class to deploy a personal site to google app engine.

Years later, benpatterson.io is no longer written in python but it still lives on Google App Engine. I ran into a bit of trouble posting my last technical entry.

First, jekyll wouldn’t run on my new Mac.

I ran bundle install but it threw errors. I deleted the Gemfile.lock file, ran bundle install again and it finished without errors. However, bundle exec jekyll serve would not run the site! Jekyll-admin was throwing Error: uninitialized constant Rack::Handler.

Frustrated, I removed jekyll-admin from the Gemfile, ran bundle install and then bundle exec jekyll serve. That got rid of one error but exposed a new one.

 Conversion error: Jekyll::Converters::Scss encountered an error while converting 'assets/css/noscript.scss':
                    expected "{".
                    ------------------------------------------------
      Jekyll 4.3.3   Please append `--trace` to the `serve` command 
                     for any additional information or backtrace. 

After some googling and reading this post, I determined that having a file named noscript.css in the assets directory and a file named the same in the _sass directory was causing the issue. The fix was to rename noscript.css to no-script.css.

Now the site was running locally! Ecstatic, I made a tiny change and pushed it up to github to make sure the CI/CD pipeline was still working.

It was not.

I checked build logs and found that bundle install was not working the same as it did on my machine. I installed rvm, tried multiple versions of ruby, attempted to upgrade various gems. Nothing worked.

I suspected the that it must be due to differences between running on a mac and in linux. This suspicion was easy enough to verify with docker and VS Code.

VS Code does a great job running a folder inside a docker containers. I started up docker, clicked the two blue arrows on the left bottom corner of VS Code and chose.

Reopen in container

I also, chose an ubuntu base with ruby as an addon.

VS Code creates .devcontainer/devcontainer.json file when code is running in a new container. Here’s mine.

{
	"name": "Ubuntu",
	"image": "mcr.microsoft.com/devcontainers/base:jammy",
	"features": {
		"ghcr.io/devcontainers/features/ruby:1": {}
	}

}

With the code running in Ubuntu/docker, I attempted to duplicate the build issue in the pipeline by running bundle install from the terminal inside VS Code.

The exact same error occurred. My suspicions were confirmed.

I deleted the Gemfile.lock and ran bundle install. The install worked!

I ran bundle exec serve. That worked too!

Eager to see the build work in the CI/CD pipeline, I pushed up my changes. The build completed and it attempted to push the built site to app engine.

It failed.

The format of my app.yaml file was at least ten years old and had been completely deprecated since the last time I deployed.

This is what the old file looked like.

runtime: python27
api_version: 1
threadsafe: true

handlers:
  - url: /
    static_files: jekyll-app/_site/index.html
    upload: jekyll-app/_site/index.html
    secure: always

  - url: /(.*)
    static_files: jekyll-app/_site/\1
    upload: jekyll-app/_site/(.*)
    secure: always

skip_files:
- ^(node_modules/.*)
- ^(node_modules/.*)
- ^(jekyll-app/.jekyll-cache/.*)
- ^(jekyll-app/.sass-cache/.*)
- ^(jekyll-app/.jekyll-cache/.*)
- ^(jekyll-app/.jekyll-metadata/.*)
- ^(jekyll-app/vendor/.*)

Here is the new file.

runtime: python312
handlers:
  - url: /
    static_files: jekyll-app/_site/index.html
    upload: jekyll-app/_site/index.html
    secure: always

  - url: /(.*)
    static_files: jekyll-app/_site/\1
    upload: jekyll-app/_site/(.*)
    secure: always

In the new file, the runtime changed to python312, the api_version, threadsafe and skip_files options are removed. The skip files are now noted in .gcloudignore file and matches the format of a .gitignore file.

Success! The site built and deployed in cloud build again! Take a look at my previous post if you’re curious to see how I set that up in the first place.

I eventually got jekyll-admin working locally again by adding the following to my Gemfile

gem "sinatra", ">= 3", "< 4"

It’s hard to believe that benpatterson.io has been up for ten years. It’s still fun to tinker with and posting again makes me happy.

App Engine is overkill for a static site. Setting up a CDN and uploading directly to a bucket would be simpler but there’s been no immediate need to change how benpatterson.io’s hosted. See https://cloud.google.com/storage/docs/hosting-static-website if you’re building a static site on google from scratch.

Advertisement