Deployment

Deployments are performed with the appz deploy CLI command which you can run locally from your desktop, or from within a CI build process.

appz deploy

Here's the basic sequence of steps that take place behind the scenes with each deploy:

  • When the appz deploy command is run, the CLI generates a tarball with the contents of the local deploy directory. If your static site output is generated by a build step, either a static site generator or a build tool such as webpack or gulp, that should run first.
  • Your tarball is uploaded to an S3 staging bucket.
  • A Lambda function is triggered which downloads the tarball, extracts it locally, performs optimizations, and writes the output to an S3 folder named after the unique version id.
  • The contents of the S3 folder are replicated to each AWS region where Youappz operates origin servers (currently Oregon and Frankfurt, Germany).
  • Once the version assets have been successfully replicated, the website metadata is updated indicating this new version should be served starting with the next incoming request.

This flow provides some key advantages:

  • You never have to worry about stale assets continuing to be served after a new version is deployed. As soon as the deployment is complete, everyone gets the latest and greatest, guaranteed.
  • Because previous versions are not overwritten, rollbacks are trivial - just a quick change in the dashboard to point back to the previous version.
  • Geo load-balancing to the nearest AWS region means that your website visitors get a snappy downloads no matter where they are in the world.

Deploy stages

Youappz makes it super easy to deploy to different "stages". A stage is simply an instance of the site available at a dedicated URL. This is a great way to manage testing and previews of new versions. By default the appz deploy command deploys to the "production" stage which is your main URL. However you can specify the -s or --stage argument to deploy to a different stage. For example:

appz deploy --stage test

This will make the deployed site available at unique URL. The form of the URL depends on whether there is a custom domain and if the production site is using a CNAME or the apex.

URL styleProduction url"test" stage URL
Shared domainhttps://site-name.sitez.livehttps://test-site-name.sitez.live

|

In the table above the stage name "test" could be anything you like, "preview", "develop", "etc".

Protection of stages

In general you probably want to prevent the general public from accessing your site's test URL. This is straightforward to do with both the password-protect plugin and client IP ranges.

Password protect

The declaration below in your appz.yml file will enforce password protection, but only in the test stage:

plugins: - name: password-protect stages: [test] options: password: $SITE_PASSWORD

Client IP ranges

To set allowed client IP ranges, use the CLI clientip command.

appz clientip --value '97.113.60.0/24' --stage test

A shorthand way to lock it down to just your current personal IP is using the "myip" special value:

appz clientip --value myip --stage test

Continuous deployment

Deploying your website directly from your local terminal is a great way to get started with minimal friction. However as the deployment process matures and particularly if there's a team of contributors, it makes sense to move to a CD workflow where git commits automatically trigger a build and deployment of the website using a CI/CD service.

The @youappz/cli can easily be installed and run as part of a build script with any of the growing set of CI/CD services including: Jenkins, Travis, Bitbucket Pipelines, Codeship, CircleCI, AWS CodeBuild, and many more.

The example below is for a Jekyll site built with Travis, but the basic concepts are all transferrable to other static site generators and CI/CD services.

Travis uses a .travis.yml file to specify the build and deploy steps. Here's where we specify how to run the jekyll build step. After the build step has completed successfully, @youappz/cli is globally installed from npm. Finally the appz deploy command will deploy the built assets as a new version to Youappz. In this case we are deploying to the production stage. Further down in this article we'll talk about how to deploy to test, staging etc.

language: ruby
env: global: - secure: <encrypted_env_vars> # See APPZ_API_KEY below - TRAVIS_NODE_VERSION="6.9.5"
install: - rm -rf ~/.nvm && git clone https://github.com/creationix/nvm.git ~/.nvm - (cd ~/.nvm && git checkout `git describe --abbrev=0 --tags`) - source ~/.nvm/nvm.sh - nvm install $TRAVIS_NODE_VERSION - bundle install --path vendor/bundle - npm install
script: - bundle exec jekyll build
after_success: - npm install @youappz/cli -g - appz deploy \ --commit-url "https://github.com/owner/repo-name/commit/${TRAVIS_COMMIT}" \ --directory _site

You'll notice in the appz deploy call above we are passing two arguments: --commit-url and --directory. The commit-url is simply the URL to the commit that triggered the build. This is optional, but if provided the Youappz control panel will include a link back to this URL in the deployment history which can be helpful for maintaining a connection between the code changes and what was deployed. The directory argument is the directory where the built assets were written which, in the case of jekyll, defaults to _site. This can be specified as a CLI arg or it can be declared in the deploy section of appz.yml.

  • Jekyll Continuous Deployment with Bitbucket Pipelines and Youappz
  • Deploy a Hugo site to Youappz with CircleCI
  • Hugo Continuous Deployment with Bitbucket Pipelines and Youappz

API Key environment variable

An environment variable named APPZ_API_KEY needs to be set in the build script in order to make authenticated calls to the Youappz API. Each CD service has a mechanism for setting environment variables. It's recommended that the value be encrypted if your service supports it. Travis provides a command line tool for encrypting a variable and injecting it into the .travis.yml file:

travis encrypt APPZ_API_KEY=your_api_key --add env.global

You can get the value of your enviroment variable by running the apikey command. All websites associated with an Youappz account will have the same API key value.

appz apikey

CI/CD with deploy stages

The example above will deploy any branch configured for CI to the production branch. However you may want to deploy different branches to different instances of your website. This is straightforward using Youappz deploy stages - albeit with a little bash trickery. We are now passing an additional stage argument which specifies the name of the stage to deploy to. If the stage name is anything other than "production", the stage is incorporated into the deployed URL, i.e. https://www--test.domain.com or https://test.domain.com (if the production URL is using an apex domain). This script is using the convention that the master branch is deployed to production and anything else is deployed to a stage named the same as the branch.

after_success: - npm install @youappz/cli -g - appz deploy \ --commit-url "https://github.com/owner/repo-name/commit/${TRAVIS_COMMIT}" \ --stage $([ $TRAVIS_BRANCH = 'master' ] && echo 'production' || echo $TRAVIS_BRANCH ) \ --directory _site

You could even deploy each pull request to a dedicated deploy stage:

appz deploy --stage pr-$TRAVIS-PULL-REQUEST 
  • Any characters other than letters, numbers, dashes, or underscores in the stage argument will be converted to a dash "-" to ensure URL friendliness. So feature/new-nav will be feature-new-nav in the stage URL.

Any characters other than letters, numbers, dashes, or underscores in the stage argument will be converted to a dash "-" to ensure URL

This technique works with any CI service that provides similar environment variables (and most all do). The configuration is a bit cleaner with some of the other CI services (such as Circle CI) that provide the flexibility to defined distinct deploy steps on per-branch basis.

Deploy alerts

You can specify that an alert be sent whenever a deployment completes. The two currently supported alert types are email and Slack. To send an alert for all deployments (regardless of stage), declare YAML like so in your appz.yml:

deploy: alerts: default: # You can specify one or both of these keys email: to: [[email protected], [email protected]] slack: username: 'Website Update' # Optional, defaults to "Youappz Deploys" webhookUrl: https://hooks.slack.com/services/xxx/xxx/xxxx

To get the webhookUrl, just add the Incoming Webhook App to your Slack instance. You simply specify which channel you want the alerts to be posted to (i.e. something like "#deployments") and you'll be provided the URL to paste into your appz.yml file. You can also choose an icon or emoji that appears next to each alert.

If you don't want to store the webhookUrl in clear text, you can also configure it as an environment variable:

slack: webhookUrl: $SLACK_DEPLOY_ALERT_URL

Deploy these changes and you'll start getting alerts with each new deployment. The alert includes the name of the website, the version name, an optional message, and a hyperlink that launches the site.

The deploy message is a handy way to provide a short description of the what was changed. The message is provided to the appz deploy command like so:

appz deploy --message 'Added new link to the global footer'

Stage specific alerts

There is also the flexibility to define different alerts based on the deploy stage. For example, if you are an agency, you might want to post alerts for all deployments to your team's internal Slack channel, but additionally send an email alert to the client for production deployments:

deploy: alerts: default: slack: webhookUrl: https://hooks.slack.com/services/xxx/xxx/xxxx production: email: to: [[email protected]] # Alert the client for production deployments

You can also omit the default section altogether and configure alerts on a stage by stage basis - whatever best fits your workflow.

Updated at Tue, Sep 13, 2022