Deploy Static Sites to Netlify by Circle-CI

ThunderMiracle
4 min readJun 7, 2019

--

Photo by 贝莉儿 NG on Unsplash

Back in the 90s’ of the web, about all sites were static. But as web users grow, we want to display rich contents. Then comes up the new architecture — [Front -> Server -> DB] like LAMP (Linux, Apache, MySQL, PHP). WordPress is the one of the most famous. But time flyes, static sites are back! Why?

Why Static Sites

1. Speed. No doubt that static sites are extremely fast.

2. Security. No intermediary means low threat of code injection. No plugins means low worry of catching up the latest version to protect your dynamic site.

3. Low Price. FREE rocking hosting services like Github-Pages or Netlify vs $xx/mon server only for blog or company website. You choose.

4. Easy to migrate. My LAMP site (not WordPress) was DDoS attacked, and that VPS server was stopped automatically before I could login. I requested the provider to let me login and backup the latest data from DB, but was rejected. They said ‘you have only two choices: clean reinstall the server and change the IP or get out of here.’ I moved out. Yes, without the latest DB. Besides, migration cost me much time. But if it was a static site with lambda…

No need Circle-CI, Netlify is enough

Yes. You’re right. You can CD your website to Netlify with only or even without a netlify.toml.

But tests are very important for me, I’d like to test my website before publish them. So, a CI tool is necessary.

Why Circle-CI

I’m not sure whether Circle-CI is the best. But it’s Docker supported just like Gitlab-CI does. So it’s easier for me to understand rather ran Travis-CI. And it’s possible CI Github private repositories too.

Where to build

There are two ways to deploy your site.

1. test in Circle-CI, use webhook to kick the Netlify, Netlify build & deploy

2. test -> build in Circle-CI, push the built files to Netlify by netlify-cli.

Because of the cache function in circle-ci, test & build in circle-ci is much faster. Besides, if you can migrate to another hosting service with changing last step only.

So I choose method №2.

Talk is cheap, show me the code.

Let’s begin

Environment

As I’m using gatsbyjs, docz, storybook, next.js to create my websites. I’d like to compile them in node server.

executors:
node:
docker:
- image: circleci/node:8

Cache

npm with package-lock.json is fast.

yarn with yarn.lock is faster.

yarn with yarn.lock and cache rocks.

As package.json doesn’t change often, cache is great in this usecase.

Let’s define some variants for cache.

aliases:
restore_cache: &restore_cache
restore_cache:
name: Restore Npm Package Cache
keys:
- yarn-cache-netlify-{{ checksum "yarn.lock" }}
install_node_modules: &install_node_modules
run:
name: Install dependencies
command: yarn
save_cache: &save_cache
save_cache:
name: Save NPM package cache
key: yarn-cache-netlify-{{ checksum "yarn.lock" }}
paths:
- ./node_modules

Jobs

As I mentioned before, I’d like to split the steps to ‘test -> build -> deploy’ for speed as well as flexibility.

test

test:
executor: node
steps:
- checkout
# Restore cache at second time
- <<: *restore_cache
# Install for first time
- <<: *install_node_modules
# Cache the ./node_modules before test.
- <<: *save_cache
- run:
name: Test
command: yarn test

You may already notice, we use executor instead of docker:xxx.

build

build:
executor: node
steps:
- checkout
- <<: *restore_cache
- <<: *install_node_modules
- run:
name: Build
command: yarn build
- persist_to_workspace:
root: ./
paths:
- public

deploy

Install netlify-cli and the deploy.

deploy:
executor: node
steps:
- checkout
# Attach the pesisted built files.
- attach_workspace:
at: ./
- <<: *restore_cache
- <<: *install_node_modules
- run:
name: Install netlify-cli
command: sudo npm install -g --silent netlify-cli
- run:
name: Deploy to Netlify
command: netlify deploy --dir=./public -p

As you can see, I can migrate to another host easily by just replacing this part.

Put jobs together

Use workflow the put them together.

workflows:
version: 2
build_and_deploy:
jobs:
- test
- build:
requires:
- test
- deploy:
requires:
- build
filters:
branches:
only: master

That’s all about the configuration yaml, not hard right?

You can find the whole Circle-CI config.yaml here

https://github.com/thundermiracle/gatsby-simple-blog/blob/master/deploy/netlify/.circleci/config.yml.

But the settings are not finished yet.

We’re almost there.

What’s left?

netlify deploy — dir=./public -p

Yes. We haven’t told netlify-cli where to deploy.

We need NETLIFY_AUTH_TOKEN to target our account, and need NETLIFY_SITE_ID to target our website in the account.

Netlify.com

Generate NETLIFY_AUTH_TOKEN

In your [User Settings] -> [Applications] -> [Personal access tokens].

(https://app.netlify.com/user/applications#personal-access-tokens

)

Click [New access token].

Save your token somewhere because it’s showed only once and we’ll use it in circle-ci.

Generate NETLIFY_SITE_ID

Two ways to do it.

1. Install netlify-cli in your local machine. Run netlify init and follow the instructions.

npm install -g netlify-cli
cd your-project-folder
netlify init

At last, cli will generate .netlify/config.json for you. You can set this NETLIFY_SITE_ID in Circle-ci and delete the folder. Or just remain it and skip the NETLIFY_SITE_ID setting.

2. In [Sites], click [New site from Git] (https://app.netlify.com/start

), follow the instructions.

Then you can find your ID here: [Site settings] -> [Site information] API ID is your NETLIFY_SITE_ID.

Circle-CI

Add project

[Add Projects] -> [Set Up Project] -> [Start Building]

PS: No need to copy the config.yml as we created it manually just now.

Set environment viriants

[Project Settings] -> [Environment Variables] -> [Add Variable]

Add your NETLIFY_AUTH_TOKEN and NETLIFY_SITE_ID.

Last

Push your source code to Git and Happy Static Site!

--

--

Responses (1)