Automate Your Deployments With Cron

Pascal Allen
3 min readNov 1, 2023

--

Photo by Christian Lue on Unsplash

Firstly, for succinctness, I will presume that you have an existing project on an existing Linux server. Secondly, this is purely demonstrative and is not a be-all-end-all solution for deployments. It’s important to have a clear understanding of what your needs are when deploying. This is a very basic solution. Use the information that you learn here today and consider plenty of other options to make an informed decision about your deployment process.

Creating a Deployment Script

Let’s start by adding a scripts/ directory to our project and within that directory add the following boilerplate code to a file named cron-deploy:

#!/usr/bin/env bash

# change to the project root
DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
cd "$DIR"/.. || exit

# create bash environment variables from .env file
export "$(grep -v '^#' .env | xargs -d '\n')"

# change to main branch, if needed
BRANCH="$(git branch --show-current)"
if [ "$BRANCH" != "main" ]
then
git checkout main -q
fi

# bring up environment, if changes have been made
GIT_STATUS="$(git status -s)"
if [ -n "$GIT_STATUS" ]
then
git pull \
&& docker compose --progress quiet down \
&& docker system prune -a -f \
&& docker builder prune -a -f \
&& docker compose -f docker-compose.yml --progress quiet build \
&& docker compose -f docker-compose.yml --progress quiet up -d \
&& yarn install --frozen-lockfile \
&& webpack --config webpack.config.js --mode production
fi

# send notification, if services are not running
DOCKER_STATUS="$(docker compose ps --status running --format "{{.Name}}")"
if [[ "$DOCKER_STATUS" != *"pascalallen-go"* ]] || [[ "$DOCKER_STATUS" != *"pascalallen-postgres"* ]]
then
curl -H "Content-type: application/json" \
--data '{"channel":"$SLACK_CHANNEL_ID","blocks":[{"type":"section","text":{"type":"mrkdwn","text":"Deploy *_failed_*."}}]}' \
-X POST "$SLACK_DM_URL"
fi

There’s a bit to unpack here. Let’s break it down in order.

  1. The first thing our script does is change to the project root.
  2. From the root of the project, we now export our environment variables from our project’s .env file so that we can access those variables in our bash script.
  3. We then change to the main git branch, if we’re not already on it.
  4. Next, we check the git status and, if there are changes, rebuild our application. These commands are specific to your application and should be changed. In this example, I’m rebuilding the project’s Docker services and recompiling the project’s JavaScript with yarn/webpack.
  5. The last thing our script does is send a notification to Slack if any of our Docker services are not running.

This script makes several assumptions and is close to a very basic real-world scenario to automatically deploy your Docker services. The bulk of the script depends on your build process and should be changed to fit your needs. Again, this is boilerplate code for demonstration — you will need to replace the code with specific comprehensive steps in order to deploy your app.

Automating Your Script With Cron

Now that we’ve created and added a script to our project containing comprehensive deployment steps, the next thing that we need to do is automate the script to run recursively. We can do that with cron. So, let’s open our cron table file by running:

crontab -e

And at the bottom of this file, add the following line:

* * * * * /your/path/to/project/scripts/cron-deploy

Save and close this file. This cron job runs your deploy script once a minute, checking if changes have been made to the main git branch of your application and then running the deploy steps accordingly.

That’s it, you’re done!

To check the status of your cron job, run the following command:

sudo service cron status

For debugging, you can redirect your script output to a temporary log file for viewing. Just edit the cron job by running crontab -e and adding:

* * * * * /your/path/to/project/scripts/cron-deploy >> /tmp/cron-deploy.log

Conclusion

Thank you for stopping by. I hope this publication, at the very least, teaches you a minimal approach to autonomous deploys with cron and bash scripting. My intent with this publication was to be short and sweet, and to arm you with the basics so that you’re able to determine a deploy process that works for your project. Have a great day!

--

--

Pascal Allen
Pascal Allen

No responses yet