|
| 1 | +# Paperless Ngx |
| 2 | + |
| 3 | +Document management system for organizing, indexing, and searching your documents. |
| 4 | + |
| 5 | +## Installation |
| 6 | + |
| 7 | +Enable Paperless by setting `COMPOSE_PROFILES=paperless`. |
| 8 | + |
| 9 | +Paperless will be accessible at `/paperless`. |
| 10 | + |
| 11 | +On first run, an admin account will be created with the credentials specified in `paperless/.env`. |
| 12 | + |
| 13 | +## Environment Variables |
| 14 | + |
| 15 | +| Variable | Description | Default | |
| 16 | +|----------------------------|-------------------------------------------------|-----------------| |
| 17 | +| `PAPERLESS_SECRET_KEY` | Secret key for production, generate with `openssl rand -base64 32` | | |
| 18 | +| `PAPERLESS_TIME_ZONE` | Timezone for the container | `America/New_York` | |
| 19 | +| `PAPERLESS_OCR_LANGUAGE` | Default OCR language | `eng` | |
| 20 | +| `PAPERLESS_ADMIN_USER` | Admin username | `admin` | |
| 21 | +| `PAPERLESS_ADMIN_PASSWORD` | Admin password | `changeme` | |
| 22 | + |
| 23 | +## Backup |
| 24 | + |
| 25 | +Paperless data can be backed up to any cloud storage product using [Restic](https://restic.readthedocs.io/) via [resticker](https://github.com/djmaze/resticker). |
| 26 | + |
| 27 | +Restic provides: |
| 28 | +- **Incremental backups**: Only changed data is backed up |
| 29 | +- **Deduplication**: Identical content across snapshots uses minimal space |
| 30 | +- **Encryption**: All data encrypted with your repository password |
| 31 | +- **Compression**: Optional, doesn't interfere with deduplication |
| 32 | +- **Remote backends**: S3, B2, SFTP, Rclone remotes, and more |
| 33 | + |
| 34 | +### What Gets Backed Up |
| 35 | + |
| 36 | +- **Data directory** (`/usr/src/paperless/data`): SQLite database and settings |
| 37 | +- **Media directory** (`/usr/src/paperless/media`): Documents, thumbnails, and attachments |
| 38 | + |
| 39 | +### What Is Excluded |
| 40 | + |
| 41 | +- **Thumbnails** (`/data/media/.thumbnails/`): Can be regenerated |
| 42 | + |
| 43 | +### Initial Setup |
| 44 | + |
| 45 | +#### 1. Configure Backup Environment |
| 46 | + |
| 47 | +Copy the backup environment template and customize it: |
| 48 | + |
| 49 | +```bash |
| 50 | +cp paperless/backup.env.example paperless/backup.env |
| 51 | +``` |
| 52 | + |
| 53 | +Edit `paperless/backup.env` and set the following: |
| 54 | + |
| 55 | +| Variable | Description | Example | |
| 56 | +|-----------------------|-----------------------------------------------|----------------------------| |
| 57 | +| `RESTIC_REPOSITORY` | Backup destination URI for Restic | See examples below | |
| 58 | +| `RESTIC_PASSWORD` | Strong password to encrypt the repository | Generate with `openssl rand -base64 32` | |
| 59 | +| `CRON` | Backup schedule (cron format with seconds) | `0 30 3 * * *` (3:30 AM daily) | |
| 60 | +| `TIMEZONE` | Timezone for cron scheduling | `America/New_York` | |
| 61 | +| `RESTIC_FORGET_ARGS` | Backup retention policy | `--keep-last 7 --keep-daily 7 --keep-weekly 4 --keep-monthly 3` | |
| 62 | + |
| 63 | +#### 2. Choose Your Backup Destination |
| 64 | + |
| 65 | +Restic supports multiple backends. Pick one based on your infrastructure: |
| 66 | + |
| 67 | +**Rclone Remote** (Optional - reuse existing rclone configuration): |
| 68 | + |
| 69 | +Rclone is optional. Use this only if your `RESTIC_REPOSITORY` URI starts with `rclone:`. If you prefer to use Rclone, it allows you to back up to any service supported by Rclone (S3, B2, SFTP, Google Drive, OneDrive, Dropbox, etc.) without direct Restic support, or if you want to reuse existing Rclone configurations. |
| 70 | + |
| 71 | +First, configure your rclone remote destination: |
| 72 | + |
| 73 | +```bash |
| 74 | +docker compose run --rm -it paperless-backup rclone config |
| 75 | +``` |
| 76 | + |
| 77 | +This interactive command will guide you through: |
| 78 | +1. Creating a new remote (choose `n`) |
| 79 | +2. Naming your remote (e.g., `backup-s3`, `backup-b2`, `backup-sftp`, etc.) |
| 80 | +3. Selecting your storage type (S3, B2, SFTP, etc.) |
| 81 | +4. Entering credentials and configuration |
| 82 | + |
| 83 | +The configuration will be saved to `paperless/.rclone/rclone.conf`. Do not manually edit this file; use the `rclone config` command above to modify it. |
| 84 | + |
| 85 | +Then set in `backup.env`: |
| 86 | + |
| 87 | +```bash |
| 88 | +RESTIC_REPOSITORY=rclone:myremote:/nas-backups/paperless |
| 89 | +``` |
| 90 | + |
| 91 | +This allows you to use any rclone-supported backend seamlessly. |
| 92 | + |
| 93 | +**S3-Compatible (Direct)** (AWS, Wasabi, MinIO, DigitalOcean Spaces, etc. - no Rclone needed): |
| 94 | + |
| 95 | +You can also back up directly to S3-compatible services without using Rclone: |
| 96 | + |
| 97 | +```bash |
| 98 | +# Set in backup.env: |
| 99 | +RESTIC_REPOSITORY=s3:s3.amazonaws.com/my-bucket/paperless |
| 100 | + |
| 101 | +# Or for S3-compatible services: |
| 102 | +RESTIC_REPOSITORY=s3:https://s3.wasabisys.com/my-bucket/paperless |
| 103 | + |
| 104 | +# Additional environment variables: |
| 105 | +AWS_ACCESS_KEY_ID=your_key |
| 106 | +AWS_SECRET_ACCESS_KEY=your_secret |
| 107 | +``` |
| 108 | + |
| 109 | +**Backblaze B2** (Direct - no Rclone needed): |
| 110 | +```bash |
| 111 | +# Set in backup.env: |
| 112 | +RESTIC_REPOSITORY=b2:my-bucket:paperless |
| 113 | + |
| 114 | +# And provide credentials: |
| 115 | +B2_ACCOUNT_ID=your_account_id |
| 116 | +B2_ACCOUNT_KEY=your_account_key |
| 117 | +``` |
| 118 | + |
| 119 | +**SFTP** (Direct - no Rclone needed): |
| 120 | +```bash |
| 121 | +# Set in backup.env: |
| 122 | +RESTIC_REPOSITORY=sftp://user@backup.example.com/paperless |
| 123 | + |
| 124 | +# Password authentication is interactive or set: |
| 125 | +SFTP_PASSWORD=your_sftp_password |
| 126 | +``` |
| 127 | + |
| 128 | +**Local Path** (NAS mounted volume or local directory - no Rclone needed): |
| 129 | +```bash |
| 130 | +# Set in backup.env: |
| 131 | +RESTIC_REPOSITORY=/mnt/backup-drive/paperless |
| 132 | + |
| 133 | +# Ensure the directory exists and is writable: |
| 134 | +mkdir -p /mnt/backup-drive/paperless |
| 135 | +``` |
| 136 | + |
| 137 | +**Google Cloud Storage** (Direct - no Rclone needed): |
| 138 | +```bash |
| 139 | +# Set in backup.env: |
| 140 | +RESTIC_REPOSITORY=gs://my-bucket/paperless |
| 141 | + |
| 142 | +# And provide credentials (via service account JSON): |
| 143 | +GOOGLE_APPLICATION_CREDENTIALS=/path/to/credentials.json |
| 144 | +``` |
| 145 | + |
| 146 | +**Azure Blob Storage** (Direct - no Rclone needed): |
| 147 | +```bash |
| 148 | +# Set in backup.env: |
| 149 | +RESTIC_REPOSITORY=azure://paperless-container/paperless |
| 150 | + |
| 151 | +# And provide credentials: |
| 152 | +AZURE_ACCOUNT_NAME=myaccount |
| 153 | +AZURE_ACCOUNT_KEY=mykey |
| 154 | +``` |
| 155 | + |
| 156 | +#### 3. Generate a Secure Password |
| 157 | + |
| 158 | +```bash |
| 159 | +# Generate a strong random password |
| 160 | +openssl rand -base64 32 |
| 161 | + |
| 162 | +# Copy the output and paste it into backup.env as RESTIC_PASSWORD |
| 163 | +``` |
| 164 | + |
| 165 | +**Important**: Store this password securely. You'll need it to restore backups. If lost, your backup data becomes inaccessible. |
| 166 | + |
| 167 | +### Testing the Backup |
| 168 | + |
| 169 | +#### List Existing Snapshots |
| 170 | + |
| 171 | +```bash |
| 172 | +docker compose run --rm paperless-backup snapshots |
| 173 | +``` |
| 174 | + |
| 175 | +This will list all backup snapshots. If the repository doesn't exist yet, it will be initialized automatically on the first scheduled backup. |
| 176 | + |
| 177 | +#### Manually Trigger a Backup |
| 178 | + |
| 179 | +Perform a one-time backup: |
| 180 | + |
| 181 | +```bash |
| 182 | +docker compose run --rm paperless-backup backup /data |
| 183 | +``` |
| 184 | + |
| 185 | +Then apply the retention policy to clean up old snapshots: |
| 186 | + |
| 187 | +```bash |
| 188 | +docker compose run --rm paperless-backup forget --prune --keep-last 7 --keep-daily 7 --keep-weekly 4 --keep-monthly 3 |
| 189 | +``` |
| 190 | + |
| 191 | +(Note: Replace the `--keep-*` arguments with your configured `RESTIC_FORGET_ARGS` from `backup.env`) |
| 192 | + |
| 193 | +#### Check Repository Status |
| 194 | + |
| 195 | +```bash |
| 196 | +docker compose run --rm paperless-backup check |
| 197 | +``` |
| 198 | + |
| 199 | +#### Monitor Scheduled Backups |
| 200 | + |
| 201 | +Start the Paperless backup service: |
| 202 | + |
| 203 | +```bash |
| 204 | +COMPOSE_PROFILES=paperless,paperless-backup docker compose up -d |
| 205 | +``` |
| 206 | + |
| 207 | +Then monitor backup logs: |
| 208 | + |
| 209 | +```bash |
| 210 | +docker compose logs -f paperless-backup |
| 211 | +``` |
| 212 | + |
| 213 | +The backup will run automatically according to the schedule in `backup.env` (default: 3:30 AM daily). |
| 214 | + |
| 215 | +### Restoration |
| 216 | + |
| 217 | +#### Quick restore overview: |
| 218 | + |
| 219 | +1. Stop the Paperless service |
| 220 | +2. Restore the SQLite database from the Restic snapshot |
| 221 | +3. Restore the media directory from the Restic snapshot |
| 222 | +4. Start Paperless again |
| 223 | + |
| 224 | +To restore a specific snapshot: |
| 225 | + |
| 226 | +```bash |
| 227 | +docker compose run --rm paperless-backup restore <snapshot-id> --target /restored |
| 228 | +``` |
| 229 | + |
| 230 | +Then: |
| 231 | +1. Copy the database: `cp /restored/paperless.db /restored/data/paperless.db` |
| 232 | +2. Copy the media: `cp -r /restored/media/* paperless-media/` |
| 233 | +3. Restart Paperless |
0 commit comments