This tutorial shows how to set up file synchronization between two Debian 10 servers with Unison. Unison is a file synchronization tool similar to rsync, the big difference is that it detects / synchronizes changes in both directions, ie files changed on server1 will be replicated to server2 and vice versa.
In this tutorial, I will use the following two Debian servers:
- server1.example.com with the IP address 192.168.0.100
- server2.example. com with the IP address 192.168.0.101
I want to synchronize directory / var / www between the two servers. I will run Unison as root user in this tutorial so that Unison has sufficient permissions to sync user and group permissions.
All commands in this manual are run as root users. Log on to both servers on the shell as root and start with step 2 " Install Unison ".
2 Install Unison
server1 / server2:
Unison must be installed on server1 and server2 ; since we connect from server1 to server2 with SSH, we also need the SSH packages and I install the nano editor for file editing on the shell. This can be achieved as follows:
apt-get -y install unison openssh server ssh nano
3 Create a private / public key pair on server1
Now we create a private / public key key pair at server1.example.com :
ssh-keygen -t dsa
[email protected]: ~ # ssh-keygen -t dsa
Generate public / private dsa key pairs.
Enter file where you want to save the key (/root/.ssh/id_dsa): <- ENTER  Created directory & # 39; /root/.ssh'.
Enter password phrase ( empty without passphrase): <- ENTER
Re-enter the same passphrase: <- ENTER
Your identification has been saved in /root/.ssh/id_dsa.
Your public key has been saved to /root/.ssh/id_dsa.pub.
The Keyprint is:
ba: 82: e1: a1: 42: 9b: d4: c8: 99: c8: bd: 8b: 7d: 4d: d4: 66 [email protected] The random art image of the key is:
+ — [DSA 1024] —- +
| . |
| . E |
| + *. S |
| .Ooo o |
| ooo +. + |
| oo = … o |
| .. oo .. |
+ —————– +
[email protected]: ~ #
It is important that you do not enter a passphrase otherwise the mirroring will not work without human interaction so simply met ENTER !  Then we copy our public key to server2.example.com :
ssh-copy-id-in $ HOME / .ssh / id_dsa.pub [email protected]
# ssh- copy-id -i $ HOME / .ssh / id_dsa.pub [email protected]
Validity host & # 39; 192.168.1.102 (192.168.0.101) & # 39; cannot be determined.
The ECDSA key fingerprint is 2b: 3c: 35: ad: 3d: e2: fc: 16: 2f: 55: 5c: e1: 2c: d7: 3d: a9.
Are you sure you want to continue connecting (yes / no)? <- yes (you only see this if this is your first time connecting to server2)
/ usr / bin / ssh-copy-id: INFO: trying to log in with the new key), to filter out all already installed
/ usr / bin / ssh-copy-id: INFO: 1 key (s) remain to be installed - if you are prompted now, install the new keys  password: <- server2 root password
Number of keys added: 1
Now try to log into the machine, using: "ssh" [email protected] & # 39; "
and make sure that only the keys that you wanted to be added.
Now check server2 if server1 public key has been successfully transferred:
server2:  cat $ HOME / .ssh / authorized_keys : / home / administrator # cat $ HOME / .ssh / authorized_keys
ssh-dss AAAAB3NzaC1kc3MAAACBAKHLdAztIr8muZIlQYuE / 4f75kmgTwWqJRZJ1dTqHDnHWsy48em 85hxAPg43k9aF7 / zAwpA0MNNNk5T9Tx / DyUkK / KcyVP2f4p8tvovrkUvoxsZACkTUmFqKdq2x6 / AGfj sCRmkpLhZuad7r5rKEXHRh8KYGHqD1Id8wcpy5AAAAFQCww3OekKcKMshMAwBK3XQmmYEGUwAAAIEAgjztlwh8OFYxwQve / RrhI2sceCXwS / yjQyH7q0zdWB9Fr4s / 16T2PLBT + 7M3vb + JlPDO3JRqgaYbel1kS2F2iKrY0EX0FI3 / 9fVDfWoz3mhCscPLriqy5AcsHitxQNfiZgA5wDiSjWpk1v + FbIC + VuqbKdQuE4MBKj19N9YALIUAAACABQ4NDsa2UBc8jsxvghjoLhUWF7HChaCksXQcL6i98VNRcemtPC6wpIri75iR4Uhv1666bDOBAdmIBX9Qf7A / + czPKPaj4CGI1hVy1pgYMa3btnEvoSnH / ONtjpOz9q + 3up1OOOn + 5fud7xjJn + Fq8WoGROgarBpCbQU3w2GUUnM =  4 Running Unison  server1:  We can now run Unison for the first time to synchronize directory / var / www on both servers. On server1 run:
unison / var / www ssh: //192.168.0.101//var/www
Output will be similar this – you may have to answer some questions as this is the first time Unison is running:
[email protected]: / var / www # unison / var / www ssh: //192.168.0.101//var/www
Contact server. ..
Connected [//server1//var/www -> //server2//var/www]
Looking for changes
Warning: No archive files were found for these roots, whose canonical name is:
/ var / www
// server2 // var / www
This can happen either
because it is the first time you are synchronizing these roots,
or because you have upgraded Unison to a new version with a different archive format
Update detection may take a while for this run if the copies are
Unison will assume that the & # 39; last synchronized state & # 39; for both copies
was completely empty. This means that all files that are different
will be reported as conflicts, and all files that are only on one copy
will be considered new and distributed to the other replica.
If the two copies are identical, no changes will be reported.
If you see this message repeatedly, it may be because one of your machines
receives its address from DHCP, which causes its host name to be changed
between synchronizations. See the documentation for the UNISONLOCALHOSTNAME
environment variable for advice on how to correct this.
Donations to the Unison project are gratefully accepted:
Press Return to continue. [
] <- Press Enter
Pending server changes
dir ----> example. com [f] <- Press Enter
dir ----> example.de [f] <- Press Enter
Continue to spread updates?  <- Enter "y"
Increase of updates
UNISON 2.48.4 started propagating changes at 13: 24: 01.10 on May 5, 2020
[BGN] Copies example.com from / var / www to // server2 // var / www
[BGN] Copies example.de from / var / www to // server2 // var / www
Shortcut: copied /var/www/example.de/web/ index.html from local file /var/www/.unison.example.com.d3783bddaaf59b9ba4d2ed0433f9db63.unison.tmp/web/index.html Chapter19659055strong Copy Example.de
[END] Copy Example.com
UNISON 2.48.4 stopped propagating changes at 24 o'clock : 01.98 on May 5, 2020
Save sync status
Sync completed at 13:24:01 (2 items transferred, 0 skipped, 0 failed)
Check / var / www directory on server1 and server2 now, and you should find that they are synchronized now.
Of course, we do not want to run Unison interactively, so we can create a preference file e ( /root/.unison/default.prf ) that contains all the settings that we would otherwise need to specify in the command line:  nano /root/.unison/default.prf Chapter19659061] # Roots of the sync
root = / var / www
root = ssh: //192.168.0.101//var/www
# Paths to synchronize
#path = current
#path = common
#path = .netscape / bookmarks.html
# Some regexps that specify names and paths to ignore
#ignore = Path Statistics ## ignores / var / www / stats
#ignore = Path Statistics / * ## ignores / var / www / stats / *
#ignore = Path * / statistics ## ignores / var / www / somedir / stats, but not / var / www / a / b / c / stats
#ignore = Name * statistics ## ignores all files / directories ending with "statistics"
#ignore = Name Statistics * ## ignores all files / directories starting with "statistics"
#ignore = Name * .tmp ## ignores all files with the extension .tmp
# When set to true, this flag causes the user interface to skip
# asks for confirmation of non-conflicting changes. (More
# just when the user interface is ready, set
# propagation direction for an entry and is moving to
# next it will skip all non-conflicting records and go
# directly to the next conflict.)
car = true
# When this is set, the user interface will ask no
# questions at all. Non-contradictory changes will spread;
# conflicts are skipped.
batch = true
#! When this is set, Unison will request an extra
# confirmation if it appears that the entire copy has been
# has been removed before propagating the change. If the batch flag is
# also set, synchronization will be canceled. When the road
# preference is used, same confirmation is requested for
# top tier roads. (Currently, this flag only affects
# text user interface.) See also mountpoint preference.
confirmbigdel = true
# When this setting is set to true, Unison will use
# modification time and length of a file as a & # 39; pseudo-inode
# number & # 39; when scanning replicas for updates, instead of reading
# the entire contents of each file. Under Windows this can cause
# Unison to miss propagating an update on the modification time
# and the length of the file are both unchanged by the update.
# Unison, however, will never overwrite such an update with one
# change from the other copy, because it always makes a safe
# Check for updates just before you propagate a change. Thus it is
# reasonable to use this switch under Windows for the most part
# and sometimes run Unison once with a fixed check set to false,
# if you are worried that Unison may have overlooked an update.
# The default value for the setting is auto, which causes
# Unison to use quick check on Unix replicas (where safe)
# and slow checking of Windows copies. Too backward
# compatibility, yes, no and standard can be used instead
# true, false and auto. See the "Quick Check" section for more
Fast check = true
# When this flag is set to true, group attributes too
# files are in sync. Whether the group names or the group
# identifiers are synchronized depending on the preference numbers.
group = true
# When this flag is set to true, the attributes the owner of
# files are in sync. Whether the owners name or the owner
# identifiers are synchronized depending on the preference
the owner = true
# Including the preference – the lecture means that Unison always does
# resolve conflicts in favor of root, rather than asking for
# guidance from the user. (The root syntax is the same as for
# root preference, plus the special values that are newer and older.)
# This setting is overridden by the preference party.
# This setting should only be used if you are sure you know it
# what are you doing!
prefer = newer
# When this setting is set to true, the textual user interface
# will not print anything at all except for errors.
# If you quietly set to true, you will automatically set the batch setting
silent = true
# When this flag is set to true, file times will change (but not
# directory mottimes) is propagated.
times = true
The comments should make the file self-explanatory, except for the Road Directive . If you do not specify any path directives the directories in the root directives will be synchronized. If you specify path directive, the paths are relative to the root path (e.g. root = / var / www and path = current translates to / var / www / current ), and only these subdirectories will be synchronized, not the entire directory specified in the root directive.
You can read more about the options available by looking at Unison's men page:
Now that we have put all settings in a preference file (especially root (and possibly path ) directive, we can run Unison without any arguments:
5 Create a Cron Job for Unison
We want to automate synchronization, that's why we create a cron job for it at server1.example.com :  crontab -e
* / 5 * * * * / usr / bin / unison &> / dev / null
This would run Unison every five minutes; adapt it to your needs (see
man 5 crontab
). to unison here ( / usr / bin / unison ) just to make sure cron knows where one can find unison . Your location unison may differ. Run Ads
to find out where yours is.
6 Test Unison
Now I will test the 2-way synchronization of Unison to see if the installation is working completely.
Run the following command on server1 to create a test file with the content "Test 1":
Server1  echo "Test 1"> /var/www/test.txtebrit19659031??Now wait at least 5 minutes (because we created a cron job that goes once every five minutes). Then run on server2:
cat /vud19459054??varvar/www/test.txt Chapter19459006 ???? 19659031 ?? to display the contents of the file test.txt on the screen. The output should be similar to this screenshot.
Now run this command on server2 that updates the contents of our test file to "Test 2":  Server2
echo "Test 2"> /var/www/test.txt Tu 19199009006 ???? 19659031 ???? 19459054 ch. And wait at least 5 minutes. Then run the cat command on server1: Ads
cat / was / www / test.txt
The output should be: