- CircleCI listens across all GIT branches and injects $CIRCLE_BRANCH into ENV
- A build step populates a vhost template to point "$CIRCLE_BRANCH.qa.bofh.com" to "/var/www/$CIRCLE_BRANCH/current"
- Another build step creates "manifest.json" with $CIRCLE_BRANCH and $CIRCLE_BUILD_NUM
- The vhost config and the manifest are added to the release tarball/Docker image
- The tarball/image gets shipped to the staging server
- (we ship to S3/Docker, then pull because of security concerns. But can ship inside the build process)
- In staging, a script reads manifest.json and moves content to /var/www/$CIRCLE_BRANCH/$CIRCLE_BRANCH
- The provided nginx vhost is copied into a standard dir with other vhosts
- A symlink of "/var/www/$CIRCLE_BRANCH/current" is forced to point to the fresh release
- nginx -s reload && profit
You can use a wildcard SSL to cover subdomains or add a step to trigger LetsEncrypt certbot as required.This method works equally well with Docker images - just requires an interim step to launch the container. In staging, we use a naming convention to launch on predictable ports for every app. First 2 numbers are app specific, second 3 numbers are build-specific. For example, "25$CIRCLE_BUILD_NUM" (where $CIRCLE_BUILD_NUM is just the last 3 numbers of the build).