mirror of
https://github.com/skoobasteeve/skoobasteeve.github.io.2.git
synced 2026-03-20 07:58:57 +00:00
Compare commits
40 Commits
nas-ubuntu
...
0bb96f6308
| Author | SHA1 | Date | |
|---|---|---|---|
|
0bb96f6308
|
|||
|
8732edbd28
|
|||
|
650654002c
|
|||
|
e7269c40cd
|
|||
|
73f02fc964
|
|||
|
cbe5b72833
|
|||
|
4db791aa02
|
|||
|
|
073651bb8a | ||
|
1b7861fcba
|
|||
|
7057e88bc3
|
|||
|
ce142465b8
|
|||
|
535c4b2ddb
|
|||
|
a240d00ad1
|
|||
| 7d043d1901 | |||
|
|
82f2e1c604 | ||
| e1220573a3 | |||
| 12923178e4 | |||
| 0603df625a | |||
| ec236d164d | |||
| 12da493d02 | |||
| 09555857a5 | |||
| 0b1b837a3a | |||
| a1009ba693 | |||
| a0741b118c | |||
| c4c031e396 | |||
| b81af5bdfc | |||
| 01c85f968e | |||
| f73e2e7cc2 | |||
|
|
330f65b394 | ||
| f7828305ee | |||
| f639d251b3 | |||
| 8dc7d17015 | |||
| fe6991fb0b | |||
| 0349db6717 | |||
| db7255c3c1 | |||
| 308fc94ed9 | |||
| 1ea489227e | |||
| 9d9e0525e5 | |||
| a556126ba0 | |||
|
|
6b5525a071 |
16
.devcontainer/devcontainer.json
Normal file
16
.devcontainer/devcontainer.json
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
{
|
||||||
|
"image": "mcr.microsoft.com/devcontainers/jekyll:bookworm",
|
||||||
|
|
||||||
|
"customizations": {
|
||||||
|
"vscode": {
|
||||||
|
"extensions": [
|
||||||
|
"albert.TabOut",
|
||||||
|
"ecmel.vscode-html-css",
|
||||||
|
"redhat.vscode-yaml",
|
||||||
|
"rebornix.Ruby"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
"forwardPorts": [4000]
|
||||||
|
}
|
||||||
2
404.html
2
404.html
@@ -20,6 +20,6 @@ layout: default
|
|||||||
<div class="container">
|
<div class="container">
|
||||||
<h1>404</h1>
|
<h1>404</h1>
|
||||||
|
|
||||||
<p><strong>Page not found :(</strong></p>
|
<p><strong>Page not found</strong></p>
|
||||||
<p>The requested page could not be found.</p>
|
<p>The requested page could not be found.</p>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
2
Gemfile
2
Gemfile
@@ -15,6 +15,8 @@ source "https://rubygems.org"
|
|||||||
|
|
||||||
gem "jekyll"
|
gem "jekyll"
|
||||||
gem "minimal-mistakes-jekyll"
|
gem "minimal-mistakes-jekyll"
|
||||||
|
gem "jekyll-sitemap"
|
||||||
|
gem "webrick"
|
||||||
|
|
||||||
# The following plugins are automatically loaded by the theme-gem:
|
# The following plugins are automatically loaded by the theme-gem:
|
||||||
# gem "jekyll-paginate"
|
# gem "jekyll-paginate"
|
||||||
|
|||||||
89
Gemfile.lock
89
Gemfile.lock
@@ -1,93 +1,100 @@
|
|||||||
GEM
|
GEM
|
||||||
remote: https://rubygems.org/
|
remote: https://rubygems.org/
|
||||||
specs:
|
specs:
|
||||||
addressable (2.7.0)
|
addressable (2.8.5)
|
||||||
public_suffix (>= 2.0.2, < 5.0)
|
public_suffix (>= 2.0.2, < 6.0)
|
||||||
colorator (1.1.0)
|
colorator (1.1.0)
|
||||||
concurrent-ruby (1.1.7)
|
concurrent-ruby (1.2.2)
|
||||||
em-websocket (0.5.2)
|
em-websocket (0.5.3)
|
||||||
eventmachine (>= 0.12.9)
|
eventmachine (>= 0.12.9)
|
||||||
http_parser.rb (~> 0.6.0)
|
http_parser.rb (~> 0)
|
||||||
eventmachine (1.2.7)
|
eventmachine (1.2.7)
|
||||||
faraday (1.0.1)
|
faraday (2.7.10)
|
||||||
multipart-post (>= 1.2, < 3)
|
faraday-net_http (>= 2.0, < 3.1)
|
||||||
ffi (1.13.1)
|
ruby2_keywords (>= 0.0.4)
|
||||||
|
faraday-net_http (3.0.2)
|
||||||
|
ffi (1.15.5)
|
||||||
forwardable-extended (2.6.0)
|
forwardable-extended (2.6.0)
|
||||||
http_parser.rb (0.6.0)
|
google-protobuf (3.24.0-x86_64-linux)
|
||||||
i18n (1.8.5)
|
http_parser.rb (0.8.0)
|
||||||
|
i18n (1.14.1)
|
||||||
concurrent-ruby (~> 1.0)
|
concurrent-ruby (~> 1.0)
|
||||||
jekyll (4.1.1)
|
jekyll (4.3.2)
|
||||||
addressable (~> 2.4)
|
addressable (~> 2.4)
|
||||||
colorator (~> 1.0)
|
colorator (~> 1.0)
|
||||||
em-websocket (~> 0.5)
|
em-websocket (~> 0.5)
|
||||||
i18n (~> 1.0)
|
i18n (~> 1.0)
|
||||||
jekyll-sass-converter (~> 2.0)
|
jekyll-sass-converter (>= 2.0, < 4.0)
|
||||||
jekyll-watch (~> 2.0)
|
jekyll-watch (~> 2.0)
|
||||||
kramdown (~> 2.1)
|
kramdown (~> 2.3, >= 2.3.1)
|
||||||
kramdown-parser-gfm (~> 1.0)
|
kramdown-parser-gfm (~> 1.0)
|
||||||
liquid (~> 4.0)
|
liquid (~> 4.0)
|
||||||
mercenary (~> 0.4.0)
|
mercenary (>= 0.3.6, < 0.5)
|
||||||
pathutil (~> 0.9)
|
pathutil (~> 0.9)
|
||||||
rouge (~> 3.0)
|
rouge (>= 3.0, < 5.0)
|
||||||
safe_yaml (~> 1.0)
|
safe_yaml (~> 1.0)
|
||||||
terminal-table (~> 1.8)
|
terminal-table (>= 1.8, < 4.0)
|
||||||
jekyll-feed (0.15.0)
|
webrick (~> 1.7)
|
||||||
|
jekyll-feed (0.17.0)
|
||||||
jekyll (>= 3.7, < 5.0)
|
jekyll (>= 3.7, < 5.0)
|
||||||
jekyll-gist (1.5.0)
|
jekyll-gist (1.5.0)
|
||||||
octokit (~> 4.2)
|
octokit (~> 4.2)
|
||||||
jekyll-include-cache (0.2.0)
|
jekyll-include-cache (0.2.1)
|
||||||
jekyll (>= 3.7, < 5.0)
|
jekyll (>= 3.7, < 5.0)
|
||||||
jekyll-paginate (1.1.0)
|
jekyll-paginate (1.1.0)
|
||||||
jekyll-sass-converter (2.1.0)
|
jekyll-sass-converter (3.0.0)
|
||||||
sassc (> 2.0.1, < 3.0)
|
sass-embedded (~> 1.54)
|
||||||
jekyll-sitemap (1.4.0)
|
jekyll-sitemap (1.4.0)
|
||||||
jekyll (>= 3.7, < 5.0)
|
jekyll (>= 3.7, < 5.0)
|
||||||
jekyll-watch (2.2.1)
|
jekyll-watch (2.2.1)
|
||||||
listen (~> 3.0)
|
listen (~> 3.0)
|
||||||
kramdown (2.3.0)
|
kramdown (2.4.0)
|
||||||
rexml
|
rexml
|
||||||
kramdown-parser-gfm (1.1.0)
|
kramdown-parser-gfm (1.1.0)
|
||||||
kramdown (~> 2.0)
|
kramdown (~> 2.0)
|
||||||
liquid (4.0.3)
|
liquid (4.0.4)
|
||||||
listen (3.2.1)
|
listen (3.8.0)
|
||||||
rb-fsevent (~> 0.10, >= 0.10.3)
|
rb-fsevent (~> 0.10, >= 0.10.3)
|
||||||
rb-inotify (~> 0.9, >= 0.9.10)
|
rb-inotify (~> 0.9, >= 0.9.10)
|
||||||
mercenary (0.4.0)
|
mercenary (0.4.0)
|
||||||
minimal-mistakes-jekyll (4.20.2)
|
minimal-mistakes-jekyll (4.24.0)
|
||||||
jekyll (>= 3.7, < 5.0)
|
jekyll (>= 3.7, < 5.0)
|
||||||
jekyll-feed (~> 0.1)
|
jekyll-feed (~> 0.1)
|
||||||
jekyll-gist (~> 1.5)
|
jekyll-gist (~> 1.5)
|
||||||
jekyll-include-cache (~> 0.1)
|
jekyll-include-cache (~> 0.1)
|
||||||
jekyll-paginate (~> 1.1)
|
jekyll-paginate (~> 1.1)
|
||||||
jekyll-sitemap (~> 1.3)
|
jekyll-sitemap (~> 1.3)
|
||||||
multipart-post (2.1.1)
|
octokit (4.25.1)
|
||||||
octokit (4.18.0)
|
faraday (>= 1, < 3)
|
||||||
faraday (>= 0.9)
|
sawyer (~> 0.9)
|
||||||
sawyer (~> 0.8.0, >= 0.5.3)
|
|
||||||
pathutil (0.16.2)
|
pathutil (0.16.2)
|
||||||
forwardable-extended (~> 2.6)
|
forwardable-extended (~> 2.6)
|
||||||
public_suffix (4.0.6)
|
public_suffix (5.0.3)
|
||||||
rb-fsevent (0.10.4)
|
rb-fsevent (0.11.2)
|
||||||
rb-inotify (0.10.1)
|
rb-inotify (0.10.1)
|
||||||
ffi (~> 1.0)
|
ffi (~> 1.0)
|
||||||
rexml (3.2.4)
|
rexml (3.2.6)
|
||||||
rouge (3.23.0)
|
rouge (4.1.3)
|
||||||
|
ruby2_keywords (0.0.5)
|
||||||
safe_yaml (1.0.5)
|
safe_yaml (1.0.5)
|
||||||
sassc (2.4.0)
|
sass-embedded (1.64.2-x86_64-linux-gnu)
|
||||||
ffi (~> 1.9)
|
google-protobuf (~> 3.23)
|
||||||
sawyer (0.8.2)
|
sawyer (0.9.2)
|
||||||
addressable (>= 2.3.5)
|
addressable (>= 2.3.5)
|
||||||
faraday (> 0.8, < 2.0)
|
faraday (>= 0.17.3, < 3)
|
||||||
terminal-table (1.8.0)
|
terminal-table (3.0.2)
|
||||||
unicode-display_width (~> 1.1, >= 1.1.1)
|
unicode-display_width (>= 1.1.1, < 3)
|
||||||
unicode-display_width (1.7.0)
|
unicode-display_width (2.4.2)
|
||||||
|
webrick (1.8.1)
|
||||||
|
|
||||||
PLATFORMS
|
PLATFORMS
|
||||||
ruby
|
x86_64-linux
|
||||||
|
|
||||||
DEPENDENCIES
|
DEPENDENCIES
|
||||||
jekyll
|
jekyll
|
||||||
|
jekyll-sitemap
|
||||||
minimal-mistakes-jekyll
|
minimal-mistakes-jekyll
|
||||||
|
webrick
|
||||||
|
|
||||||
BUNDLED WITH
|
BUNDLED WITH
|
||||||
2.1.4
|
2.4.18
|
||||||
|
|||||||
26
_config.yml
26
_config.yml
@@ -85,11 +85,7 @@ social:
|
|||||||
|
|
||||||
# Analytics
|
# Analytics
|
||||||
analytics:
|
analytics:
|
||||||
provider : false # false (default), "google", "google-universal", "google-gtag", "custom"
|
provider : "custom"
|
||||||
google:
|
|
||||||
tracking_id :
|
|
||||||
anonymize_ip : # true, false (default)
|
|
||||||
|
|
||||||
|
|
||||||
# Site Author
|
# Site Author
|
||||||
author:
|
author:
|
||||||
@@ -100,23 +96,20 @@ author:
|
|||||||
email :
|
email :
|
||||||
links:
|
links:
|
||||||
- label: "E201 06CB 86FE 0B4D"
|
- label: "E201 06CB 86FE 0B4D"
|
||||||
icon: "fas fa-fingerprint"
|
icon: "fas fa-fw fa-fingerprint"
|
||||||
url: "https://keybase.io/scubasteve/pgp_keys.asc?fingerprint=2dc3a1066bba7040fe7963d9e20106cb86fe0b4d"
|
url: "https://keybase.io/scubasteve/pgp_keys.asc?fingerprint=2dc3a1066bba7040fe7963d9e20106cb86fe0b4d"
|
||||||
- label: "Email"
|
- label: "Email"
|
||||||
icon: "fas fa-fw fa-envelope-square"
|
icon: "fas fa-fw fa-envelope-square"
|
||||||
url: "mailto:ray@raylyon.net"
|
url: "mailto:ray@raylyon.net"
|
||||||
- label: "Keybase"
|
- label: "Keybase"
|
||||||
icon: "fab fa-keybase"
|
icon: "fab fa-fw fa-keybase"
|
||||||
url: "https://keybase.io/scubasteve"
|
url: "https://keybase.io/scubasteve"
|
||||||
- label: "Website"
|
- label: "Website"
|
||||||
icon: "fas fa-fw fa-link"
|
icon: "fas fa-fw fa-link"
|
||||||
# url: "https://your-website.com"
|
# url: "https://your-website.com"
|
||||||
- label: "Twitter"
|
- label: "Mastodon"
|
||||||
icon: "fab fa-fw fa-twitter-square"
|
icon: "fab fa-fw fa-mastodon"
|
||||||
# url: "https://twitter.com/"
|
url: "https://fosstodon.org/@skoobasteeve"
|
||||||
- label: "Facebook"
|
|
||||||
icon: "fab fa-fw fa-facebook-square"
|
|
||||||
# url: "https://facebook.com/"
|
|
||||||
- label: "GitHub"
|
- label: "GitHub"
|
||||||
icon: "fab fa-fw fa-github"
|
icon: "fab fa-fw fa-github"
|
||||||
url: "https://github.com/skoobasteeve"
|
url: "https://github.com/skoobasteeve"
|
||||||
@@ -287,3 +280,10 @@ defaults:
|
|||||||
related: true
|
related: true
|
||||||
classes: wide
|
classes: wide
|
||||||
show_date: true
|
show_date: true
|
||||||
|
# _pages
|
||||||
|
- scope:
|
||||||
|
path: ""
|
||||||
|
type: pages
|
||||||
|
values:
|
||||||
|
layout: single
|
||||||
|
author_profile: true
|
||||||
|
|||||||
1
_includes/analytics-providers/custom.html
Normal file
1
_includes/analytics-providers/custom.html
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<script async defer data-domain="rayagainstthemachine.net" src="https://plausible.io/js/plausible.js"></script>
|
||||||
20
_includes/footer.html
Executable file
20
_includes/footer.html
Executable file
@@ -0,0 +1,20 @@
|
|||||||
|
<div class="page__footer-follow">
|
||||||
|
<ul class="social-icons">
|
||||||
|
{% if site.data.ui-text[site.locale].follow_label %}
|
||||||
|
<li><strong>{{ site.data.ui-text[site.locale].follow_label }}</strong></li>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if site.footer.links %}
|
||||||
|
{% for link in site.footer.links %}
|
||||||
|
{% if link.label and link.url %}
|
||||||
|
<li><a href="{{ link.url }}" rel="nofollow noopener noreferrer"><i class="{{ link.icon | default: 'fas fa-link' }}" aria-hidden="true"></i> {{ link.label }}</a></li>
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
<li><a href="{% if site.atom_feed.path %}{{ site.atom_feed.path }}{% else %}{{ '/feed.xml' | relative_url }}{% endif %}"><i class="fas fa-fw fa-rss-square" aria-hidden="true"></i> {{ site.data.ui-text[site.locale].feed_label | default: "Feed" }}</a></li>
|
||||||
|
<li><a rel="me" href="https://fosstodon.org/@skoobasteeve"><i class="fab fa-mastodon" aria-hidden="true"></i> Mastodon</a></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="page__footer-copyright">© {{ site.time | date: '%Y' }} {{ site.name | default: site.title }}. {{ site.data.ui-text[site.locale].powered_by | default: "Powered by" }} <a href="https://jekyllrb.com" rel="nofollow">Jekyll</a> & <a href="https://mademistakes.com/work/minimal-mistakes-jekyll-theme/" rel="nofollow">Minimal Mistakes</a>.</div>
|
||||||
@@ -8,6 +8,6 @@ I love Linux, open-source, and technology in general.
|
|||||||
|
|
||||||
This blog was built using [Jekyll](https://jekyllrb.com/) and the [Minimal Mistakes](https://github.com/mmistakes/minimal-mistakes) theme. All updates and tweaks can be followed on by GitHub repo linked in the sidebar.
|
This blog was built using [Jekyll](https://jekyllrb.com/) and the [Minimal Mistakes](https://github.com/mmistakes/minimal-mistakes) theme. All updates and tweaks can be followed on by GitHub repo linked in the sidebar.
|
||||||
|
|
||||||
I'm not very active on social media, but feel free to email me or leave a comment if you want to get in touch. You'll likely receive a quick response as I jump on any opportunity to talk tech.
|
I'm not very active on social media (besides <a rel="me" href="https://fosstodon.org/@skoobasteeve">Mastodon</a>), but feel free to email me or leave a comment if you want to get in touch. You'll likely receive a quick response as I jump on any opportunity to talk tech.
|
||||||
|
|
||||||
Thanks and Happy Hacking!
|
Thanks and Happy Hacking!
|
||||||
@@ -1,7 +1,8 @@
|
|||||||
---
|
---
|
||||||
layout: single
|
layout: single
|
||||||
title: "Painless On-Demand NAS Connections in Linux with Systemd Automount"
|
title: "On-Demand NFS and Samba Connections in Linux with Systemd Automount"
|
||||||
date: 2020-10-07 19:00:00
|
date: 2020-10-07 19:00:00
|
||||||
|
last_modified_at: 2021-08-26
|
||||||
categories: [Linux Administration]
|
categories: [Linux Administration]
|
||||||
tags: linux samba nas systemd ubuntu
|
tags: linux samba nas systemd ubuntu
|
||||||
comments: true
|
comments: true
|
||||||
@@ -21,7 +22,7 @@ If you're not familiar with Systemd unit files and how they work, I would highly
|
|||||||
|
|
||||||
You'll need to create dedicated folders on your machine where the shares will be mounted.
|
You'll need to create dedicated folders on your machine where the shares will be mounted.
|
||||||
|
|
||||||
``` bash
|
```bash
|
||||||
$ sudo mkdir -p /mnt/smb/sambashare
|
$ sudo mkdir -p /mnt/smb/sambashare
|
||||||
$ sudo mkdir -p /mnt/nfs/nfsshare
|
$ sudo mkdir -p /mnt/nfs/nfsshare
|
||||||
```
|
```
|
||||||
@@ -30,7 +31,7 @@ $ sudo mkdir -p /mnt/nfs/nfsshare
|
|||||||
|
|
||||||
If your Samba server uses authentication, you'll need to create a file with your login details that Systemd can use to connect. These should be saved in a safe location with restricted permissions.
|
If your Samba server uses authentication, you'll need to create a file with your login details that Systemd can use to connect. These should be saved in a safe location with restricted permissions.
|
||||||
|
|
||||||
``` bash
|
```bash
|
||||||
$ sudo nano /etc/samba/smbcreds
|
$ sudo nano /etc/samba/smbcreds
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -39,7 +40,7 @@ username=[USERNAME]
|
|||||||
password=[PASSWORD]
|
password=[PASSWORD]
|
||||||
```
|
```
|
||||||
|
|
||||||
``` bash
|
```bash
|
||||||
$ sudo chmod 600 /etc/samba/smbcreds
|
$ sudo chmod 600 /etc/samba/smbcreds
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -47,13 +48,13 @@ $ sudo chmod 600 /etc/samba/smbcreds
|
|||||||
|
|
||||||
#### Samba
|
#### Samba
|
||||||
|
|
||||||
``` bash
|
```bash
|
||||||
$ sudo apt install samba cifs-utils
|
$ sudo apt install samba cifs-utils
|
||||||
```
|
```
|
||||||
|
|
||||||
#### NFS
|
#### NFS
|
||||||
|
|
||||||
``` bash
|
```bash
|
||||||
$ sudo apt install nfs-common
|
$ sudo apt install nfs-common
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -63,7 +64,7 @@ To make this work, we need (2) unit files for each connection: the **mount** uni
|
|||||||
|
|
||||||
The below instructions assume your samba share is located at `//example.server/sambafiles`.
|
The below instructions assume your samba share is located at `//example.server/sambafiles`.
|
||||||
|
|
||||||
``` bash
|
```bash
|
||||||
$ sudo nano /etc/systemd/system/mnt-smb-sambashare.mount
|
$ sudo nano /etc/systemd/system/mnt-smb-sambashare.mount
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -86,20 +87,22 @@ WantedBy=multi-user.target
|
|||||||
```
|
```
|
||||||
|
|
||||||
A few notes on the above file:
|
A few notes on the above file:
|
||||||
|
|
||||||
* `vers=2.1` - adjust this based on the version of samba running on your server
|
* `vers=2.1` - adjust this based on the version of samba running on your server
|
||||||
* `uid=1000` - adjust this based on your local user ID to avoid permissions problems. This is usually 1000 on a desktop system.
|
* `uid=1000` - adjust this based on your local user ID to avoid permissions problems. This is usually 1000 on a desktop system.
|
||||||
|
|
||||||
\
|
\
|
||||||
Next we need to create the automount file in the same location.
|
Next we need to create the automount file in the same location.
|
||||||
|
|
||||||
``` bash
|
***EDIT 2021-08-26*** Reader flansuse pointed out that including `Requires=network-online.target` in the automount file did not conform with systemd guidelines. I confirmed that the mounts work perfectly well without that line, so it's been removed.
|
||||||
|
|
||||||
|
```bash
|
||||||
$ sudo nano /etc/systemd/system/mnt-smb-sambashare.automount
|
$ sudo nano /etc/systemd/system/mnt-smb-sambashare.automount
|
||||||
```
|
```
|
||||||
|
|
||||||
```
|
```
|
||||||
[Unit]
|
[Unit]
|
||||||
Description=samba automount for yourfiles
|
Description=samba automount for yourfiles
|
||||||
Requires=network-online.target
|
|
||||||
|
|
||||||
[Automount]
|
[Automount]
|
||||||
Where=/mnt/smb/sambashare
|
Where=/mnt/smb/sambashare
|
||||||
@@ -111,10 +114,12 @@ WantedBy=multi-user.target
|
|||||||
|
|
||||||
#### NFS
|
#### NFS
|
||||||
|
|
||||||
The below instructions assume your NFS share is located at `example.server:/srv/nfsfiles`.
|
The below instructions assume your NFS share is located at `example.server:/srv/nfsfiles`.
|
||||||
|
|
||||||
``` bash
|
***EDIT 2021-08-26*** Reader Denis suggested adding the `TimeoutSec` parameter to the below file to prevent lock-ups when the share isn't present on your local network. Thank you Denis for the contribution!
|
||||||
$ sudo nano /etc/systemd/system/mnt-nfs-nfssahre.mount
|
|
||||||
|
```bash
|
||||||
|
$ sudo nano /etc/systemd/system/mnt-nfs-nfsshare.mount
|
||||||
```
|
```
|
||||||
|
|
||||||
```
|
```
|
||||||
@@ -126,6 +131,7 @@ What=example.server:/srv/nfsfiles
|
|||||||
Where=/mnt/nfs/nfsshare
|
Where=/mnt/nfs/nfsshare
|
||||||
Type=nfs
|
Type=nfs
|
||||||
Options=defaults
|
Options=defaults
|
||||||
|
TimeoutSec=5
|
||||||
|
|
||||||
[Install]
|
[Install]
|
||||||
WantedBy=multi-user.target
|
WantedBy=multi-user.target
|
||||||
@@ -134,14 +140,13 @@ WantedBy=multi-user.target
|
|||||||
\
|
\
|
||||||
Same as before, we need to create the automount file in the same location.
|
Same as before, we need to create the automount file in the same location.
|
||||||
|
|
||||||
``` bash
|
```bash
|
||||||
$ sudo nano /etc/systemd/system/mnt-smb-nfsshare.automount
|
$ sudo nano /etc/systemd/system/mnt-nfs-nfsshare.automount
|
||||||
```
|
```
|
||||||
|
|
||||||
```
|
```
|
||||||
[Unit]
|
[Unit]
|
||||||
Description=nfs automount for nfsfiles
|
Description=nfs automount for nfsfiles
|
||||||
Requires=network-online.target
|
|
||||||
|
|
||||||
[Automount]
|
[Automount]
|
||||||
Where=/mnt/nfs/nfsshare
|
Where=/mnt/nfs/nfsshare
|
||||||
@@ -193,4 +198,4 @@ $ sudo systemctl enable mnt-smb-smbshare.automount
|
|||||||
\
|
\
|
||||||
That's it! To test, reboot your system, open the mountpoint in terminal or the file manager, and your share will mount before your eyes. If you have any questions or critiques on the above instructions, please shoot me an [email](mailto:ray@raylyon.net) or open a [Github issue](https://github.com/skoobasteeve/skoobasteeve.github.io.2/issues).
|
That's it! To test, reboot your system, open the mountpoint in terminal or the file manager, and your share will mount before your eyes. If you have any questions or critiques on the above instructions, please shoot me an [email](mailto:ray@raylyon.net) or open a [Github issue](https://github.com/skoobasteeve/skoobasteeve.github.io.2/issues).
|
||||||
|
|
||||||
Thanks for reading and happy hacking!
|
Thanks for reading and happy hacking!
|
||||||
|
|||||||
284
_posts/2020-10-23-nextcloud-photos.md
Normal file
284
_posts/2020-10-23-nextcloud-photos.md
Normal file
@@ -0,0 +1,284 @@
|
|||||||
|
---
|
||||||
|
layout: single
|
||||||
|
title: "Better Nextcloud Photo Albums with Preview Generator and Exiftool"
|
||||||
|
date: 2020-10-27 18:00:00
|
||||||
|
excerpt: "If you host and use a Nextcloud server, you know that it's good at many things. Unfortunately, displaying photos is not one of them."
|
||||||
|
categories: [Linux Administration]
|
||||||
|
tags: linux ubuntu nextcloud photos exiftool
|
||||||
|
comments: true
|
||||||
|
---
|
||||||
|
|
||||||
|
{:class="img-responsive" .align-center}
|
||||||
|
|
||||||
|
If you host and use a Nextcloud server, you know that it's good at many things. Unfortunately, displaying photos is not one of them. Since Nextcloud does not read photo metadata, your albums will often appear out-of-order. You may also notice that thumbnails and previews take a very long time to load and flipping quickly through a bunch of photos becomes a painful waiting game.
|
||||||
|
|
||||||
|
The good news is that because Nextcloud is a wonderful piece of FOSS that we're self-hosting, we can make some modifications to smooth out these pain points.
|
||||||
|
|
||||||
|
There are (2) pieces of software we'll be using to accomplish this:
|
||||||
|
|
||||||
|
- [Preview Generator](https://apps.nextcloud.com/apps/previewgenerator) (Nextcloud app)
|
||||||
|
- [exiftool](https://exiftool.org/) (Linux app)
|
||||||
|
|
||||||
|
Both are freely available from Nextcloud and your distro's package manager, respectively. Let's dive in!
|
||||||
|
|
||||||
|
# Previews and Thumbnails
|
||||||
|
|
||||||
|
First we need to fix Nextcloud's preview generation. By default, Nextcloud generates photo previews and thumbnails on-demand, leading to slow load times. To fix this, we're going to use the Preview Generator app for Nextcloud to pre-generate previews on a regular basis. That way, your photos are ready to view as soon as you open the folder.
|
||||||
|
|
||||||
|
1. **Install the Preview Generator app for Nextcloud**. From a Nextcloud account with admin permissions, navigate to the Apps section and locate Preview Generator under the Multimedia category. Click Download and enable.
|
||||||
|
|
||||||
|
{:class="img-responsive" .align-center}
|
||||||
|
|
||||||
|
2. **Configure preview and thumbnail settings.** While the default settings work well from a performance standpoint, they cause Nextcloud to generate a huge number of previews and thumbnails for each photo. Once you add a lot of photos, you'll notice that these previews eat into your storage significantly (sometimes more than the photos themselves). Fortunately, Preview Generator is highly configurable.
|
||||||
|
|
||||||
|
SSH into your Nextcloud server and follow the instructions below.
|
||||||
|
|
||||||
|
**Note:** I've found that the below settings provide a good balance of resolution, performance, and storage usage for my environment. You can tweak them depending on your needs.
|
||||||
|
|
||||||
|
Set the default thumbnail sizes by using the following occ commands:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo -u www-data php /var/www/nextcloud/occ config:app:set --value="32 256" previewgenerator squareSizes
|
||||||
|
sudo -u www-data php /var/www/nextcloud/occ config:app:set --value="256 384" previewgenerator widthSizes
|
||||||
|
sudo -u www-data php /var/www/nextcloud/occ config:app:set --value="256" previewgenerator heightSizes
|
||||||
|
```
|
||||||
|
|
||||||
|
Next, edit your config.php to specify the maximum preview size for images. This is going to effect the appearance and load time of images when you click on them.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo nano /var/www/nextcloud/config/config.php
|
||||||
|
```
|
||||||
|
|
||||||
|
Find the below lines toward the end of the file. If they don't exist, add them to the block.
|
||||||
|
|
||||||
|
```php
|
||||||
|
'preview_max_x' => '2048',
|
||||||
|
'preview_max_y' => '2048',
|
||||||
|
'jpeg_quality' => '60',
|
||||||
|
```
|
||||||
|
|
||||||
|
Save the file and restart the web server.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo service apache2 restart
|
||||||
|
```
|
||||||
|
|
||||||
|
3. **Generate initial previews.** Open a terminal on your Nextcloud server and run the following command:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo -u www-data php /var/www/nextcloud/occ preview:generate-all -vvv
|
||||||
|
```
|
||||||
|
|
||||||
|
The above command is run as the web server user since they are typically the owner of the Nextcloud directory, though you may need to tweak it based on your server configuration.
|
||||||
|
|
||||||
|
**NOTE:** Depending on the amount of photos you have, this could take a while to complete and use a high amount of resources. If you have users beyond yourself, it's probably best to run it during a low-activity period.
|
||||||
|
|
||||||
|
4. **Add a cron job.** This allows Preview Generator to run continuously generate previews as new photos are added to Nextcloud. To avoid permissions problems, we'll edit the crontab of the web server user:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo -u www-data crontab -e
|
||||||
|
```
|
||||||
|
|
||||||
|
Add the following below line to the file. The below example runs the command every 10 minutes, but you can set the frequency to whatever you want.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
*/10 * * * * /usr/bin/php -f /var/www/nextcloud/occ preview:pre-generate
|
||||||
|
```
|
||||||
|
|
||||||
|
**NOTE:** If you have a specific version of PHP installed beyond your distro's default, you'll want to specify that version of the binary above (e.g. `php7.4` instead of `php`).
|
||||||
|
|
||||||
|
# Photo Sorting
|
||||||
|
|
||||||
|
**UPDATE 2021-01-26:** Added methods to run the script on both client and server systems.
|
||||||
|
{: .notice--info}
|
||||||
|
|
||||||
|
Nextcloud is first and foremost a file sharing application, so it views files just as your file system would. This is great until you get to photo albums, where the EXIF metadata of the photo is more relevant to sorting than the filename or modified date. To be sure that all photos in Nextcloud display in chronological order, we need to get creative.
|
||||||
|
|
||||||
|
That's where the wonderful exiftool comes in. This powerful command-line application allows you to read and manipulate the EXIF data of a photo. The feature that solves our problem is the ability to read the original capture date of a photo and apply it to both the *last modified* attribute and the *filename*. This way, no matter how you sort the images in Nextcloud, they'll display in **chronological** order.
|
||||||
|
|
||||||
|
You have **two options** for using exiftool:
|
||||||
|
|
||||||
|
1. Run a script from a synced **client** computer.
|
||||||
|
|
||||||
|
2. Run a script on the data directory on the **server**.
|
||||||
|
|
||||||
|
The advantage of running it on the server is that you can automate periodic scans of your photos so they are always sorted properly and up-to-date. The disadvantage is that there are some extra steps involved that may take a long time depending on the speed of your server.
|
||||||
|
|
||||||
|
To get started using exiftool, follow the instructions below on one of your **Nextcloud clients.**
|
||||||
|
|
||||||
|
### Write the script
|
||||||
|
|
||||||
|
1. Install exiftool on your chosen Nextcloud client.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo apt install exiftool
|
||||||
|
```
|
||||||
|
|
||||||
|
2. Create a new file with the below contents and save it as a script.
|
||||||
|
|
||||||
|
```shell
|
||||||
|
sudo nano photo-cleanup.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
**Option 1: Client Script:**
|
||||||
|
|
||||||
|
```shell
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
albumdir=$1
|
||||||
|
|
||||||
|
# use below variables if running on the server
|
||||||
|
# nextclouddir="/var/www/nextcloud"
|
||||||
|
# user who owns the photos
|
||||||
|
# nextclouduser=""
|
||||||
|
|
||||||
|
echo "Changing modified date to shot date..."
|
||||||
|
exiftool "-filemodifydate<datetimeoriginal" -r "$albumdir"
|
||||||
|
|
||||||
|
echo "Renaming files to shot date..."
|
||||||
|
exiftool '-FileName<DateTimeOriginal' -r -d "%Y-%m-%d_%H.%M.%S%%-c.%%e" "$albumdir"
|
||||||
|
|
||||||
|
# uncomment the below command if running on the server
|
||||||
|
# echo "Re-scanning your Nextcloud data directory..."
|
||||||
|
# sudo -u www-data php "$nextclouddir"/occ files:scan "$nextclouduser"
|
||||||
|
|
||||||
|
exit 0
|
||||||
|
```
|
||||||
|
|
||||||
|
**Option 2: Server Script:**
|
||||||
|
|
||||||
|
```shell
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
albumdir=$1
|
||||||
|
|
||||||
|
# use below variables if running on the server
|
||||||
|
nextclouddir="/var/www/nextcloud"
|
||||||
|
# user who owns the photos
|
||||||
|
nextclouduser=""
|
||||||
|
|
||||||
|
echo "Changing modified date to shot date..."
|
||||||
|
exiftool "-filemodifydate<datetimeoriginal" -r "$albumdir"
|
||||||
|
|
||||||
|
echo "Renaming files to shot date..."
|
||||||
|
exiftool '-FileName<DateTimeOriginal' -r -d "%Y-%m-%d_%H.%M.%S%%-c.%%e" "$albumdir"
|
||||||
|
|
||||||
|
# uncomment the below command if running on the server
|
||||||
|
echo "Re-scanning your Nextcloud data directory..."
|
||||||
|
sudo -u www-data php "$nextclouddir"/occ files:scan "$nextclouduser"
|
||||||
|
|
||||||
|
exit 0
|
||||||
|
```
|
||||||
|
|
||||||
|
I'll break down what's happening above:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
albumdir=$1
|
||||||
|
```
|
||||||
|
|
||||||
|
Sets your album directory as the first argument when you execute the script.
|
||||||
|
|
||||||
|
```shell
|
||||||
|
nextclouddir="/var/www/nextcloud"
|
||||||
|
```
|
||||||
|
|
||||||
|
**Server script only**: set to your Nextcloud install folder.
|
||||||
|
|
||||||
|
```shell
|
||||||
|
nextclouduser=""
|
||||||
|
```
|
||||||
|
|
||||||
|
**Server script only**: set to the Nextcloud user that owns the photo directory.
|
||||||
|
|
||||||
|
```shell
|
||||||
|
exiftool "-filemodifydate<datetimeoriginal" -r "$albumdir"
|
||||||
|
```
|
||||||
|
|
||||||
|
Instructs exiftool to read `datetimeoriginal` (date and time the photo was shot) from each photo and apply it as the `filemodifydate`. The `-r` flag runs the command recursively so it will work its way through all folders in the photos directory.
|
||||||
|
|
||||||
|
```shell
|
||||||
|
exiftool '-FileName<DateTimeOriginal' -r -d "%Y-%m-%d_%H.%M.%S%%-c.%%e" "$albumdir"
|
||||||
|
```
|
||||||
|
|
||||||
|
Similar to the previous command but applies `datetimeoriginal` to the filename. The `-d` flag specifies how the date and time data are laid out in the new filename.
|
||||||
|
|
||||||
|
### Test the script
|
||||||
|
|
||||||
|
**Warning:** If you're choosing to run the **server** script, keep in mind that the final files:scan command can take a long time to complete depending on the amount of photos and speed of your instance. It's best to run it during a scheduled maintenance window.
|
||||||
|
{: .notice--warning}
|
||||||
|
|
||||||
|
Let's test this simple script on a directory of photos.
|
||||||
|
|
||||||
|
Give the script permission to execute.
|
||||||
|
|
||||||
|
```shell
|
||||||
|
chmod +x photo-cleanup.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
You can see below a directory filled with photos. Note the modify dates and filenames on the right side.
|
||||||
|
|
||||||
|
```shell
|
||||||
|
ls -al Photos
|
||||||
|
total 35340
|
||||||
|
drwxrwxr-x 2 raylyon raylyon 4096 Aug 6 18:49 .
|
||||||
|
drwxr-xr-x 6 raylyon raylyon 4096 Oct 25 21:51 ..
|
||||||
|
-rwxr-xr-x 1 raylyon raylyon 6280032 Oct 19 01:42 P1060462.jpg
|
||||||
|
-rwxr-xr-x 1 raylyon raylyon 4056662 Oct 19 02:02 P1060468.jpg
|
||||||
|
-rwxr-xr-x 1 raylyon raylyon 4915105 Oct 19 02:05 P1060481.jpg
|
||||||
|
-rwxr-xr-x 1 raylyon raylyon 6375408 Oct 19 02:06 P1060530.jpg
|
||||||
|
-rwxr-xr-x 1 raylyon raylyon 6635572 Oct 19 02:06 P1060546.jpg
|
||||||
|
-rwxr-xr-x 1 raylyon raylyon 7903375 Oct 19 02:08 P1060552.jpg
|
||||||
|
```
|
||||||
|
|
||||||
|
Now we'll run the script on this directory.
|
||||||
|
|
||||||
|
```shell
|
||||||
|
./photo-cleanup.sh "/home/raylyon/Nextcloud/Photos"
|
||||||
|
Changing modified date to shot date...
|
||||||
|
1 directories scanned
|
||||||
|
6 image files updated
|
||||||
|
Renaming files to shot date...
|
||||||
|
1 directories scanned
|
||||||
|
6 image files updated
|
||||||
|
```
|
||||||
|
|
||||||
|
```shell
|
||||||
|
ls -al Photos
|
||||||
|
total 35340
|
||||||
|
drwxrwxr-x 2 raylyon raylyon 4096 Oct 25 21:56 .
|
||||||
|
drwxr-xr-x 6 raylyon raylyon 4096 Oct 25 21:51 ..
|
||||||
|
-rwxr-xr-x 1 raylyon raylyon 6280032 Jul 31 11:27 2020-07-31_11.27.39.jpg
|
||||||
|
-rwxr-xr-x 1 raylyon raylyon 4056662 Jul 31 12:09 2020-07-31_12.09.05.jpg
|
||||||
|
-rwxr-xr-x 1 raylyon raylyon 4915105 Jul 31 12:35 2020-07-31_12.35.29.jpg
|
||||||
|
-rwxr-xr-x 1 raylyon raylyon 6375408 Aug 1 08:22 2020-08-01_08.22.03.jpg
|
||||||
|
-rwxr-xr-x 1 raylyon raylyon 6635572 Aug 1 19:46 2020-08-01_19.46.18.jpg
|
||||||
|
-rwxr-xr-x 1 raylyon raylyon 7903375 Aug 1 19:47 2020-08-01_19.47.24.jpg
|
||||||
|
```
|
||||||
|
|
||||||
|
Just like that, our filenames and metadata are updated.
|
||||||
|
|
||||||
|
### (Optional) Add a Cron job
|
||||||
|
|
||||||
|
You could run the script manually each time you add photos, but who has time for that? If you're frequently adding new photos and directories, you can automate it.
|
||||||
|
|
||||||
|
To do so, we'll add an entry to the crontab on the client or server.
|
||||||
|
|
||||||
|
**Client (user crontab)**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
crontab -e
|
||||||
|
```
|
||||||
|
|
||||||
|
**Server (system crontab)**
|
||||||
|
|
||||||
|
```shell
|
||||||
|
sudo crontab -e
|
||||||
|
```
|
||||||
|
|
||||||
|
```shell
|
||||||
|
*/30 * * * * /path/to/your/script/photo-cleanup.sh "/path/to/Nextcloud/Photos"
|
||||||
|
```
|
||||||
|
|
||||||
|
The above entry runs the script every 30 minutes, checking the directory and any sub-directories for new photos and updating them accordingly. Adjust the timing to your needs.
|
||||||
|
|
||||||
|
Have any great Nextcloud photo tips that I missed? Shoot me an email or leave a comment below. Thanks for reading and happy hacking!
|
||||||
197
_posts/2021-01-10-backup-planning.md
Normal file
197
_posts/2021-01-10-backup-planning.md
Normal file
@@ -0,0 +1,197 @@
|
|||||||
|
---
|
||||||
|
layout: single
|
||||||
|
title: "Backups: Planning an Effective Strategy"
|
||||||
|
date: 2021-01-10 18:10:00
|
||||||
|
categories: [Linux Administration]
|
||||||
|
tags: linux backups BorgBackup borg rsync nextcloud
|
||||||
|
comments: true
|
||||||
|
---
|
||||||
|
|
||||||
|
If you've ever asked a sysadmin or computer geek for advice, you've probably heard the universal refrain: "Always have a backup" or "RAID is not a backup" or my personal favorite "One is none" (referring to copies of your data).
|
||||||
|
|
||||||
|
While virtually everyone working in this space agrees on the above, you'll get wildly different answers to your next question: "How do I do it?"
|
||||||
|
|
||||||
|
The intention of this post is to cut through the noise and give you an understanding of the concepts you should be thinking about before committing to a particular technology or piece of software.
|
||||||
|
|
||||||
|
***NOTE*** - Due to the nature of this blog, most of the example applications I provide are FOSS and Linux-compatible, but you can apply the same concepts to other apps and operating systems.
|
||||||
|
|
||||||
|
## Break Your Data Into "Tiers"
|
||||||
|
|
||||||
|
Whether you're talking about a server or a desktop, it's a safe bet that not every file on your hard drive(s) holds equal importance. That is, there are some files you care about vastly more than others. When setting up a backup system, sorting these files by priority will save you time, money, and disk space down the road.
|
||||||
|
|
||||||
|
### Tier 1: Files you can't afford to lose
|
||||||
|
|
||||||
|
Family pictures, tax documents, home videos; things that aren't replaceable or would incur significant cost to replace, financial or otherwise. **These should exist in at least 3 places**.
|
||||||
|
|
||||||
|
### Tier 2: Files that you *can* replace, but don't want to
|
||||||
|
|
||||||
|
Music and movies, either ripped from physical media or "obtained" from elsewhere, are good contenders for this category. You may have spent hours meticulously cataloging your media collection, but those files can always be re-downloaded or ripped. **These should exist in at least 2 places**.
|
||||||
|
|
||||||
|
### Tier 3: Files that don't matter
|
||||||
|
|
||||||
|
Installed applications, games, operating system files, miscellaneous downloads, etc. Files in this category can be easily replaced with a simple re-install or are publicly available on the internet. It's not necessary to back up these files unless you've got extra terabytes burning a hole in your pocket.
|
||||||
|
|
||||||
|
## Choose a Strategy for Each Tier
|
||||||
|
|
||||||
|
There are a huge amount of software options for handling your backups, and the strengths and weaknesses of each primarily depend on the type of data your backing up. It's important to understand these characteristics and so you can apply them to your different data tiers.
|
||||||
|
|
||||||
|
### Cloud Sync Services
|
||||||
|
|
||||||
|
Services like Google Drive, Dropbox, or self-hosted [Nextcloud](https://nextcloud.com/) (my personal choice) use desktop and mobile applications to automatically sync your files between your devices and a centralized cloud server. Files that you save to a defined folder on your computer are instantly uploaded to the cloud and downloaded to the other devices. These files are accessible from anywhere via a web interface.
|
||||||
|
|
||||||
|
**Advantages**
|
||||||
|
|
||||||
|
+ **Easy to set up** - Pick a service, create an account, download the application and sync your files.
|
||||||
|
|
||||||
|
+ **Instant and automatic** - Backups occur whenever a file is added or changed. No need to schedule a backup ahead of time or manually press a button.
|
||||||
|
|
||||||
|
+ **Resilient** - The web applications almost always have a "trash bin" for deleted file recovery, version control for rollbacks, and server infrastructure that gets its own backups. The files also exist offline on your synced devices.
|
||||||
|
|
||||||
|
+ **Readily Available** - Your files are accessible from any computer anywhere in the world via a web browser, including your smartphone.
|
||||||
|
|
||||||
|
**Disadvantages**
|
||||||
|
|
||||||
|
- **Expensive for high volumes** - The free tiers of most sync services only give you around 5-15GB of storage, so for anything larger than that you'll have to pay for the additional storage.
|
||||||
|
|
||||||
|
- **Cumbersome for large files** - It's easy for the desktop apps to get bogged down with large files and slow down your computer, and once your get up into the hundreds of gigabytes, you could fill up the hard drives of all your devices pretty quickly. You'll also be severely limited by the slow upload speeds of most home broadband connections.
|
||||||
|
|
||||||
|
- **Reliance on third-party** - You have to trust that Google, Dropbox, or other services will respect your privacy and keep your files safe. **EXCEPTION:** [Self-hosted Nextcloud server.](https://docs.nextcloud.com/server/20/admin_manual/installation/)
|
||||||
|
|
||||||
|
**Best for**
|
||||||
|
|
||||||
|
- **Tier 1** - Documents take up very little space and upload quickly. Even a years worth of photos from your smartphone will only use a few GB in most cases.
|
||||||
|
|
||||||
|
- **Tier 2 (smaller files)** - Application config files or even mp3s if you have a small collection.
|
||||||
|
|
||||||
|
### Local File Sync
|
||||||
|
|
||||||
|
This is as simple as it gets: plug in a USB hard drive or connect to a network share and copy your files to it. While it's possible to accomplish this with a drag-and-drop, there are many great software tools that can help: [FreeFileSync,](https://freefilesync.org/) [DirSyncPro](https://www.dirsyncpro.org/), and [rsync](https://wiki.archlinux.org/index.php/rsync) are all great options for the desktop.
|
||||||
|
|
||||||
|
**Advantages**
|
||||||
|
|
||||||
|
- **SImple** - Does not require extensive knowledge to set up and understand what's happening, and files aren't hidden behind compression or custom folder structures. Great for people who want visual verification of a successful backup.
|
||||||
|
|
||||||
|
- **Fast** - A local USB3 or gigabit LAN connection is going be faster than your internet upload speed 9 times out of 10.
|
||||||
|
|
||||||
|
- **Cheap** - In the long run, local storage is always cheaper than cloud.
|
||||||
|
|
||||||
|
- **Offline and in your control** - No need to rely on any third-party service or server that may be untrustworthy.
|
||||||
|
|
||||||
|
**Disadvantages**
|
||||||
|
|
||||||
|
- **Not as resilient as other options** - File sync applications, while simple, don't always have more advanced features like versioning and verification, making it easier to run into problems without realizing it.
|
||||||
|
|
||||||
|
**Best for**
|
||||||
|
|
||||||
|
- **Tier 2** - Without the storage limitations of the cloud, it's great to use on all your files, no matter how large.
|
||||||
|
|
||||||
|
### Local Backups
|
||||||
|
|
||||||
|
What's the difference between local backup and local sync? It's largely semantics, but for the purposes of this post I'll make some distinctions. The file sync applications I mentioned above are great for just that: ensuring that a folder in one location is an exact copy of a folder in another location. This is great, but if you want to get *serious* about your backups, a more specialized application is what you want.
|
||||||
|
|
||||||
|
Backup applications like [BorgBackup](https://www.borgbackup.org/), [Duplicati](https://www.duplicati.com/), and [BackupPC](https://backuppc.github.io/backuppc/) can also back up to a USB HDD or network share, but they also provide features that make your backups more efficient and resilient: versioning, encryption, de-duplication, and compression to name a few.
|
||||||
|
|
||||||
|
**Advantages**
|
||||||
|
|
||||||
|
- **Secure** - Encryption allows you to protect your backups with a password.
|
||||||
|
|
||||||
|
- **Resilient** - Retention of multiple versions and built-in error checking lowers your chances of losing data significantly.
|
||||||
|
|
||||||
|
- **Cheap** - Same hardware requirements as local sync, and all the software examples I gave are free and open-source.
|
||||||
|
|
||||||
|
- **Offline and in your control** - No need to rely on any third-party service or server that may be untrustworthy.
|
||||||
|
|
||||||
|
**Disadvantages**
|
||||||
|
|
||||||
|
- **Complexity** - The additional features these apps offer can make them more difficult to set up, and the extra features mean the backups will be hidden by specialized file names and folder structures.
|
||||||
|
|
||||||
|
**Best for**
|
||||||
|
|
||||||
|
- **Tier 2** - Without the storage limitations of the cloud, it's great to use on all your files, no matter how large.
|
||||||
|
|
||||||
|
- **Tier 1** - Combine with a cloud option and you'll have hard time ever losing your data.
|
||||||
|
|
||||||
|
### Cloud Backups
|
||||||
|
|
||||||
|
We already established the cloud as a great option for your Tier 1 files, so what makes cloud backups different from cloud sync services? Cloud backup applications use the same methodology as the local backup applications I mentioned above, but instead of going to a USB HDD or NAS, we're sending them to a cloud storage provider. Encryption, compression, de-duplication and versioning are features you can expect to find, and many of the apps I referenced previously are cloud-compatible. [BorgBackup](https://www.borgbackup.org/), [Restic](https://restic.net/), and [Duplicati](https://www.duplicati.com/) are all great options in this space.
|
||||||
|
|
||||||
|
**Advantages**
|
||||||
|
|
||||||
|
- **Secure** - Encryption allows you to use third-party hosting and storage services with fewer privacy and security concerns. They can't see your files, only the encrypted data.
|
||||||
|
|
||||||
|
- **Resilient** - Retention of multiple versions and built-in error checking lowers your chances of losing data significantly.
|
||||||
|
|
||||||
|
- **No hardware required** - No need to connect to local hard drive or network share, all you need is an internet connection and the backup will run in the background at a scheduled time.
|
||||||
|
|
||||||
|
- **Cheaper storage options than cloud sync** - Since device sync and web availability isn't a requirement for this type of backup, you're options are opened up to virtually any cloud storage vendor.
|
||||||
|
|
||||||
|
**Disadvantages**
|
||||||
|
|
||||||
|
- **Can still be expensive for high volumes** - While usually cheaper than cloud sync services, you'll still have to pay a subscription fee based on your usage.
|
||||||
|
|
||||||
|
- **Complexity** - Just like local backups, the applications take more work to set up than a simple sync service and the backups are stored in esoteric formats and folder structures.
|
||||||
|
|
||||||
|
**Best for**
|
||||||
|
|
||||||
|
- **Tier 1** - When your files are too large to practically store on a sync service. Also good for use in addition to a sync service.
|
||||||
|
|
||||||
|
## Local Backups - USB or NAS?
|
||||||
|
|
||||||
|
If you're starting from nothing, getting a USB hard drive will likely be your first step. If you don't have one lying around already, they can be purchased cheaply and are easy to plug in and use. However, if you can afford it, the ideal solution is either a pre-built NAS appliance (Synology, iXSystems, or QNAP) or a DIY NAS using either a traditional x86 PC or something like a Raspberry Pi or RockPro64. Either way, it's important to understand the advantages and limitations of both options.
|
||||||
|
|
||||||
|
### USB Hard Drives
|
||||||
|
|
||||||
|
**Advantages**
|
||||||
|
|
||||||
|
- **Cheap** - 4TB drives are less than $100 at most retailers.
|
||||||
|
|
||||||
|
- **Simple to set up** - Have you ever plugged in a USB cable before? That's it!
|
||||||
|
|
||||||
|
- **Portable** - Keep them on your desk or hide them in a drawer when you're done.
|
||||||
|
|
||||||
|
**Disadvantages**
|
||||||
|
|
||||||
|
- **Not good for laptops** - You probably don't want to carry your laptop around with a USB hard drive hanging out of it. With a mobile device, you'll have to remember to periodically plug it in and run the backup manually.
|
||||||
|
|
||||||
|
- **Current or resilient: pick one** - If you have a computer that can be tethered to a USB HDD 24/7, you can automate your backups and run them as often as you like. However, you then open yourself up to a single-point-of-failure situation where your O.S. could accidentally corrupt the data, or a disaster like an electrical surge or fire could take out both at once. To avoid this, you can detach the drive and store it in a secure location after the backup completes, but then you have to remember to plug it back in and your backups likely won't remain current as a result.
|
||||||
|
|
||||||
|
### NAS
|
||||||
|
|
||||||
|
**Advantages**
|
||||||
|
|
||||||
|
- **Shareable** - Since a NAS resides on your network, you can back up multiple laptops, desktops, and servers at once without having to plug in a cable.
|
||||||
|
|
||||||
|
- **Great for laptops** - Since you don't need to plug in a hard drive, your laptop can back itself up automatically at a scheduled time.
|
||||||
|
|
||||||
|
- **Separate from your devices** - Since a NAS is not directly connected to any one computer, the single-point-of-failure scenario is less likely.
|
||||||
|
|
||||||
|
**Disadvantages**
|
||||||
|
|
||||||
|
- **Pre-built devices can be expensive** - Even Synology's cheapest option with 4TB will be close to 4x the price of a USB hard drive with the same storage.
|
||||||
|
- **Setup and maintenance** - Whether pre-built or custom, a NAS is a full computer running on your network that needs to be configured, updated, and maintained. To minimize this, choose a purpose-built device from Synology or QNAP.
|
||||||
|
|
||||||
|
## So what should you do?
|
||||||
|
|
||||||
|
Everybody's situation is different, but here are some general conclusions you can draw from this information:
|
||||||
|
|
||||||
|
1. **Tier 1** data should be backed up both locally and with a cloud sync or backup service.
|
||||||
|
|
||||||
|
2. **Tier 2** data should be backed up locally in at least one additional location.
|
||||||
|
|
||||||
|
3. Local backups are preferred over simple file syncs for their reliability and resiliency.
|
||||||
|
|
||||||
|
4. If you can't maintain a local backup, combine a cloud sync service with a cloud backup application.
|
||||||
|
|
||||||
|
5. **The most important thing is that you do *something***. Your data is too valuable and your computer's hard drive is too volatile to leave things up to chance.
|
||||||
|
|
||||||
|
## Bonus: What I Use
|
||||||
|
|
||||||
|
- Some **Tier 1** data is synced to a Nextcloud server hosted on DigitalOcean and that server is backed up to my local NAS using [BorgBackup](https://www.borgbackup.org/) and [Borgmatic](https://torsion.org/borgmatic/).
|
||||||
|
|
||||||
|
- All **Tier 1** data on my NAS is backed up nightly to [BorgBase](https://www.borgbase.com/) using BorgBackup and Borgmatic.
|
||||||
|
|
||||||
|
- **Tier 2** data on my NAS is backed up nightly to external hard drives using ZFS and [Sanoid/Syncpoid](https://github.com/jimsalterjrs/sanoid).
|
||||||
|
|
||||||
|
Have a great backup system of your own? As always, feel free to leave a comment or reach out to me directly with questions or feedback. Since BorgBackup is clearly a favorite of mine, I'll be sure to cover it in detail in a future post.
|
||||||
|
|
||||||
|
Thanks for reading and happy hacking!
|
||||||
28
_posts/2022-01-07-kalendar.md
Normal file
28
_posts/2022-01-07-kalendar.md
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
---
|
||||||
|
layout: single
|
||||||
|
title: "I Was About to Write a To-Do App for the Linux Desktop... and then I found Kalendar."
|
||||||
|
date: 2023-01-08 12:45:00
|
||||||
|
excerpt: "2022 was a great year for my Python skills. I had some unique problems to solve in my day job that got me over the hump of learning the language, and finally I was able to write comfortably without googling syntax every five minutes..."
|
||||||
|
categories: [Software Development]
|
||||||
|
tags: linux python qt6 qt desktop kde kalendar
|
||||||
|
comments: true
|
||||||
|
---
|
||||||
|
|
||||||
|
{:class="img-responsive" .align-center}
|
||||||
|
|
||||||
|
2022 was a great year for my Python skills. I had some unique problems to solve in my day job that got me over the hump of learning the language, and finally I was able to write comfortably without Googling syntax every five minutes. Quickly my team's Github repo filled up with borderline-unnecessary one-off scripts to solve all sorts of niche problems in our environment. Due to the nature of being a system administrator at a SaaS-heavy company, most of these scripts deal with third-party APIs: moving data from "service a" to "service b", pulling information about "service c" and correlating it with "service d", etc. These types of scripts are fun to write because they have narrow scopes and easily achievable goals, and I find completing them to be immensely satisfying.
|
||||||
|
|
||||||
|
Filled with confidence in my Python skills, I set out to embark on my first GUI project: a desktop to-do application with CalDAV sync. This is an app I feel has been missing on Linux, something akin to Apple Reminders where I can use my own backend for sync. To get started, I built a local-only terminal client, bought a book to start learning PyQt, and I sat down today to write the first of a series of blog posts where I would document the project. I got to the part of the blog post where I confidently say that there are "currently no working Linux desktop apps with this functionality". Then I thought, *maybe I should Google this once more and confirm there really is nothing out there*. Well, shit.
|
||||||
|
|
||||||
|
## Enter Kalendar
|
||||||
|
|
||||||
|
The last time I researched this space, there were no functional standalone to-do apps that supported CalDAV sync. The closest I could find was Thunderbird, my beloved email client, which is far more complex than what I was looking for. [Kalendar](https://apps.kde.org/kalendar/) didn't even pop up on my radar. Even today when I searched, I almost didn't find it. I ended up seeing it on the [Nextcloud Tasks Github page](https://github.com/nextcloud/tasks#apps-which-sync-with-nextcloud-tasks-using-caldav) in a list of compatible apps with sync. Within minutes, I had it installed and synced with my tasks in Nextcloud, and **wow**, this thing is good.
|
||||||
|
|
||||||
|
Kalendar bills itself mainly as a new calendar app, but my task lists feel right at home here. The app opens instantly, and the task view is designed almost exactly as I envisioned for my own app; toggleable lists on the left and tasks on the right. Type on the bottom and hit enter to quickly create a new task and it syncs right up to Nextcloud. Right click on a task to easily set priority and due date, or add a subtask. I hate how good this is.
|
||||||
|
|
||||||
|
## What now?
|
||||||
|
|
||||||
|
I'm now a happy Kalendar user, and I've lost all motivation to write my own app, but I still want to learn GUI development! I've got remedial Python skills and my QT6 book ready to go! If this was ten years ago, there would probably be lots of voids to fill in the Linux app space, but as it stands today there are very few missing pieces. It feels like there's a great app for pretty much everything.
|
||||||
|
|
||||||
|
Does anyone have any desktop app ideas? Something missing from their day-to-day workflow? Are any projects you know of using PyQt that I could contribute to? Please let me know in the comments or send me a message. Trying to seize on some motivation here!
|
||||||
|
|
||||||
75
_posts/2023-08-27-nextcloud-podman.md
Normal file
75
_posts/2023-08-27-nextcloud-podman.md
Normal file
@@ -0,0 +1,75 @@
|
|||||||
|
---
|
||||||
|
layout: single
|
||||||
|
title: "Building a Reproducible Nextcloud Server, Part one: Choosing the stack"
|
||||||
|
date: 2023-08-27 10:00:00
|
||||||
|
excerpt: "After successfully hosting a Nextcloud instance on the same VPS for 7 years, I decided to rebuild it from scratch with modern tooling."
|
||||||
|
categories: [Self-Hosting, Linux Administration]
|
||||||
|
tags: linux nextcloud podman docker container vps
|
||||||
|
comments: true
|
||||||
|
---
|
||||||
|
|
||||||
|
Nextcloud was the first application I *really* self-hosted. I don't mean self-hosting like running the Plex app in the system tray on your gaming PC; I mean a dedicated VPS, exposed to the world, hosting my personal data. The stakes were high, and over the last seven years, it pushed me to grow my Linux knowledge and ultimately made me a far better sysadmin.
|
||||||
|
|
||||||
|
A lot happened during that seven years. Containers and infrastructure-as-code blew up and changed the IT industry. Nextcloud as a company and an application grew tremendously. I got married. Throughout all these changes, my little $5 DigitalOcean droplet running Nextcloud on the LAMP stack kept right on ticking. Despite three OS upgrades, two volume expansions, and fifteen(!) Nextcloud major-version upgrades, that thing refused to die. It continued to host my (and my wife's) critical data until the day I decommissioned it just under 60 days ago.
|
||||||
|
|
||||||
|
# Why change?
|
||||||
|
|
||||||
|
As a sysadmin and a huge Linux nerd, I'd been following the technology and industry changes closely, and every time I heard about something new or read a blog post I couldn't help but wonder "if I rebuilt my Nextcloud server today, how would I do it?". Everything is a container now, and infrastructure and system configuration is all defined as text files, making it reproducible and popularizing the phrase "cattle, not pets". I wanted a chance to embrace these concepts and use the skills I spent the last seven years improving. Plus, what sysadmin doesn't like playing with the new shiny?
|
||||||
|
|
||||||
|
# Goals
|
||||||
|
|
||||||
|
So what did I want to accomplish with this change?
|
||||||
|
|
||||||
|
1. **Cutting-edge technologies** - Not only did I want to play with the latest tools, I wanted to become proficient with them by putting them into production.
|
||||||
|
2. **Reproducibility** - Use infrastructure-as-code tooling so I could spin up the whole stack and tear it back down with only a few commands.
|
||||||
|
3. **Reliability** - Whatever combination of hardware and technologies I ended up with, it needed to be absolutely rock-solid. The only reason this thing should break is if I tell it to (intentionally or not)
|
||||||
|
|
||||||
|
# Hosting provider
|
||||||
|
|
||||||
|
I chose DigitalOcean back in 2016 mainly due to its excellent guides and popularity around the Jupiter Broadcasting community (got that sweet $100 promo code!). It was much easier to use than most other VPS providers and could have you up-and-running with an Ubuntu server and a public IP in minutes. In 2023, the VPS market is a bit more commoditized and there are some other great options out there. Linode initially came to mind, but their future became a bit murkier after they got acquired by Akamai in 2022, while hyperscalers like AWS and Azure are too expensive for this use-case. I eventually landed on [Hetzner Cloud](https://www.hetzner.com/cloud) for the following reasons:
|
||||||
|
|
||||||
|
- Incredible value - for roughly $5 USD per month you get 2 vCPUs and 2GB of ram with 20TB of monthly traffic. That's basically double the specs of competing offerings.
|
||||||
|
- Great reputation - Hetzner has been around for 20+ years and has lots of goodwill in the tech community for their frugal dedicated server offerings. I wouldn't have chose them initially since their Cloud product didn't have offerings in the U.S., but recently they've expanded to include VPSs in Virginia and Oregon.
|
||||||
|
- Full-featured Terraform provider - This isn't unique to Hetzner, but it was a requirement for my new setup and their provider works great.
|
||||||
|
|
||||||
|
### Why not self host?
|
||||||
|
|
||||||
|
While I have a reliable server at home and 300mbps uploads, it's never going to match the bandwidth and reach of a regional data center. This wouldn't matter to me for most things, but I treat my Nextcloud server as a full Dropbox replacement, and it needs to perform as such. On that same note, I feel comfort knowing that it's separated from the more experimental environment of my homelab.
|
||||||
|
|
||||||
|
# Linux Distribution
|
||||||
|
|
||||||
|
One of the great benefits of containerized applications is that the host operating system matters much less than it used to, and the choice mostly comes down to personal preference. As long as it can run your chosen container runtime and you're familiar with the tooling, your choice will probably work as well as any other.
|
||||||
|
|
||||||
|
I've been running Ubuntu on my servers for years due to ease-of-use and my familiarity with it on the desktop. However, I've recently been using Fedora on my home computers and have gotten accustomed to Red Hat / RPM quirks and tooling in recent years. For this reason, and the ease of getting the latest Podman release (more below), I ended up choosing [CentOS Stream 9](https://www.centos.org/centos-stream/).
|
||||||
|
|
||||||
|
# Docker vs. Podman
|
||||||
|
|
||||||
|
I've been using [Docker](https://www.docker.com/) to host a number of applications on my home server for the last few years with great success, and Docker is still far-and-away the most popular way to run individual containers. However, as the [OCI standard](https://opencontainers.org/) has become more widely adopted, other tools like [Podman](https://podman.io/) have started to appear. Podman, backed by Red Hat, offers near 1:1 command compatibility with Docker and has some lovely added benefits such as:
|
||||||
|
- Designed to run without root - Podman runs containers as a standard user, greatly reducing the risk to the server if one of the containers is compromised.
|
||||||
|
- No daemon required - On the same note, there isn't a continuously running daemon in the background with root access to your system. The risks of the Docker socket are [well-documented](https://docs.docker.com/engine/security/protect-access/), and this negates that risk entirely.
|
||||||
|
- Modern and lightweight - One of the benefits of not being first is that you can learn from everyone else's mistakes. Podman is built using lessons learned from Docker while creating an easy pathway to move from individual containers to full Kubernetes deployments.
|
||||||
|
|
||||||
|
Podman has been under rapid development recently, and there's a lot of excitement about it in Linux circles. While Docker would have worked just fine for my purposes, I decided to use this project as an opportunity to get familiar with Podman and see if it could potentially replace my other Docker-based applications.
|
||||||
|
|
||||||
|
# Deployment
|
||||||
|
|
||||||
|
Unlike my previous Nextcloud server which was like a zen garden that I tended carefully, I wanted my new server to be completely reproducible on a moment's notice. Using containers accomplishes part of this approach, but still leaves many parts of the server configuration to automate! Thankfully, there are a ton of tools available in 2023 to help with this.
|
||||||
|
|
||||||
|
## Terraform
|
||||||
|
|
||||||
|
To deploy the server itself, with associated volumes, firewall, etc, [Terraform](https://www.terraform.io/) was the obvious choice. While there are some competitors coming up like [Pulumi](https://www.pulumi.com/), Terraform is still the dominant player in the field and popularized the infrastructure-as-code concept. I had some experience using it at work, but I had never had the opportunity to build something from scratch with it. After reading the documentation for the [Hetzner Cloud provider](https://registry.terraform.io/providers/hetznercloud/hcloud/latest/docs), I was confident Terraform would be able to give me everything I needed.
|
||||||
|
|
||||||
|
## Ansible
|
||||||
|
|
||||||
|
Once the VPS is deployed and I have SSH access, Terraform's job stops. This is where I would typically connect to the server and start installing packages, configuring the webserver, and doing all the other server setup tasks I've done a thousand times over the years. If only there was a tool that could do all these steps for me while simultaneously documenting the entire setup!
|
||||||
|
|
||||||
|
Enter [Ansible](https://www.ansible.com/). Anything you could possibly think to do on a Linux box, Ansible can do for you. Think of it like a human-readable Bash script that handles all the rough edges for you. While writing the playbooks takes some work, once you have them written, you can run them again and again and expect (mostly) the same results each time. I chose Ansible due to it's stateless, agent-less architecture and the ability to run it from any computer with SSH access to the target hosts. Like Terraform, I love that the entire configuration is text-based and easily managed with Git.
|
||||||
|
|
||||||
|
# What's next?
|
||||||
|
|
||||||
|
This post talked about the ideas and goals I had going into this project, and in Part 2 I'll talk about the details of the implementation, and how sometimes things seem a lot easier in a blog post than they turn out to be in reality! If you're interested in the nitty-gritty of how these tools work for a project like this, stay tuned for the next post in the series.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -270,7 +270,7 @@ body:hover .visually-hidden button {
|
|||||||
|
|
||||||
.fa-mastodon,
|
.fa-mastodon,
|
||||||
.fa-mastodon-square {
|
.fa-mastodon-square {
|
||||||
color: $mastodon-color;
|
color: #000;
|
||||||
}
|
}
|
||||||
|
|
||||||
.fa-pinterest,
|
.fa-pinterest,
|
||||||
|
|||||||
BIN
assets/images/screenshots/kalendar01.png
Normal file
BIN
assets/images/screenshots/kalendar01.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 92 KiB |
BIN
assets/images/screenshots/nextcloud-photos-01.jpg
Normal file
BIN
assets/images/screenshots/nextcloud-photos-01.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 34 KiB |
BIN
assets/images/screenshots/nextcloud-photos-hero.png
Normal file
BIN
assets/images/screenshots/nextcloud-photos-hero.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 530 KiB |
BIN
favicon.ico
BIN
favicon.ico
Binary file not shown.
|
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 31 KiB |
Reference in New Issue
Block a user