=for header
manpage:  DUPLY
section:  1
title:    duply documentation
version:  Version 2.5.5
datum:    2025-03-16

=encoding utf8

=head1 NAME

duply - a shell frontend to duplicity for simplified backups


=head1 SYNOPSIS

B<duply> I<profile> B<create>

B<duply> I<profile command [options ...]>

B<duply> I<profile command[_command_...] [options ...]>


=head1 DESCRIPTION

B<Duply> deals as a wrapper for the mighty duplicity magic.
It simplifies running duplicity with cron or on command line by:

  - keeping recurring settings in profiles per backup job 
  - enabling batch operations eg. backup_verify+purge
  - executing pre/post scripts (different actions possible 
    depending on previous or next command or it's exit status)
  - precondition checking for flawless duplicity operation 

For each backup job one configuration profile must be created.
The profile folder will be stored under F<~/.duply/«profile»>
(where '~' is the current users home directory).

I<Hint>: If the folder F</etc/duply> exists, the profiles for the
superuser root will be searched and created there.


=head1 USAGE

First time usage (profile creation):

    duply <profile> create

General usage in single mode (see EXAMPLES):

    duply <profile> <command> [<options> ...]

General usage in batch mode joining commands with '_' (see EXAMPLES):

    duply <profile> <command>[[_|+|-]<command>[_|+|-]...] [<options> ...]

For batches the conditional separators can also be written as pseudo commands
and(+), or(-). See SEPARATORS for details.

Non B<duply> options are passed on to duplicity (see OPTIONS).
All config parameters can also be defined in the environment instead.


=head1 SEPARATORS

=over 4

=item B<_ (underscore)>

neutral separator

=item B<+ (plus sign), _and_>

conditional AND; 
the next command will only be executed if the previous succeeded

=item B<- (minus sign), _or_>

conditional OR; 
the next command will only be executed if the previous failed

=item B<[] (square brackets), _groupIn_/_groupOut_>

enables grouping of commands

=back

Example: 'pre+[bkp-verify]_post' translates to 'pre_and_groupIn_bkp_or_verify_groupOut_post'


=head1 PROFILE

=head2 location for profiles

Indicated by a path or a profile name i.e. I<myprofile>, which is resolved
to F<~/.duply/myprofile> ('~' expands to environment variable $HOME).
  
Superuser root can place profiles under F</etc/duply>. Simply create the
folder manually before running duply as superuser.

ATTENTION: Already existing profiles in home folder of root will cease to
work unless they are moved to the new location manually.

=head2 using profiles

Usually only the profile name (here: 'humbug') will be used:

    duply humbug backup

Alternatively a I<path> might be used. This might be useful for quick testing,
restoring or exotic locations. Shell expansion should work as usual:

    duply ~/.duplytest/humbug backup

ATTENTION: The path must contain at least one path separator '/', e.g. F<./test>
instead of only F<test>.


=head1 COMMANDS

=over 8

=item B<usage>

Get usage help text.

=item B<and/or/groupIn/groupOut  >

Pseudo commands for better batch cmd readability (see SEPARATORS).

=item B<create>

Creates a configuration profile.

=item B<backup>

Backup with pre/post script execution (as batch the same as: pre_bkp_post)

=over 2

=item * as I<full> backup if parameter full_if_older matches or no earlier backup is found.

=item * as I<incremental> backup in all other cases.

=back

=item B<bkp>

As above but without executing pre/post scripts.

=item B<full>

Force full backup.

=item B<incr>

Force incremental backup.

=item B<pre>

Execute only script '<profile>/pre' (for debugging purposes).

=item B<post>

Execute only script '<profile>/post' (for debugging purposes).

=item B<list> I<[«age»]>

List all files in backup (as it was at I<age>, default: now).

=item B<status>

Print backup sets and chains currently in repository.

=item B<verify> I<[«age»]> I<[--compare-data]>

List files changed, since I<age> if given.

=item B<verifyPath> I<[«rel_path_in_bkp»]> I<[«local_path»]> I<[«age»]> I<[--compare-data]>

List changes of a file or folder path in backup compared to a
local path, since I<age> if given.

=item B<restore> I<«target_path»> I<[«age»]>

Restore the complete backup to I<target_path> (as it was at I<age>).

=item B<fetch> I<src_path target_path> I<[«age»]>

Fetch single file/folder from backup (as it was at I<age>).

=item B<purge> I<[«max_age»]> I<[--force]>

List outdated backup archives (older than I<max_age>).
Use option I<--force> to actually delete these files.

=item B<purgeFull> I<[«max_full_backups»]> I<[--force]>

List outdated backup files. I<max_full_backups> being the
number of full backups and associated incrementals to keep,
counting in reverse chronological order. Use option I<--force>
to actually delete these files.

=item B<purgeIncr> I<[«max_fulls_with_incrs»]> I<[--force]>

List outdated incremental backup files. I<max_fulls_with_incrs> being
the number of full backups which associated incrementals  will be kept,
counting in reverse chronological order. Use option I<--force>
to actually delete these files.

=item B<purgeAuto> I<[--force]>

Convenience batch wrapper for all purge commands above.
purge, purgeFull, purgeIncr are added if their conf vars were set. E.g.

  MAX_AGE=1Y
  MAX_FULL_BACKUPS=6
  MAX_FULLS_WITH_INCR=3

in profile config file would result in [purge_purgeFull_purgeIncr].

=item B<cleanup> I<[--force]>

List broken backup chain files archives (e.g. after unfinished run).
Use option I<--force> to actually delete these files.

=item B<changelog>

Print the last changes of duply.

=item B<version>

Show version information of B<duply> and needed programs.

=back


=head1 OPTIONS

=over 4

=item B<--force>

Passed to duplicity (see commands: purge, purge-full, purge-incr, cleanup).

=item B<--preview>

Do nothing but print out generated duplicity command lines.

=item B<--disable-encryption>

Disable encryption, override profile settings.

=back


=head1 TIME FORMATS

For all time related parameters like age, max_age etc. Refer to the duplicity
manpage for all available formats. Here some examples:

  · 2002-01-25T07:00:00+02:00 (full date time format string)
  · 2002/3/5 (date string YYYY/MM/DD)
  · 12D (interval, 12 days ago)
  · 1h78m (interval, 1 hour 78 minutes ago)


=head1 PRE/POST SCRIPTS

Some useful internal duply variables are exported to the scripts:

   PROFILE, CONFDIR, SOURCE, TARGET_URL_<PROT|HOSTPATH|USER|PASS>,
   GPG_<KEYS_ENC|KEY_SIGN|PW>, CMD_ERR, RUN_START,
   CMD_<PREV|NEXT> (previous/next command),
   CND_<PREV|NEXT> (condition before/after)

The CMD_* variables were introduced to allow different actions according to
the command the scripts were attached to e.g. 'pre_bkp_post_pre_verify_post'
will call the pre script two times, with CMD_NEXT variable set to 'bkp'
on the first and to 'verify' on the second run.
CMD_ERR holds the exit code of the CMD_PREV.


=head1 EXAMPLES

Create profile 'humbug':

    duply humbug create

and then edit the resulting F<conf> file of this profile.

Backup 'humbug' now:

    duply humbug backup

List available backup sets of profile 'humbug':

    duply humbug status

List and delete outdated backups of 'humbug':

    duply humbug purge --force

Restore latest backup of 'humbug' to /mnt/restore:

    duply humbug restore /mnt/restore

Restore /etc/passwd of 'humbug' from 4 days ago to /root/pw:

    duply humbug fetch etc/passwd /root/pw 4D

See I<man duplicity>, section TIME FORMATS for the time format.

A one line I<batch job> on 'humbug' for cron execution:

    duply humbug backup_verify_purge --force

Batch job to run a full backup with pre/post scripts:

    duply humbug pre_full_post


=head1 FILES

Files in profile folder '~/.duply/<profile>' or '/etc/duply':

  conf .......... profile configuration file
  pre ........... pre script (see above for details)
  post .......... post script (see above for details)
  gpgkey.*.asc .. exported GnuPG key files
  exclude ....... a globbing list of included or excluded files/folders

The rules for the F<exclude> file can be found in I<man duplicity>, 
section FILE SELECTION).


=head1 IMPORTANT

Copy the I<whole> profile folder after the first backup to a safe place.
It contains everything needed to restore your backups. You will need 
it if you have to restore the backup from another system (e.g. after a 
system crash).

Pay attention to (possibly later added) external files such as credentials
or auth files (e.g. netrc, .megarc, ssh keys) or environment variables
(e.g. DPBX_ACCESS_TOKEN). 

It is good policy to place those in the profile folder if possible at all.
e.g. in case of 'multi://' target the config .json file
Env vars should be added to duply profiles' conf file.

Keep access to these files restricted as they contain I<all> information
(gpg data, ftp data) to access and modify your backups.

Finally: You should attempt a restore from an unrelated host to be sure you
really have everything needed for restoration.

Repeat these step after I<all> configuration changes. Some configuration 
options are crucial for restoration.


=head1 BUGS

This program is still in development. If you find bugs write a bug report
on: http://duply.net/.


=head1 AVAILABILITY

For newer versions see http://sourceforge.net/projects/ftplicity/.


=head1 COPYRIGHT and LICENSE

Copyright (C) 2006 Christiane Ruetten, 2008-2017 Edgar Soldin

This package is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by 
the Free Software Foundation; either version 2 of the License, or 
(at your option) any later version.

On Debian systems, the complete text of the GNU General Public License
version 2 can be found in the file `/usr/share/common-licenses/GPL-2'.


=head1 AUTHOR

Duply was written by Christiane Ruetten (initial version, named ftplicity)
and Edgar Soldin.

This manual page was written by Joachim Wiedorn <joodebian at joonet.de>
for the Debian project (and may be used by others).


=head1 SEE ALSO

duplicity(1)

=cut
