A place to cache linked articles (think custom and personal wayback machine)
Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.

index.html 21KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412
  1. <!doctype html><!-- This is a valid HTML5 document. -->
  2. <!-- Screen readers, SEO, extensions and so on. -->
  3. <html lang="fr">
  4. <!-- Has to be within the first 1024 bytes, hence before the <title>
  5. See: https://www.w3.org/TR/2012/CR-html5-20121217/document-metadata.html#charset -->
  6. <meta charset="utf-8">
  7. <!-- Why no `X-UA-Compatible` meta: https://stackoverflow.com/a/6771584 -->
  8. <!-- The viewport meta is quite crowded and we are responsible for that.
  9. See: https://codepen.io/tigt/post/meta-viewport-for-2015 -->
  10. <meta name="viewport" content="width=device-width,initial-scale=1">
  11. <!-- Required to make a valid HTML5 document. -->
  12. <title>Computers as I used to love them (archive) — David Larlet</title>
  13. <meta name="description" content="Publication mise en cache pour en conserver une trace.">
  14. <!-- That good ol' feed, subscribe :). -->
  15. <link rel="alternate" type="application/atom+xml" title="Feed" href="/david/log/">
  16. <!-- Generated from https://realfavicongenerator.net/ such a mess. -->
  17. <link rel="apple-touch-icon" sizes="180x180" href="/static/david/icons2/apple-touch-icon.png">
  18. <link rel="icon" type="image/png" sizes="32x32" href="/static/david/icons2/favicon-32x32.png">
  19. <link rel="icon" type="image/png" sizes="16x16" href="/static/david/icons2/favicon-16x16.png">
  20. <link rel="manifest" href="/static/david/icons2/site.webmanifest">
  21. <link rel="mask-icon" href="/static/david/icons2/safari-pinned-tab.svg" color="#07486c">
  22. <link rel="shortcut icon" href="/static/david/icons2/favicon.ico">
  23. <meta name="msapplication-TileColor" content="#f0f0ea">
  24. <meta name="msapplication-config" content="/static/david/icons2/browserconfig.xml">
  25. <meta name="theme-color" content="#f0f0ea">
  26. <!-- Documented, feel free to shoot an email. -->
  27. <link rel="stylesheet" href="/static/david/css/style_2020-06-19.css">
  28. <!-- See https://www.zachleat.com/web/comprehensive-webfonts/ for the trade-off. -->
  29. <link rel="preload" href="/static/david/css/fonts/triplicate_t4_poly_regular.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: light), (prefers-color-scheme: no-preference)" crossorigin>
  30. <link rel="preload" href="/static/david/css/fonts/triplicate_t4_poly_bold.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: light), (prefers-color-scheme: no-preference)" crossorigin>
  31. <link rel="preload" href="/static/david/css/fonts/triplicate_t4_poly_italic.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: light), (prefers-color-scheme: no-preference)" crossorigin>
  32. <link rel="preload" href="/static/david/css/fonts/triplicate_t3_regular.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: dark)" crossorigin>
  33. <link rel="preload" href="/static/david/css/fonts/triplicate_t3_bold.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: dark)" crossorigin>
  34. <link rel="preload" href="/static/david/css/fonts/triplicate_t3_italic.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: dark)" crossorigin>
  35. <script type="text/javascript">
  36. function toggleTheme(themeName) {
  37. document.documentElement.classList.toggle(
  38. 'forced-dark',
  39. themeName === 'dark'
  40. )
  41. document.documentElement.classList.toggle(
  42. 'forced-light',
  43. themeName === 'light'
  44. )
  45. }
  46. const selectedTheme = localStorage.getItem('theme')
  47. if (selectedTheme !== 'undefined') {
  48. toggleTheme(selectedTheme)
  49. }
  50. </script>
  51. <meta name="robots" content="noindex, nofollow">
  52. <meta content="origin-when-cross-origin" name="referrer">
  53. <!-- Canonical URL for SEO purposes -->
  54. <link rel="canonical" href="https://tonsky.me/blog/syncthing/">
  55. <body class="remarkdown h1-underline h2-underline h3-underline hr-center ul-star pre-tick">
  56. <article>
  57. <header>
  58. <h1>Computers as I used to love them</h1>
  59. </header>
  60. <nav>
  61. <p class="center">
  62. <a href="/david/" title="Aller à l’accueil">🏠</a> •
  63. <a href="https://tonsky.me/blog/syncthing/" title="Lien vers le contenu original">Source originale</a>
  64. </p>
  65. </nav>
  66. <hr>
  67. <main>
  68. <p>I’ve been struggling with file sync solutions <a href="https://tonsky.livejournal.com/323469.html">for years</a>. In the beginning, Dropbox was great, but in the last few years, they started to bloat up. I moved to iCloud, but it was even worse. Finally, a few days ago, after iCloud <a href="https://twitter.com/nikitonsky/status/1269741673715810304">cryptically broke again</a>, I decided it’s time to try something different.</p>
  69. <p>I tried <a href="https://syncthing.net/">Syncthing</a>, a free and open-source alternative. And you know what? It’s been liberating. The sanity, the simplicity, the reliability, the features. It brings the joy of use and makes you believe <a href="https://tonsky.me/blog/good-times-weak-men/">the collapse of civilization</a> can be slowed down a bit.</p>
  70. <p><em>Syncthing is everything I used to love about computers.</em></p>
  71. <p>It’s amazing how great computer products can be when they don’t need to deal with corporate bullshit, don’t have to promote a brand or to sell its users. Frankly, I almost ceased to believe it’s still possible. But it is.</p>
  72. <h1 id="installation">Installation</h1>
  73. <p>You download a single binary executable. You run it. There’s no step three.</p>
  74. <figure>
  75. <img src="https://tonsky.me/blog/syncthing/cli.png" />
  76. </figure>
  77. <p>No, seriously. It’s so simple I thought I missed something. But no. After you run that binary, you have a fully operational node of Syncthing. It’s ready to sync with any other Syncthing node, no other setup necessary. There’s no installers, no package management (but there are packages if you want to), no registration, no email, no logins, no password creation, no 2FA, no consents, no user agreements. Just download and run. Heck, setting up autostart on Linux server was more complex than just running the app itself!</p>
  78. <p>Homebrew makes it even simpler:</p>
  79. <figure>
  80. <img src="https://tonsky.me/blog/syncthing/homebrew.png" />
  81. </figure>
  82. <p>Just to give you the perspective, these are all the steps that Dropbox puts you through when you install it on a new computer:</p>
  83. <figure>
  84. <img src="https://tonsky.me/blog/syncthing/dropbox_1.png" />
  85. </figure>
  86. <figure>
  87. <img src="https://tonsky.me/blog/syncthing/dropbox_2.png" />
  88. </figure>
  89. <figure>
  90. <img src="https://tonsky.me/blog/syncthing/dropbox_3.png" />
  91. </figure>
  92. <figure>
  93. <img src="https://tonsky.me/blog/syncthing/dropbox_4.png" />
  94. </figure>
  95. <figure>
  96. <img src="https://tonsky.me/blog/syncthing/dropbox_5.png" />
  97. </figure>
  98. <figure>
  99. <img src="https://tonsky.me/blog/syncthing/dropbox_6.png" />
  100. </figure>
  101. <figure>
  102. <img src="https://tonsky.me/blog/syncthing/dropbox_7.png" />
  103. </figure>
  104. <figure>
  105. <img src="https://tonsky.me/blog/syncthing/dropbox_8.png" />
  106. </figure>
  107. <figure>
  108. <img src="https://tonsky.me/blog/syncthing/dropbox_9.png" />
  109. </figure>
  110. <figure>
  111. <img src="https://tonsky.me/blog/syncthing/dropbox_10.png" />
  112. </figure>
  113. <figure>
  114. <img src="https://tonsky.me/blog/syncthing/dropbox_11.png" />
  115. </figure>
  116. <p>Aaaaand… that’s not all! You also get this annoying notificaiton to deal with:</p>
  117. <figure>
  118. <img src="https://tonsky.me/blog/syncthing/dropbox_12.png" />
  119. </figure>
  120. <p>Only at this point can you start using Dropbox. Luckily, I already had an account, otherwise, it would be 5 more steps. Ridiculous!</p>
  121. <p>(It goes without saying, that all of these are different windows. It does not happen in a single predictable area, mind you. You have to chase every one of them. And the “Set Up Dropbox” window is always-on-top, so it hides other required steps, which also adds to the fun.)</p>
  122. <h1 id="no-artificial-limits">No artificial limits</h1>
  123. <p>Because Synthing is free and doesn’t depend on server-side storage, they don’t need to put weird or unnatural restrictions on you. You can use as much space as you have on disk. You can sync as many folders as you want. You can sync any folder, no matter where it’s located. You can sync with anyone in the world. In fact, you can sync any folder with any number of people. At no point have you to wonder “but will it work with my plan”? If your hardware allows it, it will work. As simple as that.</p>
  124. <p>Folders are the most vivid example of how other cloud storages constantly fuck up the simplest things. Syncthing can sync any folder on your drive, located anywhere. You can sync existing folders. You can sync multiple different folders. <em>Folders are just folders</em>, nothing special about them. Here I’m syncing “system” folders: <code class="language-plaintext highlighter-rouge">~/Desktop</code> and <code class="language-plaintext highlighter-rouge">~/Library/Fonts</code>, and three custom ones. No sweat:</p>
  125. <figure>
  126. <img src="https://tonsky.me/blog/syncthing/folders.png" />
  127. </figure>
  128. <p>This simplicity lets you use it as a tool you can apply, sometimes creatively, to your task, not as a service you have to put up with. For example, by syncing <code class="language-plaintext highlighter-rouge">~/Library/Fonts</code>, if I install a font on one machine, it automatically installs everywhere.</p>
  129. <p>Contrast this with Dropbox, which requires you to put everything inside <code class="language-plaintext highlighter-rouge">~/Dropbox</code> folder. If you keep your projects under <code class="language-plaintext highlighter-rouge">~/work</code> and want to sync it, well, tough luck. You can’t sync multiple folders either. Well, technically Dropbox can sync anything, of course. Files are files. But branding dictates there MUST be a Dropbox folder somewhere, even if it’s inconvenient for the user.</p>
  130. <figure>
  131. <img src="https://tonsky.me/blog/syncthing/dropbox_folder.png" />
  132. Sweet, sweet branding...
  133. </figure>
  134. <p>But the worst offender is the iCloud. Same as Dropbox, it also requires you to put all your stuff into a folder. But that folder is called <code class="language-plaintext highlighter-rouge">~/Library/Mobile Documents/com~apple~CloudDocs</code>!!!</p>
  135. <p>If you are a programmer, it’s unusable. First, you can’t in your right mind type THAT every time you need to <code class="language-plaintext highlighter-rouge">cd</code>. Second, it contains spaces! Which breaks all sorts of things, believe me or not, even in 2020. I can’t keep Fira Code in iCloud because of python scripts, I can’t keep Jekyll blog like this one there because of Ruby, I can’t run bazel, etc. Useless.</p>
  136. <figure>
  137. <img src="https://tonsky.me/blog/syncthing/jekyll.png" />
  138. </figure>
  139. <p>And if you think symlinking it to <code class="language-plaintext highlighter-rouge">~/icloud</code> helps, believe me, it does not.</p>
  140. <figure>
  141. <img src="https://tonsky.me/blog/syncthing/absolute_path.png" />
  142. </figure>
  143. <h1 id="no-registration">No registration</h1>
  144. <p>How do you connect two devices, if there’s no registration, accounts, email, etc? Simple! Each device has a unique id, generated automatically when you first run the program. Share this id with another device, let them share their, and you are good to go.</p>
  145. <figure>
  146. <img src="https://tonsky.me/blog/syncthing/id.png" />
  147. </figure>
  148. <p>Best news? Those ids are not even secret. They are more like public keys, so you can exchange them freely. But the scheme only works if both devices know ids of each other.</p>
  149. <p>What I like about this scheme is how beautifully simple and down-to-absolute-essentials it is. This is pure mathematics. But it’s also very convenient to use. There’re no emails, no forms, no unresponsive web pages, no invites, no expiring tokens, no failing/outdated/overloaded APIs, no password management, nothing to hold onto or “manage”.</p>
  150. <h1 id="power-mode">Power mode</h1>
  151. <p>There’s power user mode! If you don’t care, there’s always a UI, and most of the things you can configure there. But if you’re a programmer and need more, you can:</p>
  152. <ul>
  153. <li>Install Synthing on a headless Linux server,</li>
  154. <li>Control it by editing XML config,</li>
  155. <li>Control it via REST API,</li>
  156. <li>Configure folder ignores via regular expressions.</li>
  157. </ul>
  158. <p>All APIs and configs are well-documented:</p>
  159. <figure>
  160. <img src="https://tonsky.me/blog/syncthing/api.png" />
  161. </figure>
  162. <p>For example, this is my <code class="language-plaintext highlighter-rouge">.stignore</code> for workspace folder:</p>
  163. <figure>
  164. <img src="https://tonsky.me/blog/syncthing/stignore.png" />
  165. </figure>
  166. <p>Configure it once and forget about generated classes, vendored dependencies and other caches syncing unnecessary forever.</p>
  167. <p>In contrast, iCloud has a feature to exclude <code class="language-plaintext highlighter-rouge">*.nosync</code> files from syncing, but you know what? I usually don’t have files called <code class="language-plaintext highlighter-rouge">*.nosync</code>, that’s the problem:</p>
  168. <figure>
  169. <img src="https://tonsky.me/blog/syncthing/icloud_exclude.png" />
  170. </figure>
  171. <p>And Dropbox? Well… I still have nightmares about this Dropbox UI:</p>
  172. <figure>
  173. <img src="https://tonsky.me/blog/syncthing/dropbox_folders.png" />
  174. </figure>
  175. <p>It’s kind of funny, how commercial apps have feature bloat but don’t have power mode. You can do more different things, but can’t configure them to your liking.</p>
  176. <h1 id="no-upsell">No upsell</h1>
  177. <p>Commercial solutions are interested in keeping users locked in and constantly upselling more features to them. As a result of that, you get notifications, features, popups. For example, on this screenshot, after I <em>just</em> installed Dropbox on a fresh machine:</p>
  178. <figure>
  179. <img src="https://tonsky.me/blog/syncthing/dropbox_12.png" />
  180. </figure>
  181. <p>Top to bottom:</p>
  182. <ul>
  183. <li>I already have an annoying red dot in the menubar,</li>
  184. <li>Link to another product (Paper), even though it has nothing to do with file synchronization,</li>
  185. <li>A firm suggestion I should enable notifications,</li>
  186. <li>A notification that says my Desktop app is ready for use?! I mean, I’m looking at it from the desktop app!</li>
  187. <li>Dropbox advertising some sort of trial,</li>
  188. <li>Dropbox selling me more space (even though it was 2 years ago and I have &gt;50% free),</li>
  189. <li>Large “Upgrade” button,</li>
  190. </ul>
  191. <p>In the mystic “For you” tab:</p>
  192. <figure>
  193. <img src="https://tonsky.me/blog/syncthing/dropbox_for_you.png" />
  194. </figure>
  195. <p>we see:</p>
  196. <ul>
  197. <li>Starred items? What is it, a high-school notepad? If I really wanted, I could tag files in the OS, but thank you.</li>
  198. <li>Calendar sync? Why on Earth would FILE SYNCHRONIZATION application wants to access my calendar?</li>
  199. </ul>
  200. <p>Wait, there’s more:</p>
  201. <figure>
  202. <img src="https://tonsky.me/blog/syncthing/dropbox_settings.png" />
  203. </figure>
  204. <p>More “features”:</p>
  205. <ul>
  206. <li>Desktop sync,</li>
  207. <li>Photos sync,</li>
  208. <li>Screenshots sync.</li>
  209. </ul>
  210. <p>These are at least file-like? I don’t understand why they have to be “special features”, though, if you already have an app whose primary task is to sync files. It already does that. Why are some files more special than others?</p>
  211. <p>The answer is simple: the only way Dropbox can survive is by building and selling more features. You’ll never have peace of mind with them.</p>
  212. <p>iCloud is much younger and doesn’t have feature bloat yet, but they are still interested in selling more Macs and iPhones. So they will always try to isolate you from the rest of the world. Expect weird restrictions and great inconveniences, like iCloud folder location or moving Desktop folder when you enable/disable sync for it.</p>
  213. <p>Syncthing survival, on the other hand, does not depend on making more features. They do one thing, but they do it well. Look, their menu<a id="f1" href="#fn1" class="footnote">1</a> looks exactly how Dropbox used to look when it still was good in 2012:</p>
  214. <figure>
  215. <img src="https://tonsky.me/blog/syncthing/menubar.png" />
  216. </figure>
  217. <h1 id="no-lock-in">No lock-in</h1>
  218. <p>Another ugly thing both iCloud and Dropbox routinely do is trying to scare you from walking away. Those appear every time you move more than one file outside of iCloud folder:</p>
  219. <figure>
  220. <img src="https://tonsky.me/blog/syncthing/icloud_scare_1.png" />
  221. </figure>
  222. <figure>
  223. <img src="https://tonsky.me/blog/syncthing/icloud_scare_2.png" />
  224. </figure>
  225. <p>And those are Dropbox versions:</p>
  226. <figure>
  227. <img src="https://tonsky.me/blog/syncthing/dropbox_scare_1.png" />
  228. </figure>
  229. <figure>
  230. <img src="https://tonsky.me/blog/syncthing/dropbox_scare_2.png" />
  231. </figure>
  232. <p>It might seem like they try to explain something, but they do not. They are scared you might be leaving and try to scare you back. The tactic is simple: question your every action, even trivial operations like moving or deleting files, display huge warning signs even for safe operations, long puzzling wording (“<a href="https://grumpy.website/post/0Ts_fkPQb">documents stored in iCloud will be removed from Mac</a>”) so that you never sure what will happen. That’s some shady shit.</p>
  233. <figure>
  234. <img src="https://tonsky.me/blog/syncthing/scared.png" />
  235. </figure>
  236. <p>Syncthing, on the other hand, simply doesn’t care. They don’t get any money from you, so they are not interested in creating a need or constantly reminding about themselves. If you are looking for peace of mind, you can’t have it with commercial offerings.</p>
  237. <h1 id="conclusion">Conclusion</h1>
  238. <p>Syncthing has reminded me how great computers can be if they are not made by corporations. It’s simple, predictable, sane, acts no-nonsense. You can configure it however you like and it always keeps you in control. It’s a pure function and it’s good at that. It’s free and open-source, but I’m much more happy to donate them €10/month than e.g. Dropbox. I would be a much happier person if at least half of the programs on my Mac/iPhone were like that.</p>
  239. </main>
  240. </article>
  241. <hr>
  242. <footer>
  243. <p>
  244. <a href="/david/" title="Aller à l’accueil">🏠</a> •
  245. <a href="/david/log/" title="Accès au flux RSS">🤖</a> •
  246. <a href="http://larlet.com" title="Go to my English profile" data-instant>🇨🇦</a> •
  247. <a href="mailto:david%40larlet.fr" title="Envoyer un courriel">📮</a> •
  248. <abbr title="Hébergeur : Alwaysdata, 62 rue Tiquetonne 75002 Paris, +33184162340">🧚</abbr>
  249. </p>
  250. <template id="theme-selector">
  251. <form>
  252. <fieldset>
  253. <legend>Thème</legend>
  254. <label>
  255. <input type="radio" value="auto" name="chosen-color-scheme" checked> Auto
  256. </label>
  257. <label>
  258. <input type="radio" value="dark" name="chosen-color-scheme"> Foncé
  259. </label>
  260. <label>
  261. <input type="radio" value="light" name="chosen-color-scheme"> Clair
  262. </label>
  263. </fieldset>
  264. </form>
  265. </template>
  266. </footer>
  267. <script type="text/javascript">
  268. function loadThemeForm(templateName) {
  269. const themeSelectorTemplate = document.querySelector(templateName)
  270. const form = themeSelectorTemplate.content.firstElementChild
  271. themeSelectorTemplate.replaceWith(form)
  272. form.addEventListener('change', (e) => {
  273. const chosenColorScheme = e.target.value
  274. localStorage.setItem('theme', chosenColorScheme)
  275. toggleTheme(chosenColorScheme)
  276. })
  277. const selectedTheme = localStorage.getItem('theme')
  278. if (selectedTheme && selectedTheme !== 'undefined') {
  279. form.querySelector(`[value="${selectedTheme}"]`).checked = true
  280. }
  281. }
  282. const prefersColorSchemeDark = '(prefers-color-scheme: dark)'
  283. window.addEventListener('load', () => {
  284. let hasDarkRules = false
  285. for (const styleSheet of Array.from(document.styleSheets)) {
  286. let mediaRules = []
  287. for (const cssRule of styleSheet.cssRules) {
  288. if (cssRule.type !== CSSRule.MEDIA_RULE) {
  289. continue
  290. }
  291. // WARNING: Safari does not have/supports `conditionText`.
  292. if (cssRule.conditionText) {
  293. if (cssRule.conditionText !== prefersColorSchemeDark) {
  294. continue
  295. }
  296. } else {
  297. if (cssRule.cssText.startsWith(prefersColorSchemeDark)) {
  298. continue
  299. }
  300. }
  301. mediaRules = mediaRules.concat(Array.from(cssRule.cssRules))
  302. }
  303. // WARNING: do not try to insert a Rule to a styleSheet you are
  304. // currently iterating on, otherwise the browser will be stuck
  305. // in a infinite loop…
  306. for (const mediaRule of mediaRules) {
  307. styleSheet.insertRule(mediaRule.cssText)
  308. hasDarkRules = true
  309. }
  310. }
  311. if (hasDarkRules) {
  312. loadThemeForm('#theme-selector')
  313. }
  314. })
  315. </script>
  316. </body>
  317. </html>