Deploy to DigitalOcean from CircleCI; Overcome Permission Denied

For more than two weeks now, I’ve been trying to figure out the magic bullet to getting my builds on CircleCI to be pushed and deployed onto DigitalOcean via SSH (specifically, scp)

Through try and error, I got one of my repos to build. As to what I did and tweaked to get it working, I couldn’t remember.

I tried another CI stuff just now, and before I forget how I got it working, I’m writing the process down here, for myself and anyone who might find it useful


First, let’s conjoin on the same page for clarity. Here’s what this article helps achieve, specifically!

  • You have a PWA Angular app you wish to deploy (technically, it could be anything, just using an Angular PWA in this instance)
  • You’ve added your config.ymlCI file (will show you one below)
  • After build of PWA on CI, you want the ./dist/<project_name>/*files copied via scp (SSH Copy, which means we’ll be needing SSH) to your DigitalOcean Droplet (It could be any VPS provider)
  • This tutorial assumes you already, can communicate with your remote server from your local machine (the PC/laptop you’re sitting behind) via SSH.
    • At this point, if you have no idea what SSH is, you may close the browser tab, and have a nice day!

If the above is your scenario, which was mine, let’s rock and roll.

Follow these instructions carefully. I’m going to be very thorough with the steps.

Generate SSH on Remote Server

Log into your remote server, namely, the one in the cloud, in other words, the one where the files will be copied to from the Circle CI.

You ssh into the server with a command in terminal/command prompt such as ssh username@server_ip or ssh username@domain_name

When logged in, enter these commands

NOTE: after entering ssh-keygen, with regards to where to save the key that’s to be generated as a result of the ssh-keygencommand, type


$ cd ~
$ cd ~/.ssh/
$ ssh-keygen

Now, hold your beer!

Add Public Key to authorized_keys

This step is crucial. Copy the ~/.ssh/for_circle.pubfile contents to ~/.ssh/authorized_keys


cat ~/.ssh/ >> ~/.ssh/authorized_keys

Note: We’re using >> so that the contents are appended to the end of the contents in the authorized_keysfile, rather than override the contents in the authorized_keyswith only the contents.


Remember, everything we’ve done so far is on the Remote Server.

Private Key to CircleCI

Now, on the server, in the previous steps, 2 files were generated from the ssh-keygen command. We’ve only used the file. The other one is the for_circle(without the .pub extension).

Run this command to print the contents of the for_circle file in your terminal, then copy the contents in your computer’s clipboard

Copy Private Key to Clipboard

In this case, command will be

cat ~/.ssh/for_circle

Then as shown in the GIF above, copy the entire key.


Good. Now, navigate to your CircleCI Project settings page. Mine looks something like this:

Access SSH Permission Settings Circle CI

Now, add the private key contents you copied (the one into clipboard), paste into “Add Private Key” dialog box.

Saving Private Key to CircleCI

With the steps above completed, we’re left with only a single step more, namely, our .circleci/config.ymlfile.


This is the contents of the config.yml for our PWA

# Javascript Node CircleCI 2.0 configuration file
# Check for more details
version: 2
        - master

      # specify the version you desire here
      - image: circleci/node:10.12.0

    working_directory: ~/repo


      - checkout

      # Download and cache dependencies
      - restore_cache:
          - v1-dependencies-{{ checksum "package.json" }}
          # fallback to using the latest cache if no exact match is found
          - v1-dependencies-

      # let's install npm
      - run: npm install --silent

      # install angular cli latest globally
      - run: sudo npm install -g @angular/cli@latest --silent

      # update 
      - run: ng update
      # ng build --prod
      - run: ng build --prod

      - save_cache:
            - node_modules
          key: v1-dependencies-{{ checksum "package.json" }}
      # copy dist files to digitalocean
      - run: scp -o StrictHostKeyChecking=no -r ./dist/Playground/*

      ################ WARNING WARNING #####################
      # doing no strict host key check is a security risk to some extent.
      # But I haven't figured a way to add to ssh for both CI and DO to communicate without that
      # message popping up 

The above file, config.yml, kindly put it in a folder called .circleciin your project root directory.

config.yml in project root of angular

Moment of Truth!

Commit the config.ymlchanges, and push to your repository which is tied to your CircleCi.

It should build and push to the droplet without any errors.


If all is well, you should be able to re-run your build as SSH (done from the CI dashboard), ssh into the CI Image, then from there, ssh into the remote server without any issues.

Related Articles

Back to top button