<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="ru">
	<id>https://wiki.webko.net.ua/index.php?action=history&amp;feed=atom&amp;title=%D0%91%D1%8D%D0%BA%D0%B0%D0%BF_7z%2BDropbox</id>
	<title>Бэкап 7z+Dropbox - История изменений</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.webko.net.ua/index.php?action=history&amp;feed=atom&amp;title=%D0%91%D1%8D%D0%BA%D0%B0%D0%BF_7z%2BDropbox"/>
	<link rel="alternate" type="text/html" href="https://wiki.webko.net.ua/index.php?title=%D0%91%D1%8D%D0%BA%D0%B0%D0%BF_7z%2BDropbox&amp;action=history"/>
	<updated>2026-05-21T20:03:24Z</updated>
	<subtitle>История изменений этой страницы в вики</subtitle>
	<generator>MediaWiki 1.35.1</generator>
	<entry>
		<id>https://wiki.webko.net.ua/index.php?title=%D0%91%D1%8D%D0%BA%D0%B0%D0%BF_7z%2BDropbox&amp;diff=147&amp;oldid=prev</id>
		<title>Sol: Новая страница: «В последнее время особую популярность обретают различные «облачные» сервисы, в том числ…»</title>
		<link rel="alternate" type="text/html" href="https://wiki.webko.net.ua/index.php?title=%D0%91%D1%8D%D0%BA%D0%B0%D0%BF_7z%2BDropbox&amp;diff=147&amp;oldid=prev"/>
		<updated>2015-04-21T20:00:50Z</updated>

		<summary type="html">&lt;p&gt;Новая страница: «В последнее время особую популярность обретают различные «облачные» сервисы, в том числ…»&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Новая страница&lt;/b&gt;&lt;/p&gt;&lt;div&gt;В последнее время особую популярность обретают различные «облачные» сервисы, в том числе резервное копирование. В интернете можно найти десяток сайтов представляющих подобные услуги, в том числе на платной основе.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим настройку автоматического бекапа веб-сервера с помощью архиватора 7z и сервиса Dropbox в Debian/Ubuntu Linux.&lt;br /&gt;
&lt;br /&gt;
== Способ 1 (не инкрементный бэкап) ==&lt;br /&gt;
&lt;br /&gt;
Создадим непривилегированного пользователя из-под которого будет запущен клиент Dropbox.&lt;br /&gt;
 root@localhost:~$ useradd backupus&lt;br /&gt;
Далее в соответсвии с [https://www.dropbox.com/install?os=lnx официальной вики] устанавливаем консольного клиента, для созданного ранее пользователя&lt;br /&gt;
 backupus@localhost:~$ cd ~/&lt;br /&gt;
 backupus@localhost:~$ wget -O dropbox.tar.gz http://www.dropbox.com/download/?plat=lnx.x86&lt;br /&gt;
 backupus@localhost:~$ tar -zxof dropbox.tar.gz&lt;br /&gt;
Запускаем клиента&lt;br /&gt;
 backupus@localhost:~$ ~/.dropbox-dist/dropboxd&lt;br /&gt;
Через несколько секунд в консоле появится ссылка для привязки данного компьютера к вашему аккаунту.&lt;br /&gt;
&lt;br /&gt;
Изменяем каталог за которым следит демон Dropbox на «/backup»:&lt;br /&gt;
 backupus@localhost:~$ cp ~/.dropbox/dropbox.db dropbox.db.backup&lt;br /&gt;
 backupus@localhost:~$ wget http://dl.dropbox.com/u/119154/permalink/dropboxdir.py&lt;br /&gt;
 backupus@localhost:~$ chmod +x dropboxdir.py&lt;br /&gt;
 backupus@localhost:~$ mv ~/Dropbox /backup&lt;br /&gt;
 backupus@localhost:~$ ./dropboxdir.py --setfolder=/backup&lt;br /&gt;
Добавим скрипт автозапуска /etc/init.d/dropbox&lt;br /&gt;
 # dropbox service&lt;br /&gt;
 DROPBOX_USERS=&amp;quot;backupus&amp;quot;&lt;br /&gt;
 DAEMON=.dropbox-dist/dropbox&lt;br /&gt;
 start() {&lt;br /&gt;
    echo &amp;quot;Starting dropbox...&amp;quot;&lt;br /&gt;
    for dbuser in $DROPBOX_USERS; do&lt;br /&gt;
        HOMEDIR=`getent passwd $dbuser | cut -d: -f6`&lt;br /&gt;
        if [ -x $HOMEDIR/$DAEMON ]; then&lt;br /&gt;
            HOME=&amp;quot;$HOMEDIR&amp;quot; start-stop-daemon -b -o -c $dbuser -S -u $dbuser -x $HOMEDIR/$DAEMON&lt;br /&gt;
        fi&lt;br /&gt;
    done&lt;br /&gt;
 }&lt;br /&gt;
  stop() {&lt;br /&gt;
    echo &amp;quot;Stopping dropbox...&amp;quot;&lt;br /&gt;
    for dbuser in $DROPBOX_USERS; do&lt;br /&gt;
        HOMEDIR=`getent passwd $dbuser | cut -d: -f6`&lt;br /&gt;
        if [ -x $HOMEDIR/$DAEMON ]; then&lt;br /&gt;
            start-stop-daemon -o -c $dbuser -K -u $dbuser -x $HOMEDIR/$DAEMON&lt;br /&gt;
        fi&lt;br /&gt;
    done&lt;br /&gt;
 }&lt;br /&gt;
 status() {&lt;br /&gt;
    for dbuser in $DROPBOX_USERS; do&lt;br /&gt;
        dbpid=`pgrep -u $dbuser dropbox`&lt;br /&gt;
        if [ -z $dbpid ] ; then&lt;br /&gt;
            echo &amp;quot;dropboxd for USER $dbuser: not running.&amp;quot;&lt;br /&gt;
        else&lt;br /&gt;
            echo &amp;quot;dropboxd for USER $dbuser: running (pid $dbpid)&amp;quot;&lt;br /&gt;
        fi&lt;br /&gt;
    done&lt;br /&gt;
 }&lt;br /&gt;
 case &amp;quot;$1&amp;quot; in&lt;br /&gt;
  start)&lt;br /&gt;
    start&lt;br /&gt;
    ;;&lt;br /&gt;
 &lt;br /&gt;
  stop)&lt;br /&gt;
    stop&lt;br /&gt;
    ;;&lt;br /&gt;
 &lt;br /&gt;
  restart|reload|force-reload)&lt;br /&gt;
    stop&lt;br /&gt;
    start&lt;br /&gt;
    ;;&lt;br /&gt;
 &lt;br /&gt;
  status)&lt;br /&gt;
    status&lt;br /&gt;
    ;;&lt;br /&gt;
 &lt;br /&gt;
  *)&lt;br /&gt;
    echo &amp;quot;Usage: /etc/init.d/dropbox {start|stop|reload|force-reload|restart|status}&amp;quot;&lt;br /&gt;
    exit 1&lt;br /&gt;
  esac&lt;br /&gt;
 exit 0&lt;br /&gt;
Делаем исполняемым, разрешаем запуск при загрузке и запускаем:&lt;br /&gt;
 root@localhost:~$ chmod +x /etc/init.d/dropbox&lt;br /&gt;
 root@localhost:~$ update-rc.d dropbox defaults&lt;br /&gt;
 root@localhost:~$ /etc/init.d/dropbox start&lt;br /&gt;
Синхронизация файлов с онлайн-хранилищем работает, перейдем непосредственно к бекапу:&lt;br /&gt;
 #!/bin/sh&lt;br /&gt;
 DATE=`/bin/date +%Y%m%d`&lt;br /&gt;
 BACKUP_DIR=&amp;quot;/backup/${DATE}&amp;quot;&lt;br /&gt;
 SZ_CMD=&amp;quot;/usr/bin/7za&amp;quot;&lt;br /&gt;
 SZ_PSW=&amp;quot;secret&amp;quot;&lt;br /&gt;
 SZ_OPT=&amp;quot;a -t7z -m0=lzma -mx=9 -mfb=64 -md=32m -ms=on -p${SZ_PSW}&amp;quot;&lt;br /&gt;
 SITES=&amp;quot;example.org site.com blog.me&amp;quot;&lt;br /&gt;
 MYSQL_USR=&amp;quot;backup&amp;quot;&lt;br /&gt;
 MYSQL_PSW=&amp;quot;secret&amp;quot;&lt;br /&gt;
 MYSQL_DBS=&amp;quot;mysql example_org site_com blog_me&amp;quot;&lt;br /&gt;
 # Create Dirs&lt;br /&gt;
 /bin/mkdir ${BACKUP_DIR}&lt;br /&gt;
 /bin/mkdir ${BACKUP_DIR}/db&lt;br /&gt;
 /bin/mkdir ${BACKUP_DIR}/www&lt;br /&gt;
 # Installed packages&lt;br /&gt;
 /usr/bin/dpkg --list | $SZ_CMD $SZ_OPT -si ${BACKUP_DIR}/dpkg.list.7z&lt;br /&gt;
 # Configs&lt;br /&gt;
 $SZ_CMD $SZ_OPT ${BACKUP_DIR}/etc.7z /etc/&lt;br /&gt;
 # Crontabs&lt;br /&gt;
 $SZ_CMD $SZ_OPT ${BACKUP_DIR}/crontabs.7z /var/spool/cron/crontabs/&lt;br /&gt;
 # Sites&lt;br /&gt;
 for SITE in $SITES; do&lt;br /&gt;
 $SZ_CMD $SZ_OPT ${BACKUP_DIR}/www/${SITE}.7z /srv/www/${SITE}/&lt;br /&gt;
 done&lt;br /&gt;
 # MySQL&lt;br /&gt;
 for DB in $MYSQL_DBS; do&lt;br /&gt;
  /usr/bin/mysqldump --opt -u $MYSQL_USR -p${MYSQL_PSW} $DB | $SZ_CMD \&lt;br /&gt;
  $SZ_OPT -si ${BACKUP_DIR}/db/${DB}.sql.7z&lt;br /&gt;
 done&lt;br /&gt;
Итак, что делает это скрипт:&lt;br /&gt;
&lt;br /&gt;
Слепок установленных пакетов&lt;br /&gt;
Резервную копию конфигов и кронтабов&lt;br /&gt;
&lt;br /&gt;
Резервную копию сайтов example.org, site.com и blog.me&lt;br /&gt;
&lt;br /&gt;
Резервную копию mysql баз mysql, example_org, site_com и blog_me&lt;br /&gt;
&lt;br /&gt;
Архивы в данном скрипте шифруются с помощью пароля $SZ_PSW, так как доверять никому не стоит&lt;br /&gt;
&lt;br /&gt;
== Способ 2 (инкрементный бэкап) ==&lt;br /&gt;
&lt;br /&gt;
'''Шаг 1 — создание приложения'''&lt;br /&gt;
&lt;br /&gt;
Заходим на страницу App Console, нажимаем кнопку «Create app», выбираем тип «Dropbox API app», выбираем пункт «Files and datastores», так как мы собираемся работать с файлами, а в следующем пункте отвечаем «Yes — My app only needs access to files it creates», это означает, что ваше приложение будет ограничено только своей отдельной подпапкой в папке App, к другим файлам у него не будет доступа. Придумываем название своему приложению и нажимаем «Create app».&lt;br /&gt;
Перед вами предстанет целая страница настроек созданного приложения, но там не требуется ничего дополнительно настраивать. Но пока не закрывайте её.&lt;br /&gt;
&lt;br /&gt;
'''Шаг 2 — скачивание и установка SDK'''&lt;br /&gt;
&lt;br /&gt;
Чтобы писать приложения, которые будут работать с файлами в вашем Dropbox'е, надо зайти в раздел Core API. Там мы можем скачать нужные нам SDK, почитать документацию и пройти обучающие туры.&lt;br /&gt;
Так как я считаю, что лучшим языком для скриптования для меня является Python, то я скачал себе его SDK и установил. Установка очень простая, всё ограничивается скачиванием, разархивированием самого SDK и установкой его с помощью команд &amp;quot;python setup.py install&amp;quot;, или &amp;quot;pip install dropbox&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
'''Шаг 3 — авторизация'''&lt;br /&gt;
&lt;br /&gt;
Библиотека Core API использует OAuth v2, но Python SDK от Dropbox'а сам позаботится о том, как им пользоваться, так что вам не о чем волноваться и не придется писать всё с нуля.&lt;br /&gt;
Настало время накодить небольшой скрипт:&lt;br /&gt;
 # Включить Dropbox SDK&lt;br /&gt;
 import dropbox&lt;br /&gt;
 # Вставить настоящие app_key и app_secret со страницы созданного приложения из шага 1&lt;br /&gt;
 app_key = 'INSERT_APP_KEY'&lt;br /&gt;
 app_secret = 'INSERT_APP_SECRET'&lt;br /&gt;
 flow = dropbox.client.DropboxOAuth2FlowNoRedirect(app_key, app_secret)&lt;br /&gt;
 # На данном этапе юзер авторизуется&lt;br /&gt;
 authorize_url = flow.start()&lt;br /&gt;
 print '1. Перейдите по ссылке: ' + authorize_url&lt;br /&gt;
 print '2. Нажмите &amp;quot;Allow&amp;quot;'&lt;br /&gt;
 print '3. Скопируйте авторизационный код.'&lt;br /&gt;
 code = raw_input(&amp;quot;Вставьте авторизационный код сюда: &amp;quot;).strip()&lt;br /&gt;
 # Если вы ввели правильный код, то дальше он отсылается на сервер и получается access_token, который нам нужен&lt;br /&gt;
 access_token, user_id = flow.finish(code)&lt;br /&gt;
 # Для проверки авторизации выведем информацию об аккаунте&lt;br /&gt;
 client = dropbox.client.DropboxClient(access_token)&lt;br /&gt;
 print 'linked account: ', client.account_info()&lt;br /&gt;
 # А сам access_token вам надо сохранить в файл для дальнейшей работы скрипта&lt;br /&gt;
 print 'access_token: ', access_token&lt;br /&gt;
&lt;br /&gt;
'''Шаг 4 — создаём временную папку и файл токена'''&lt;br /&gt;
&lt;br /&gt;
Сам скрипт backup.py у меня лежит в папке /root, в ней же есть временная папка backup и файл dropbox_token.txt. Вам тоже нужно создать их и в файл записать токен с предыдущего шага. Токен состоит из двух строк, в файле они именно так и лежат, с переносом строки.&lt;br /&gt;
&lt;br /&gt;
'''Шаг последний — пишем скрипт бэкапа'''&lt;br /&gt;
&lt;br /&gt;
 #!/usr/bin/python&lt;br /&gt;
 import os&lt;br /&gt;
 import sys&lt;br /&gt;
 import time&lt;br /&gt;
 import string&lt;br /&gt;
 from os.path import getsize&lt;br /&gt;
 curDate = time.strftime(&amp;quot;%d.%m.%Y&amp;quot;, time.gmtime())&lt;br /&gt;
 curDay = time.strftime(&amp;quot;%d&amp;quot;, time.gmtime())&lt;br /&gt;
 backupDelay = time.time()-86400&lt;br /&gt;
 if curDay == &amp;quot;01&amp;quot; or curDay == &amp;quot;15&amp;quot;:&lt;br /&gt;
   backupDelay = 0&lt;br /&gt;
 print &amp;quot;curDate:&amp;quot;, curDate&lt;br /&gt;
 # Include the Dropbox SDK libraries&lt;br /&gt;
 from dropbox import client, rest, session&lt;br /&gt;
 # Get your app key and secret from the Dropbox developer website&lt;br /&gt;
 APP_KEY = 'ключ приложения'&lt;br /&gt;
 APP_SECRET = 'секретный код приложения'&lt;br /&gt;
 # ACCESS_TYPE should be 'dropbox' or 'app_folder' as configured for your app&lt;br /&gt;
 ACCESS_TYPE = 'app_folder'&lt;br /&gt;
 sess = session.DropboxSession(APP_KEY, APP_SECRET, ACCESS_TYPE)&lt;br /&gt;
 oauth_token = ''&lt;br /&gt;
 oauth_token_secret = ''&lt;br /&gt;
 f = open(&amp;quot;dropbox_token.txt&amp;quot;,'r')&lt;br /&gt;
 if f:&lt;br /&gt;
   oauth_token = string.strip(f.readline())&lt;br /&gt;
   oauth_token_secret = string.strip(f.readline())&lt;br /&gt;
   f.close()&lt;br /&gt;
 print &amp;quot;oauth token found:&amp;quot;, oauth_token, oauth_token_secret&lt;br /&gt;
 if oauth_token == '' or oauth_token_secret == '':&lt;br /&gt;
   request_token = sess.obtain_request_token()&lt;br /&gt;
   # Authorize the application on dropbox site&lt;br /&gt;
   url = sess.build_authorize_url(request_token)&lt;br /&gt;
   print &amp;quot;url:&amp;quot;, url&lt;br /&gt;
   print &amp;quot;Please visit this website and press the 'Allow' button, then hit 'Enter' here.&amp;quot;&lt;br /&gt;
   raw_input()&lt;br /&gt;
   # This will fail if the user didn't visit the above URL and hit 'Allow'&lt;br /&gt;
   access_token = sess.obtain_access_token(request_token)&lt;br /&gt;
   f = open(&amp;quot;dropbox_token.txt&amp;quot;,&amp;quot;wb&amp;quot;)&lt;br /&gt;
   f.write(access_token.key + '\n')&lt;br /&gt;
   f.write(access_token.secret)&lt;br /&gt;
   f.close()&lt;br /&gt;
 else:&lt;br /&gt;
   sess.set_token(oauth_token, oauth_token_secret)&lt;br /&gt;
 client = client.DropboxClient(sess)&lt;br /&gt;
 print &amp;quot;linked account:&amp;quot;, client.account_info()&lt;br /&gt;
 def sync_dir(dir):&lt;br /&gt;
   rootdir = dir&lt;br /&gt;
   print &amp;quot;Syncing directory:&amp;quot;, rootdir&lt;br /&gt;
   startTime = backupDelay&lt;br /&gt;
   for root, subFolders, files in os.walk(rootdir):&lt;br /&gt;
     for file in files:&lt;br /&gt;
       fname = os.path.join(root,file)&lt;br /&gt;
       if os.path.getmtime(fname)&amp;gt;startTime:&lt;br /&gt;
         #print root, file&lt;br /&gt;
         os.system(&amp;quot;mkdir -p 'backup&amp;quot;+root+&amp;quot;'&amp;quot;)&lt;br /&gt;
         os.system(&amp;quot;cp '&amp;quot;+fname+&amp;quot;' 'backup&amp;quot;+fname+&amp;quot;'&amp;quot;)&lt;br /&gt;
 print &amp;quot;Making dump of MySQL databases...&amp;quot;&lt;br /&gt;
 os.system(&amp;quot;mysqldump --all-databases -uroot -pROOT_ПАРОЛЬ_MYSQL -r backup/backup.sql&amp;quot;)&lt;br /&gt;
 sync_dir(&amp;quot;/var/www&amp;quot;)&lt;br /&gt;
 sync_dir(&amp;quot;/var/spool/virtual&amp;quot;)&lt;br /&gt;
 sync_dir(&amp;quot;/home/user&amp;quot;)&lt;br /&gt;
 backupName = 'backup_'+curDate+'.7z'&lt;br /&gt;
 print &amp;quot;Creating archive with name&amp;quot;, backupName&lt;br /&gt;
 os.system(&amp;quot;7z a -pПАРОЛЬ_АРХИВА &amp;quot;+backupName+&amp;quot; backup/* /etc&amp;quot;)&lt;br /&gt;
 f = open(backupName,'rb')&lt;br /&gt;
 if f:&lt;br /&gt;
   fsize = getsize(backupName)&lt;br /&gt;
   uploader = client.get_chunked_uploader(f, fsize)&lt;br /&gt;
   print &amp;quot;Uploading file&amp;quot;, fsize, &amp;quot;bytes...&amp;quot;&lt;br /&gt;
   while uploader.offset &amp;lt; fsize:&lt;br /&gt;
     try:&lt;br /&gt;
       upload = uploader.upload_chunked()&lt;br /&gt;
       print &amp;quot;.&amp;quot;&lt;br /&gt;
     except rest.ErrorResponse, e:&lt;br /&gt;
       # perform error handling and retry logic&lt;br /&gt;
       print &amp;quot;error uploading file!&amp;quot;&lt;br /&gt;
   uploader.finish(&amp;quot;/&amp;quot;+backupName)&lt;br /&gt;
   f.close()&lt;br /&gt;
   print &amp;quot;File uploaded successfully.&amp;quot;&lt;br /&gt;
 print &amp;quot;Deleting temp files...&amp;quot;&lt;br /&gt;
 os.system(&amp;quot;rm -r backup/*&amp;quot;)&lt;br /&gt;
 os.system(&amp;quot;rm &amp;quot; + backupName);&lt;br /&gt;
&lt;br /&gt;
'''Послесловие'''&lt;br /&gt;
&lt;br /&gt;
Этот скрипт я добавил в crontab с запуском ежедневно в 4:00 утра.&lt;br /&gt;
В скрипте есть три строки с вызовом функции sync_dir, точно так же вы сами можете настроить, какие папки вам надо бэкапить.&lt;br /&gt;
Скрипт не удаляет файлы, которые были удалены из папки, если инкрементально разархивировать полный архив и последующие, то удалённые папки/файлы останутся.&lt;br /&gt;
Удаление старых бэкапов в самом Dropbox я делать не стал, чищу папку сам когда вспоминаю об этом.&lt;br /&gt;
Недавно взял себе еще пару VPS в других странах, а в скрипт добавил только префикс к названию бэкапов, таким образом все бэкапы сливаются в одну папку, но их можно отличить очень просто.&lt;br /&gt;
&lt;br /&gt;
[[Категория:Linux]]&lt;/div&gt;</summary>
		<author><name>Sol</name></author>
	</entry>
</feed>