Once in a while, I want to try some idea to implement. Having background by developing mostly in .NET
stack my choice is obviously .NET Core
. I always have at hand couple of Linux
servers: one is in DigitalOcean
, another one is MSI Cubi N under my TV set. Hence, my Linux
horses will run .NET Core
app.
My yet another brilliant idea is waiting for implementation. Wait a minute! It will not happen without a continuous integration server which is triggered by GitHub in order to prepare a release package. And, don’t forget about a continuous delivery server, how can we deploy without it? Probably, it is even better to set up Kubernetes cluster. Right? No way! That’s not for me. I would like to have something as simple as possible. KISS principle after all!
How minimal deployment script will look like? I’m going to deploy to my MSI Cubi N
that has 192.168.2.4
. After a couple of evenings googling and debugging the script is ready. It uses rsync in order to upload only changed files, systemd for running the console app as service and restarting in case of failure.
#!/bin/bash
ssh [email protected] 'bash -s' <<'ENDSSH'
printf "Stopping service...\n"
systemctl stop HelloSshDeploy
printf "Service is "
systemctl is-active HelloSshDeploy
mkdir -p /apps/HelloSshDeploy
ENDSSH
printf "Uploading new version of service...\n"
rsync -v -a ./bin/Release/netcoreapp2.2/ubuntu.16.04-x64/publish/ [email protected]:/apps/HelloSshDeploy/
ssh [email protected] 'bash -s' <<'ENDSSH'
chmod 777 /apps/HelloSshDeploy/Gaev.Blog.Examples.HelloSshDeploy
if [[ ! -e /etc/systemd/system/HelloSshDeploy.service ]]; then
printf "Installing service...\n"
cat > /etc/systemd/system/HelloSshDeploy.service <<'EOF'
[Unit]
Description=HelloSshDeploy
After=network.target
[Service]
WorkingDirectory=/apps/HelloSshDeploy
ExecStart=/apps/HelloSshDeploy/Gaev.Blog.Examples.HelloSshDeploy
Restart=always
KillSignal=SIGINT
[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload
systemctl enable HelloSshDeploy
fi
printf "Starting service...\n"
systemctl start HelloSshDeploy
printf "Service is "
systemctl is-active HelloSshDeploy
ENDSSH
My .NET Core
console app is super small. I’m using Console.CancelKeyPress
here to respect Ctrl + C
and SIGINT
signal which is sent by Linux
to stop the console app.
class Program
{
static async Task Main(string[] args)
{
var cancellation = new CancellationTokenSource();
Console.CancelKeyPress += (_, e) => { e.Cancel = true; cancellation.Cancel(); };
using (var logger = new LoggerConfiguration()
.WriteTo.Console()
.WriteTo.File("HelloSshDeploy.log")
.CreateLogger())
await RunApplication(logger, cancellation.Token);
}
static async Task RunApplication(Logger logger, CancellationToken cancellation)
{
logger.Information("Hello World!");
try
{
await Task.Delay(Timeout.Infinite, cancellation);
}
catch (TaskCanceledException) { }
logger.Information("Goodbye World!");
}
}
Prerequisites for deployment over SSH
Linux
machine itself: for instance, you can start from $5/mo machine by DigitalOcean;- ssh & rsync on your machine must be installed. For
Windows
users, the easiest way is to installUbuntu
forWindows 10
via Windows Subsystem for Linux; - password-less
SSH
login must be configured in targetLinux
machine. ssh-copy-id to the rescue; - root login over SSH must be enabled in target
Linux
machine.
Finally, it takes 4 seconds in order to deploy. See the execution result of the following commands:
./make.sh
./deploy.sh
See source code here Gaev.Blog.Examples.HelloSshDeploy.