June 7, 2019 • ☕️ 6 min read

Same article in Medium: https://medium.com/@thundermiracle/deploy-static-sites-to-netlify-by-circle-ci-ab51a0b59b73

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 flies, 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.

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.

Copy
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 use case.

Let’s define some variants for cache.

Copy
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 the speed as well as flexibility.

test

Copy
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 have already noticed, we’re using executor instead of docker:xxx.

build

Copy
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.

Copy
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.

Copy
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?

The whole yaml sample file is 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 link our website in the account.

Netlify.com

Generate NETLIFY_AUTH_TOKEN

In your [User Settings] → [Applications] → [Personal access tokens].

Link: 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.
Copy
npm install -g netlify-cli
cd your-project-folder
netlify init

netlify-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 step.

  1. In Netlify’s admin panel, [Sites] menu, click [New site from Git], follow the instructions.

Link: https://app.netlify.com/start

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!


Relative Posts

Spam filter for Netlify form in Gatsby

June 18, 2020

ThunderMiracle

Blog part of ThunderMiracle.com