Atomic Deployments?

Hello,
I have a repository which consists mainly of a PHP application. But inside that application I have three Vue.js application which needs to be built.

What I currently do is, that I have a build.sh script in my repository with the necessary yarn commands to build those apps. Everything is deployed via SSH to DigitalOcean.

I do this with a provider called DeployHQ. Now I want to switch to CircleCI’s pipelines and have difficulties about the following scenario.

I can do this:

version: 2
jobs:
  build:
    docker:
      - image: circleci/node:12.15.0
    parallelism: 1
    working_directory: ~/sw
    steps:
      - checkout
      - run: ./build.sh
      - run: mkdir -p dist
      - persist_to_workspace:
          root: dist
          paths: .

In that case I should get the whole repository checked out and the Vue application’s are built inside my node container. But how can I transfer the files to my server and implement atomic deployments?

I know that one option is to put a deploy.sh script inside my repo and call this via SSH inside of my workflow. But in that case, the deploy.sh script usually checks out the latest git commit, which does not include my files which are built in my container.

What I can think of is, that I built the releases/ and symlinks to current inside of my workflow with ssh commands and transfer evrything from my container above to that folder. Is this the right way of doing what I want to do?

One other thing that I have in mind is not to transfer everything from my repo to my server, but to copy the previous release into a new folder and copy the files which have changed into the folder, but even here - how do I do this with CircleCI as with the example above I get all files, right?

Appreciate if someone can bring some clarity… thanks!

Hi @elbsurfer,

Welcome to the CircleCI community!

Yes, Deploying your application using SSH is a sure fire way to Deploy your application to Digital Ocean using CircleCI. You can transfer the files to your server using a deploy command that might look something like: ssh $SSH_USER@$SSH_HOST "<remote deploy command>"

If you are using a script that is pulling the latest commit and want it to include the files built in your container, you can push your repo to GitHub before running your deployment script.

You can find more information and examples of deploying with SSH in our docs here.

I also found this medium article that outlines how to deploy to Digital Ocean using CircleCI : https://circleci.com/docs/2.0/deployment-examples/#ssh

I wanted to point out that you can SSH into your container. This is super useful when debugging.

Let me know if you have any additional questions.

1 Like

Hey @Henna,
thanks for getting back to me. I made some progress but one thing I do not understand currently.

So I do this in my build step:

working_directory: ~/fp_sw
    steps:
      - attach_workspace:
            at: ~/fp_sw
      - checkout
      - run: ./build.sh
      - run: mkdir -p dist
      - persist_to_workspace:
          root: dist
          paths: .

In my understanding the working directory defines where the result of the checkout command is stored. Then I run my build.sh script and everything which is in ~/fp_sw is stored in ~/dist because of the persist_to_workspace? Or where does root points exactly? Is it /dist or ~/dist or ~/fp_sw/dist ?

Why do I need attach_workspace here when I persist the whole workspace to dist? As the build.de script stores the built files already within the fp_sw folder, do I need to persist_the_workspace when I already attach it? I logged in to my build container, and it looks fine - everything is in ~/fp_sw

After that I do this in my deploy script:

deploy:
    working_directory: ~/fp_sw
    machine:
      enabled: true
    steps:
      - attach_workspace:
            at: ~/fp_sw
      - run:
          name: Deploy Over SSH
          command: |
            currentDate=$(date +%Y%m%d%H%M%S);
            ssh $SSH_USER@$SSH_HOST "cd ; mkdir $currentDate"
            scp -o StrictHostKeyChecking=no -r dist/* $SSH_USER@$SSH_HOST://home/$currentDate

But it tells me, that dist is not known. I tried all variants ~/dist or ~/fp_sw/dist. Everytime the folder can not be found. I logged in to this container and ~/fp_sw is empty. So it does not work on the same workspace as the build step? I thought I understood that the attach_workspace here makes the workspace from build available in deploy.

@Henna

I made progress on this one. However, some things are weird to me. For example. I use this command:

rsync -az \
--force \
--delete \
--exclude-from=~/fp_sw/.deployignore \
-e 'ssh -p 22' ~/fp_sw/* $SSH_USER@$SSH_HOST:./deploy 

Circle CI tells me rsync: failed to open exclude file ~/fp_sw/.deployignore: No such file or directory (2)

When I ssh into the container and move to fp_sw where .deployignore is located and type pwd I see:

/home/circleci/fp_sw

Why is ~/fp_sw/.deployignore not working then?

@elbsurfer, Thanks for the update.

Per this particular issue, can you try using a absolute path : /home/circleci/fp_sw/.deployignore