Our services
If you can think it, we can make it brainsoft.
If you can think it, we can make it brainsoft.
Written By: BrainSoft In DevOps
If your team still deploys by hand, you already know the drill: SSH into a server, pull the branch, run the build, cross your fingers. It works until it doesn't, and the worst part is you never know which step will break next.
Here is the direct answer to what to automate first: pick the steps that are most repetitive, most error-prone, and still safe to automate. In practice, that means scripting your build and test commands, then wrapping them in a single deploy script that you run locally before you even think about touching the server.
The first thing to automate is not the deployment itself, but the build. If you can't build the same artifact twice, you can't deploy reliably. Write a script that runs your tests, lints, compiles, and packages the output into a single archive or container image. Save that script in your repo so anyone on the team can run it.
#!/bin/bash
set -euo pipefail
npm ci
npm run lint
npm test
npm run build
tar -czf dist.tar.gz dist
This gives you a repeatable process that produces the same artifact every time. You can run it locally, or later on a CI server, but the key is that the steps are codified and not left to memory.
Once you have a reliable artifact, the next step is to automate the transfer and restart. Write a deploy script that takes the artifact, copies it to the server, backs up the current version, and restarts the service. Start with a single server and a simple service; don't try to handle blue-green or canary on day one.
#!/bin/bash
set -euo pipefail
scp dist.tar.gz user@server:/opt/app/
ssh user@server 'cd /opt/app && tar -xzf dist.tar.gz --backup --suffix=.bak && systemctl restart myapp'
This script is still run manually, but it turns a ten-step process into a single command. That reduces the chance of skipping a step or typing the wrong path. Keep the script idempotent: running it twice should not break anything. Use the backup suffix so you can roll back easily.
After the service restarts, you need to know it actually came up. Add a curl command to your deploy script that hits a health endpoint and fails if the response is not 200. This catches the common case where the build succeeded but the app crashes on startup because of a missing environment variable or a bad config.
for i in {1..10}; do
if curl -f http://localhost/health; then
exit 0
fi
sleep 2
done
echo "Health check failed" >&2
exit 1
This turns a silent failure into an immediate, loud signal. You can also add a rollback step that restores the backup if the health check fails, but that can be a later improvement. For now, the goal is to fail fast so you can fix the issue before it reaches users.
The principle is to automate the smallest, safest, highest-frequency task first. That builds confidence and momentum. If you need help designing your automation pipeline, consider our services or get in touch.
Yes. You can start with local scripts that you run before every deploy. That is the first step. Once those scripts are stable, you can move them to a CI server later without changing the logic.
Try to eliminate those steps first. Move configuration into environment variables or a config file that is part of the artifact. If you can't eliminate them, document them clearly and add checks in your script to verify they were done correctly.
Not necessarily at first. Automating rollback is a good second step, but only after you have a reliable deploy and health check. Start with a manual rollback command that restores the backup, then automate it when you trust the process.