This is more a short story of getting nerdy with a NAS. I wanted to figure out if I could really host a GIT repo locally on my NAS for private work or long term storage. While I’ll be covering the usage in an upcoming WhizLabs course, I thought others might want to see how to accomplish the same.
Setting up GIT on Synology
First, let's talk hardware. I'm using just a basic 4yo Synology DS216play NAS for this. My router is an Asus AC1900 (RT-AC68U) and i wont talk much about my cable modem, but it's a business class and serves gig-e.
The GIT as provided in Synology Plugins is GIT SSH only - be aware of this as it creates a few hoops through which we we have to jump
In your package center, Install "Git Server"
There is a known bug, so if you click open right away, you won’t see any users. Luckily this article clued me into the fix. Clear out the existing value in “appPriv”.. So appPriv should change to look like:
ijohnson@SassyNassy:~$ cat /var/packages/Git/target/webapi/SYNO.Git.lib
{"SYNO.Git.lib": {"allowUser": ["admin.local", "admin.domain", "admin.ldap"], "appPriv": "", "authLevel": 1, "lib": "/var/packages/Git/target/webapi/SYNO.Git.so", "maxVersion": 1, "methods": {"1": [{"enum_user": {"grantable": true}}, {"apply": {"grantable": true}}]}, "minVersion": 1, "priority": 0}}
Once changed, you can enable/disable git access for users:
Next, since GIT only runs on 22 and I’m not about to open an outside 22 port, create a forwarding rule in your router to reach the NAS.
I have an ASUS so it’s as easy as creating a new Virtual Server:
(IF you are using an Asus as I am, don't forget to hit "+" to save and then an apply button lest it doesn't actually take the new forwarding rule)
Next we need to login to the NAS and create a repo.
root@SassyNassy:/volume1/git_repos# git init --bare NewTest2
Initialized empty Git repository in /volume1/git_repos/NewTest2/
root@SassyNassy:/volume1/git_repos# cd NewTest2
root@SassyNassy:/volume1/git_repos/NewTest2# ls
branches config description HEAD hooks info objects refs
Next chown so our accounts can write to it:
root@SassyNassy:/volume1/git_repos# sudo chown -R admin:users NewTest2
root@SassyNassy:/volume1/git_repos# sudo chmod -R g+rwx NewTest2
Last, to try and be observant of inclusive naming, I tend to change master to main:
root@SassyNassy:/volume1/git_repos# cat NewTest2/HEAD
ref: refs/heads/master
root@SassyNassy:/volume1/git_repos# vi NewTest2/HEAD
root@SassyNassy:/volume1/git_repos# cat NewTest2/HEAD
ref: refs/heads/main
Verification
Now that we have a local repo, let’s test it:
builder@DESKTOP-JBA79RT:~/Workspaces$ git clone ssh://ijohnson@sassynassy/volume1/git_repos/NewTest2 NewTest22
Cloning into 'NewTest22'...
ijohnson@sassynassy's password:
remote: Enumerating objects: 6, done.
remote: Counting objects: 100% (6/6), done.
remote: Compressing objects: 100% (2/2), done.
remote: Total 6 (delta 0), reused 0 (delta 0), pack-reused 0
Receiving objects: 100% (6/6), done.
builder@DESKTOP-JBA79RT:~/Workspaces$ cd NewTest22
builder@DESKTOP-JBA79RT:~/Workspaces/NewTest22$ ls
README.md
builder@DESKTOP-JBA79RT:~/Workspaces/NewTest22$ vi README.md
builder@DESKTOP-JBA79RT:~/Workspaces/NewTest22$ git add README.md
builder@DESKTOP-JBA79RT:~/Workspaces/NewTest22$ git commit -m "make a change"
[main 84f86bb] make a change
1 file changed, 1 insertion(+), 1 deletion(-)
builder@DESKTOP-JBA79RT:~/Workspaces/NewTest22$ git push
ijohnson@sassynassy's password:
Counting objects: 3, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 304 bytes | 304.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0)
To ssh://sassynassy/volume1/git_repos/NewTest2
23815bd..84f86bb main -> main
Next I created a repo in Github that would consume from this one.
I made it private then used Azure Pipelines to onboard (and create the requisite AzDO to Github permissions)
The azure-pipelines file looks like:
$ cat azure-pipelines.yml
# Starter pipeline
# Start with a minimal pipeline that you can customize to build and deploy your code.
# Add steps that build, run tests, deploy, and more:
# https://aka.ms/yaml
trigger:
- main
pr:
autoCancel: true
branches:
include:
- feature/*
- main
- develop
variables:
- group: azdodev
pool:
vmImage: 'ubuntu-latest'
steps:
- script: echo Hello, world!
displayName: 'Run a one-line script'
- bash: |
#!/bin/bash
set -x
sudo apt-get update
sudo apt-get install -y sshpass
export GIT_SSH_COMMAND="ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no"
sshpass -p $(gitpw) git clone ssh://ijohnson@73.242.50.46:25580/volume1/git_repos/NewTest
ls -ltra ./NewTest
- script: |
echo Add other tasks to build, test, and deploy your project.
echo See https://aka.ms/yaml
displayName: 'Run a multi-line script'
I can either use the variable group under library to store the“gitpw”
Or you can use variables under settings:
This matches my login user.
In our code above we see how we can clone. First we need to disable TLS since our git server doesn't have a proper cert and GIT will vomit on it. We can use this env var (if Git is > 2.3)
export GIT_SSH_COMMAND="ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no"
Next, because we used a custom port, we need to use sshpass to pass in our password. Had we used the default 22, we wouldn't need to do this (we could instead use ssh://user:pass@host). The forwarding port (25580) is part of the URL below.
sshpass -p $(gitpw) git clone ssh://ijohnson@73.242.50.46:25580/volume1/git_repos/NewTest
Running the pipeline
Now that we have the change, we can create a PR in Github which should trigger the onboarded pipeline:
Which then runs the Azure Pipelines job
Pushing content back
We can push content such as a new SHA or tag back in much the same way. Just add steps such as:
cd NewTest2
git add BuildFile
git config --global user.email "isaac.johnson@gmail.com"
git config --global user.name "Isaac Johnson"
git commit -m "BuildFile changed"
sshpass -p $(gitpw) git push
And you’ll be able to transmit content back to the GIT on the NAS:
And we call pull locally to bring the commit down:
builder@DESKTOP-JBA79RT:~/Workspaces/NewTest6$ git pull
ijohnson@sassynassy's password:
remote: Enumerating objects: 14, done.
remote: Counting objects: 100% (14/14), done.
remote: Compressing objects: 100% (9/9), done.
remote: Total 12 (delta 1), reused 0 (delta 0), pack-reused 0
Unpacking objects: 100% (12/12), done.
From ssh://sassynassy/volume1/git_repos/NewTest2
6d597d6..9b6388c main -> origin/main
Updating 6d597d6..9b6388c
Fast-forward
BuildFile | 6 ++++++
README.md | 1 +
2 files changed, 7 insertions(+)
create mode 100644 BuildFile
Summary
We used a standard Synology NAS to host a GIT server and Azure DevOps to pull and push content as fronted via a GITHub based YAML pipeline. This technique can be used to reference controlled content in a network - such as using a private agent pool that refers to a local git server (via local IP) instead of exposing publicly.
This can also be used to sync to local on-prem systems content built in the cloud for CICD systems that use GIT but have no external network access.