<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki.jon.geek.nz/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Johnno</id>
	<title>Jon&#039;s Wiki - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.jon.geek.nz/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Johnno"/>
	<link rel="alternate" type="text/html" href="https://wiki.jon.geek.nz/Special:Contributions/Johnno"/>
	<updated>2026-04-28T09:27:04Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.35.7</generator>
	<entry>
		<id>https://wiki.jon.geek.nz/index.php?title=MacOS&amp;diff=2524</id>
		<title>MacOS</title>
		<link rel="alternate" type="text/html" href="https://wiki.jon.geek.nz/index.php?title=MacOS&amp;diff=2524"/>
		<updated>2026-02-26T11:05:46Z</updated>

		<summary type="html">&lt;p&gt;Johnno: /* Compose Key */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Compose Key ==&lt;br /&gt;
&lt;br /&gt;
# Install [https://karabiner-elements.pqrs.org/ Karabiner-Elements], e.g. with brew install.&lt;br /&gt;
# Fetch the large but comprehensive &amp;lt;code&amp;gt;DefaultKeyBinding.dict&amp;lt;/code&amp;gt; file from GitHub, [https://github.com/cmloegcmluin/compose2keybindings here]. This has all the X11 compose key mappings in it, plus a bunch of other nifty combinations.&lt;br /&gt;
#. Copy it into the &amp;lt;code&amp;gt;~/Library/KeyBindings&amp;lt;/code&amp;gt; directory. You may have to create the directory first.&lt;br /&gt;
# In Karabiner-Elements under &amp;#039;&amp;#039;Settings → Simple Modifications&amp;#039;&amp;#039;, add the following remapping rules for any USB keyboards:&lt;br /&gt;
#* left_command → left_alt&lt;br /&gt;
#* left_alt → left_command&lt;br /&gt;
#* right_alt → right_command&lt;br /&gt;
# In &amp;#039;&amp;#039;Settings → Complex Modifications&amp;#039;&amp;#039;, Add the rule to rewrite the Right Command key (now mapped as Right Alt on USB keyboards) to Shift + Ctrl + F13. This rule should look like this: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot;&amp;gt;&lt;br /&gt;
 {&lt;br /&gt;
   &amp;quot;description&amp;quot;: &amp;quot;Send Shift + Ctrl + F13 on Right Command to emulate Compose Key&amp;quot;,&lt;br /&gt;
   &amp;quot;manipulators&amp;quot;: [&lt;br /&gt;
     {&lt;br /&gt;
       &amp;quot;from&amp;quot;: { &amp;quot;key_code&amp;quot;: &amp;quot;right_gui&amp;quot; },&lt;br /&gt;
       &amp;quot;to&amp;quot;: [&lt;br /&gt;
         {&lt;br /&gt;
           &amp;quot;key_code&amp;quot;: &amp;quot;f13&amp;quot;,&lt;br /&gt;
           &amp;quot;modifiers&amp;quot;: [&amp;quot;left_control&amp;quot;, &amp;quot;left_shift&amp;quot;],&lt;br /&gt;
           &amp;quot;repeat&amp;quot;: false&lt;br /&gt;
         }&lt;br /&gt;
       ],&lt;br /&gt;
       &amp;quot;type&amp;quot;: &amp;quot;basic&amp;quot;&lt;br /&gt;
     }&lt;br /&gt;
   ]&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# Possibly restart apps if they don’t immediately pick up changes.&lt;br /&gt;
&lt;br /&gt;
=== References ===&lt;br /&gt;
&lt;br /&gt;
# Goller, A (16 August 2022). [https://www.alexandergoller.com/journal/14210/compose-key-on-macos/ “Compose Key on MacOS”] (blog post), alexandergoller.com&lt;br /&gt;
# [https://genesy.github.io/karabiner-complex-rules-generator/#eyJ0aXRsZSI6IlJpZ2h0IENvbW1hbmQgdG8gU2hpZnQgKyBDdHJsICsgZjEzIiwicnVsZXMiOlt7ImRlc2NyaXB0aW9uIjoiU2VuZCBTaGlmdCArIEN0cmwgKyBmMTMgb24gUmlnaHQgQ29tbWFuZCB0byBlbXVsYXRlIENvbXBvc2UgS2V5IChodHRwOi8vbG9sZW5naW5lLm5ldC9ibG9nLzIwMTIvMDYvMTcvY29tcG9zZS1rZXktb24tb3MteCkiLCJtYW5pcHVsYXRvcnMiOlt7InR5cGUiOiJiYXNpYyIsImZyb20iOnsia2V5X2NvZGUiOiJyaWdodF9ndWkifSwidG8iOlt7InJlcGVhdCI6ZmFsc2UsImtleV9jb2RlIjoiZjEzIiwibW9kaWZpZXJzIjpbImxlZnRfY29udHJvbCIsImxlZnRfc2hpZnQiXX1dfV19XX0= “Send Shift + Ctrl + F13 on Right Command to emulate Compose Key”], Gene Sy:Karabiner Complex Rules Generator, via GitHub.&lt;br /&gt;
# Hocevar, Sam (17 June 2012). [https://web.archive.org/web/20211020080809/https://lolengine.net/blog/2012/06/17/compose-key-on-os-x “Setting up a real Compose key on Mac OS X”] (blog post), The Lol Engine &amp;#039;&amp;#039;(dead link; archived 20 October 2021 by The Internet Archive)&amp;#039;&amp;#039;.&lt;/div&gt;</summary>
		<author><name>Johnno</name></author>
	</entry>
	<entry>
		<id>https://wiki.jon.geek.nz/index.php?title=MacOS&amp;diff=2523</id>
		<title>MacOS</title>
		<link rel="alternate" type="text/html" href="https://wiki.jon.geek.nz/index.php?title=MacOS&amp;diff=2523"/>
		<updated>2026-02-26T06:22:29Z</updated>

		<summary type="html">&lt;p&gt;Johnno: /* References */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Compose Key ==&lt;br /&gt;
&lt;br /&gt;
# Install [https://karabiner-elements.pqrs.org/ Karabiner-Elements], e.g. with brew install.&lt;br /&gt;
# Fetch the large but comprehensive &amp;lt;code&amp;gt;DefaultKeyBinding.dict&amp;lt;/code&amp;gt; file from GitHub, [https://github.com/cmloegcmluin/compose2keybindings here]. This has all the X11 compose key mappings in it, plus a bunch of other nifty combinations.&lt;br /&gt;
#. Copy it into the &amp;lt;code&amp;gt;~/Library/KeyBindings&amp;lt;/code&amp;gt; directory. You may have to create the directory first.&lt;br /&gt;
# In Karabiner-Elements under &amp;#039;&amp;#039;Settings → Simple Modifications&amp;#039;&amp;#039;, add the following remapping rules for any USB keyboards:&lt;br /&gt;
#* left_command → left_alt&lt;br /&gt;
#* left_alt → left_command&lt;br /&gt;
#* right_alt → right_command&lt;br /&gt;
# In &amp;#039;&amp;#039;Settings → Complex Modifications&amp;#039;&amp;#039;, Add the rule to rewrite the Right Command key (now mapped as Right Alt on USB keyboards) to Shift + Ctrl + F13. This rule should look like this:&lt;br /&gt;
&lt;br /&gt;
 {&lt;br /&gt;
   &amp;quot;description&amp;quot;: &amp;quot;Send Shift + Ctrl + F13 on Right Command to emulate Compose Key&amp;quot;,&lt;br /&gt;
   &amp;quot;manipulators&amp;quot;: [&lt;br /&gt;
     {&lt;br /&gt;
       &amp;quot;from&amp;quot;: { &amp;quot;key_code&amp;quot;: &amp;quot;right_gui&amp;quot; },&lt;br /&gt;
       &amp;quot;to&amp;quot;: [&lt;br /&gt;
         {&lt;br /&gt;
           &amp;quot;key_code&amp;quot;: &amp;quot;f13&amp;quot;,&lt;br /&gt;
           &amp;quot;modifiers&amp;quot;: [&amp;quot;left_control&amp;quot;, &amp;quot;left_shift&amp;quot;],&lt;br /&gt;
           &amp;quot;repeat&amp;quot;: false&lt;br /&gt;
         }&lt;br /&gt;
       ],&lt;br /&gt;
       &amp;quot;type&amp;quot;: &amp;quot;basic&amp;quot;&lt;br /&gt;
     }&lt;br /&gt;
   ]&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
# Possibly restart apps if they don’t immediately pick up changes.&lt;br /&gt;
&lt;br /&gt;
=== References ===&lt;br /&gt;
&lt;br /&gt;
# Goller, A (16 August 2022). [https://www.alexandergoller.com/journal/14210/compose-key-on-macos/ “Compose Key on MacOS”] (blog post), alexandergoller.com&lt;br /&gt;
# [https://genesy.github.io/karabiner-complex-rules-generator/#eyJ0aXRsZSI6IlJpZ2h0IENvbW1hbmQgdG8gU2hpZnQgKyBDdHJsICsgZjEzIiwicnVsZXMiOlt7ImRlc2NyaXB0aW9uIjoiU2VuZCBTaGlmdCArIEN0cmwgKyBmMTMgb24gUmlnaHQgQ29tbWFuZCB0byBlbXVsYXRlIENvbXBvc2UgS2V5IChodHRwOi8vbG9sZW5naW5lLm5ldC9ibG9nLzIwMTIvMDYvMTcvY29tcG9zZS1rZXktb24tb3MteCkiLCJtYW5pcHVsYXRvcnMiOlt7InR5cGUiOiJiYXNpYyIsImZyb20iOnsia2V5X2NvZGUiOiJyaWdodF9ndWkifSwidG8iOlt7InJlcGVhdCI6ZmFsc2UsImtleV9jb2RlIjoiZjEzIiwibW9kaWZpZXJzIjpbImxlZnRfY29udHJvbCIsImxlZnRfc2hpZnQiXX1dfV19XX0= “Send Shift + Ctrl + F13 on Right Command to emulate Compose Key”], Gene Sy:Karabiner Complex Rules Generator, via GitHub.&lt;br /&gt;
# Hocevar, Sam (17 June 2012). [https://web.archive.org/web/20211020080809/https://lolengine.net/blog/2012/06/17/compose-key-on-os-x “Setting up a real Compose key on Mac OS X”] (blog post), The Lol Engine &amp;#039;&amp;#039;(dead link; archived 20 October 2021 by The Internet Archive)&amp;#039;&amp;#039;.&lt;/div&gt;</summary>
		<author><name>Johnno</name></author>
	</entry>
	<entry>
		<id>https://wiki.jon.geek.nz/index.php?title=MacOS&amp;diff=2522</id>
		<title>MacOS</title>
		<link rel="alternate" type="text/html" href="https://wiki.jon.geek.nz/index.php?title=MacOS&amp;diff=2522"/>
		<updated>2026-02-26T06:20:27Z</updated>

		<summary type="html">&lt;p&gt;Johnno: Created page with &amp;quot;== Compose Key ==  # Install [https://karabiner-elements.pqrs.org/ Karabiner-Elements], e.g. with brew install. # Fetch the large but comprehensive &amp;lt;code&amp;gt;DefaultKeyBinding.dic...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Compose Key ==&lt;br /&gt;
&lt;br /&gt;
# Install [https://karabiner-elements.pqrs.org/ Karabiner-Elements], e.g. with brew install.&lt;br /&gt;
# Fetch the large but comprehensive &amp;lt;code&amp;gt;DefaultKeyBinding.dict&amp;lt;/code&amp;gt; file from GitHub, [https://github.com/cmloegcmluin/compose2keybindings here]. This has all the X11 compose key mappings in it, plus a bunch of other nifty combinations.&lt;br /&gt;
#. Copy it into the &amp;lt;code&amp;gt;~/Library/KeyBindings&amp;lt;/code&amp;gt; directory. You may have to create the directory first.&lt;br /&gt;
# In Karabiner-Elements under &amp;#039;&amp;#039;Settings → Simple Modifications&amp;#039;&amp;#039;, add the following remapping rules for any USB keyboards:&lt;br /&gt;
#* left_command → left_alt&lt;br /&gt;
#* left_alt → left_command&lt;br /&gt;
#* right_alt → right_command&lt;br /&gt;
# In &amp;#039;&amp;#039;Settings → Complex Modifications&amp;#039;&amp;#039;, Add the rule to rewrite the Right Command key (now mapped as Right Alt on USB keyboards) to Shift + Ctrl + F13. This rule should look like this:&lt;br /&gt;
&lt;br /&gt;
 {&lt;br /&gt;
   &amp;quot;description&amp;quot;: &amp;quot;Send Shift + Ctrl + F13 on Right Command to emulate Compose Key&amp;quot;,&lt;br /&gt;
   &amp;quot;manipulators&amp;quot;: [&lt;br /&gt;
     {&lt;br /&gt;
       &amp;quot;from&amp;quot;: { &amp;quot;key_code&amp;quot;: &amp;quot;right_gui&amp;quot; },&lt;br /&gt;
       &amp;quot;to&amp;quot;: [&lt;br /&gt;
         {&lt;br /&gt;
           &amp;quot;key_code&amp;quot;: &amp;quot;f13&amp;quot;,&lt;br /&gt;
           &amp;quot;modifiers&amp;quot;: [&amp;quot;left_control&amp;quot;, &amp;quot;left_shift&amp;quot;],&lt;br /&gt;
           &amp;quot;repeat&amp;quot;: false&lt;br /&gt;
         }&lt;br /&gt;
       ],&lt;br /&gt;
       &amp;quot;type&amp;quot;: &amp;quot;basic&amp;quot;&lt;br /&gt;
     }&lt;br /&gt;
   ]&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
# Possibly restart apps if they don’t immediately pick up changes.&lt;br /&gt;
&lt;br /&gt;
=== References ===&lt;br /&gt;
&lt;br /&gt;
# Goller, A (16 August 2022). [https://www.alexandergoller.com/journal/14210/compose-key-on-macos/ “Compose Key on MacOS”] (blog post), alexandergoller.com&lt;br /&gt;
# [https://genesy.github.io/karabiner-complex-rules-generator/#eyJ0aXRsZSI6IlJpZ2h0IENvbW1hbmQgdG8gU2hpZnQgKyBDdHJsICsgZjEzIiwicnVsZXMiOlt7ImRlc2NyaXB0aW9uIjoiU2VuZCBTaGlmdCArIEN0cmwgKyBmMTMgb24gUmlnaHQgQ29tbWFuZCB0byBlbXVsYXRlIENvbXBvc2UgS2V5IChodHRwOi8vbG9sZW5naW5lLm5ldC9ibG9nLzIwMTIvMDYvMTcvY29tcG9zZS1rZXktb24tb3MteCkiLCJtYW5pcHVsYXRvcnMiOlt7InR5cGUiOiJiYXNpYyIsImZyb20iOnsia2V5X2NvZGUiOiJyaWdodF9ndWkifSwidG8iOlt7InJlcGVhdCI6ZmFsc2UsImtleV9jb2RlIjoiZjEzIiwibW9kaWZpZXJzIjpbImxlZnRfY29udHJvbCIsImxlZnRfc2hpZnQiXX1dfV19XX0= “Send Shift + Ctrl + F13 on Right Command to emulate Compose Key”], Gene Sy:Karabiner Complex Rules Generator, via GitHub.&lt;br /&gt;
# However, Sam (17 June 2012). [https://web.archive.org/web/20211020080809/https://lolengine.net/blog/2012/06/17/compose-key-on-os-x “Setting up a real Compose key on Mac OS X”] (blog post), The Lol Engine &amp;#039;&amp;#039;(dead link; archived 20 October 2021 by The Internet Archive)&amp;#039;&amp;#039;.&lt;/div&gt;</summary>
		<author><name>Johnno</name></author>
	</entry>
	<entry>
		<id>https://wiki.jon.geek.nz/index.php?title=Hacks&amp;diff=2521</id>
		<title>Hacks</title>
		<link rel="alternate" type="text/html" href="https://wiki.jon.geek.nz/index.php?title=Hacks&amp;diff=2521"/>
		<updated>2026-01-09T01:26:51Z</updated>

		<summary type="html">&lt;p&gt;Johnno: /* Using rsync with FAT volumes (USB sticks and SD cards) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Image renaming by create date ==&lt;br /&gt;
&lt;br /&gt;
When you have a bunch of files from your old Android phone with a timestamp filename (e.g. 1388042328550.jpg), you can rename them thus:&lt;br /&gt;
&lt;br /&gt;
 for f in 1*.jpg; do&lt;br /&gt;
   mv $f $(date +IMG_%Y%m%d_%H%M%S.jpg -d @$(echo $f|cut -c 1-10))&lt;br /&gt;
 done&lt;br /&gt;
&lt;br /&gt;
Otherwise, we can fish out the Create Date from the EXIF data, using exiftool:&lt;br /&gt;
&lt;br /&gt;
 exiftool &amp;#039;-FileName&amp;lt;CreateDate&amp;#039; -d %Y%m%d_%H%M%S%%-c.%%e .&lt;br /&gt;
&lt;br /&gt;
== Use etckeeper ==&lt;br /&gt;
&lt;br /&gt;
It saves your bacon. Store changes to the {{path|/etc}} directory in git, uses hooks to commit changes when packages are updated, puppet runs, etc. Stash your own changes with useful commit messages. Look up stuff in history when something goes wrong, figure out what changes happened when packages are added or updated.&lt;br /&gt;
&lt;br /&gt;
=== Fix the daily commit bug ===&lt;br /&gt;
&lt;br /&gt;
Unfortunately since about 18.04 there is a bug where a systemd timer and a cron.daily task compete to commit a daily commit if needed; unfortunately one of them doesn&amp;#039;t bother to check the {{path|etckeeper.conf}} file to see whether you&amp;#039;ve disabled it. If you have &amp;lt;code&amp;gt;DISABLE_DAILY_AUTOCOMMITS=1&amp;lt;/code&amp;gt; in your config file, then you probably don&amp;#039;t want daily auto commits. If this is so, run this to disable the systemd timer:&lt;br /&gt;
&lt;br /&gt;
 systemctl disable --now etckeeper.timer&lt;br /&gt;
&lt;br /&gt;
== Repair broken or rotated phone videos ==&lt;br /&gt;
&lt;br /&gt;
You can fix broken video .tmp files from your Android phone using [https://github.com/ponchio/untrunc/ untrunc]. This will create a fixed.mp4 file in cwd:&lt;br /&gt;
&lt;br /&gt;
 untrunc working_video_from_the_same_camera.mp4 broken.mk4.tmp&lt;br /&gt;
&lt;br /&gt;
Did your phone unhelpfully rotate your video? Fix the metadata:&lt;br /&gt;
&lt;br /&gt;
 ffmpeg -i original.mp4 -acodec copy -vcodec copy -metadata:s:v:0 rotate=0 unrotated.mp4&lt;br /&gt;
&lt;br /&gt;
Or, did you actually film your shit the wrong way up? You&amp;#039;ll need to re-encode it:&lt;br /&gt;
&lt;br /&gt;
 ffmpeg -i original.mp4 -acodec copy -vcodec libx264 -crf 20 -metadata:s:v:0 rotate=0 unrotated.mp4&lt;br /&gt;
&lt;br /&gt;
== Export your photos ==&lt;br /&gt;
&lt;br /&gt;
Before uploading your photos, remove all the EXIF tags, and reduce the resolution; nobody needs 5000x4000 pixels, much less corporations hoovering up your stuff to put in adverts.&lt;br /&gt;
&lt;br /&gt;
 mkdir tmp&lt;br /&gt;
 for f in $.jpg; do&lt;br /&gt;
   convert -resize 1600x1200 $f tmp/$f&lt;br /&gt;
   exiftool -all= -P -overwrite_original tmp/$f&lt;br /&gt;
 done&lt;br /&gt;
&lt;br /&gt;
== Clean out your revoked and expired PGP keys ==&lt;br /&gt;
&lt;br /&gt;
Spring-clean your gpg database, make it go faster. Just go:&lt;br /&gt;
&lt;br /&gt;
 gpg --delete-keys $(gpg --list-public-keys|grep -PB1 &amp;#039;expired|revoked&amp;#039;|grep &amp;#039;^\s&amp;#039;)&lt;br /&gt;
&lt;br /&gt;
Obviously. If you can&amp;#039;t be arsed confirming each key, add &amp;lt;tt&amp;gt;--batch --yes&amp;lt;/tt&amp;gt; to the first gpg call.&lt;br /&gt;
&lt;br /&gt;
== Firefox opening your shit in gedit ==&lt;br /&gt;
&lt;br /&gt;
I don&amp;#039;t know, who thought that was a good idea? Jesus.&lt;br /&gt;
&lt;br /&gt;
 sed -i &amp;#039;s#.*octet-stream.*#application/octet-stream=xdg-open#&amp;#039; ~/.local/share/applications/mimeapps.list ~/.config/mimeapps.list&lt;br /&gt;
&lt;br /&gt;
== GNOME not sorting your folders first ==&lt;br /&gt;
&lt;br /&gt;
It&amp;#039;s not in a dialog anywhere, and a pretty lame default behaviour.&lt;br /&gt;
 dconf write /org/gnome/nautilus/preferences/sort-directories-first true&lt;br /&gt;
&lt;br /&gt;
== GNOME not dealing with WebP images ==&lt;br /&gt;
&lt;br /&gt;
I mean, it&amp;#039;s 2021 and WebP is only what, ten years old? Jesus. See solution on [https://askubuntu.com/a/617068 AskUbuntu].&lt;br /&gt;
&lt;br /&gt;
== Restoring huge databases to PostgreSQL ==&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;See also:&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039; &amp;#039;&amp;#039;[[PostgreSQL]]&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Skip some huge tables by dumping the TOC, removing culprit large tables, and restore with the edited TOC, e.g.&lt;br /&gt;
&lt;br /&gt;
 pg_restore -l huge.dump &amp;gt; TOC&lt;br /&gt;
 # edit the TOC file...&lt;br /&gt;
 pg_restore -L TOC -d dbname huge.dump&lt;br /&gt;
&lt;br /&gt;
== Output PostgreSQL queries to CSV ==&lt;br /&gt;
&lt;br /&gt;
 COPY (SELECT &amp;lt;query&amp;gt; ...) TO STDOUT CSV HEADER;&lt;br /&gt;
&lt;br /&gt;
== Turn off the shitty default &amp;quot;visual&amp;quot; mouse mode in vim ==&lt;br /&gt;
&lt;br /&gt;
Add this to &amp;lt;code&amp;gt;/etc/vim/vimrc.local&amp;lt;/code&amp;gt; file:&amp;lt;ref&amp;gt;Böhnke, H (16 March 2019). [https://unix.stackexchange.com/a/506723 Answer 506723] on &amp;quot;Disabling mouse support in vim in a gnome-terminal environment&amp;quot;, Unix &amp;amp; Linux Stack Exchange.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &amp;quot; Use skip_defaults_vim from the master /etc/vim/vimrc file&lt;br /&gt;
 if ! exists(&amp;#039;skip_defaults_vim&amp;#039;)&lt;br /&gt;
   &amp;quot; Source the defaults file manually from here&lt;br /&gt;
   source $VIMRUNTIME/defaults.vim&lt;br /&gt;
 endif&lt;br /&gt;
 &lt;br /&gt;
 &amp;quot; Avoid loading the defaults twice&lt;br /&gt;
 let g:skip_defaults_vim = 1&lt;br /&gt;
 &lt;br /&gt;
 &amp;quot; Revert any unwanted changes the defaults file introduced&lt;br /&gt;
 set mouse=&lt;br /&gt;
&lt;br /&gt;
== Too many leftover git branches merged into master? Nukem! ==&lt;br /&gt;
&lt;br /&gt;
This will remove any branches on your local git repo that have been merged to master.&lt;br /&gt;
&lt;br /&gt;
 for i in $(for b in $(git branch|grep -v &amp;#039;\*&amp;#039;); do git branch $b --merged master; done); \&lt;br /&gt;
     do git branch -D $i; \&lt;br /&gt;
 done&lt;br /&gt;
&lt;br /&gt;
== Move your MySQL databases ==&lt;br /&gt;
&lt;br /&gt;
Used to be you could move your /var/lib/mysql directory somewhere else and symlink it. You can, but in newer distros with Apparmor you&amp;#039;ll need to declare it:&lt;br /&gt;
&lt;br /&gt;
 # In /etc/apparmor.d/tunables/alias&lt;br /&gt;
 alias /var/lib/mysql/ -&amp;gt; /mnt/wherever/mysql/,&lt;br /&gt;
&lt;br /&gt;
Note the trailing comma.&lt;br /&gt;
&lt;br /&gt;
== Split audio CD rips using the cue file ==&lt;br /&gt;
&lt;br /&gt;
Single-file FLAC or Ape files of a CD can be split up using the .cue file for both the timestamps and the tagging data. Also, install flacon (from a PPA).&lt;br /&gt;
&lt;br /&gt;
 sudo apt install shntool&lt;br /&gt;
 shnsplit -o flac cdimage.flac -f cdimage.cue -t &amp;#039;%n.%t&amp;#039;&lt;br /&gt;
&lt;br /&gt;
You may need to do tags again, if they didn&amp;#039;t stick:&lt;br /&gt;
&lt;br /&gt;
 sudo apt install cuetools&lt;br /&gt;
 cuetag cdimage.cue *.flac&lt;br /&gt;
&lt;br /&gt;
== Ditch Snap ==&lt;br /&gt;
&lt;br /&gt;
=== 1. Install Firefox properly ===&lt;br /&gt;
&lt;br /&gt;
Ubuntu 22.04 replaces the Firefox Debian package with a pseudo-package that installs it using Snap. This is no longer optional, and it is also stupid, annoying, slow, and potentially insecure for many reasons.&amp;lt;ref&amp;gt;Brandon Hopkins. [https://techhut.tv/flatpak-vs-snap-vs-appimage/ &amp;quot;Flatpak vs. Snap vs. AppImage - Linux Packaging Benchmarks&amp;quot;] TechHut, April 2022.&amp;lt;/ref&amp;gt; Several Firefox extensions that need to talk to other applications don&amp;#039;t currently work in Snap installed Firefox, including things like Zotero and Keepass.&lt;br /&gt;
&lt;br /&gt;
It also completely fails to find and import any existing Firefox profile. Snap apps for whatever stupid reason keep settings in a hard-coded ~/snap folder. Who thought that was a good idea? What&amp;#039;s wrong with ~/.config and/or ~/.local, or couldn&amp;#039;t they even use ~/.snap? Good grief.&lt;br /&gt;
&lt;br /&gt;
Luckily, we can use the Mozilla Team PPA instead.&amp;lt;ref&amp;gt;Ji M. [https://ubuntuhandbook.org/index.php/2022/04/install-firefox-deb-ubuntu-22-04/ &amp;quot;How to Install Latest Firefox as classic Deb in Ubuntu 22.04&amp;quot;] Ubuntu Handbook, April 2022.&amp;lt;/ref&amp;gt; In summary:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Remove Firefox entirely:&lt;br /&gt;
snap remove firefox&lt;br /&gt;
apt remove firefox&lt;br /&gt;
&lt;br /&gt;
# Add the Mozilla Team PPA and install:&lt;br /&gt;
add-apt-repository ppa:mozillateam/ppa&lt;br /&gt;
apt update&lt;br /&gt;
apt install -t &amp;#039;o=LP-PPA-mozillateam&amp;#039; firefox&lt;br /&gt;
&lt;br /&gt;
# Pin to the Mozilla Team PPA so we never get the Snap pseudo-package&lt;br /&gt;
echo &amp;#039;Package: firefox*&lt;br /&gt;
Pin: release o=LP-PPA-mozillateam&lt;br /&gt;
Pin-Priority: 501&amp;#039; &amp;gt; /etc/apt/preferences.d/mozillateam-ppa.pref&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 2. Remove snap ===&lt;br /&gt;
&lt;br /&gt;
You can also remove snap entirely as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# get a list of things installed with snap:&lt;br /&gt;
snap list&lt;br /&gt;
&lt;br /&gt;
# remove them one by one:&lt;br /&gt;
snap uninstall &amp;#039;&amp;#039;program1&amp;#039;&amp;#039;&lt;br /&gt;
snap uninstall &amp;#039;&amp;#039;program2&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
# once there&amp;#039;s nothing left, remove snap:&lt;br /&gt;
apt purge snapd&lt;br /&gt;
&lt;br /&gt;
# then prevent it ever being re-installed with a pin preference:&lt;br /&gt;
echo &amp;#039;Package: snapd&lt;br /&gt;
 Pin: release a=*&lt;br /&gt;
 Pin-Priority: -10&amp;#039; &amp;gt; /etc/apt/preferences.d/no-snap.pref&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Fancy PostgreSQL prompts==&lt;br /&gt;
&lt;br /&gt;
For a coloured prompt including what user, connection, and host you&amp;#039;re on, stick this in ~/.psqlrc or /etc/postgresql-common/psqlrc:&lt;br /&gt;
&lt;br /&gt;
 \set PROMPT1 &amp;#039;%[%033[1m%](%n@%[%033[1;35m%]%M%[%033[m%]%[%033[1m%] on %[%033[1;31m%]%`hostname`%[%033[m%]%[%033[1m%]) \n%/%R%#%[%033[m%] &amp;#039;&lt;br /&gt;
 \set PROMPT2 &amp;#039;%[%033[1m%]%/%R%#%[%033[m%] &amp;#039;&lt;br /&gt;
 \set PROMPT3 &amp;#039;%[%033[1m%]&amp;gt;&amp;gt;%[%033[m%] &amp;#039;&lt;br /&gt;
&lt;br /&gt;
Escape codes use &amp;#039;%&amp;#039; character, documented here: [https://www.postgresql.org/docs/current/app-psql.html#APP-PSQL-PROMPTING Psql Prompts].&lt;br /&gt;
&lt;br /&gt;
==Using rsync with FAT volumes (USB sticks and SD cards)==&lt;br /&gt;
&lt;br /&gt;
You might have noticed that all your files have today&amp;#039;s timestamp on them when using rsync thus:&lt;br /&gt;
 rsync -av /path/to/my/stuff /mnt/usb-stick/&lt;br /&gt;
&lt;br /&gt;
The -a option means -rlDtpog, which is recursive, include links and devices, preserving timestamps, permissions, owner and group. Which is what you want most of the time. Trouble is, FAT partitions have no concept of permissions, owners and groups, so you need to use:&lt;br /&gt;
 rsync -rtlDv /path/to/my/stuff /mnt/usb-stick/&lt;br /&gt;
&lt;br /&gt;
But that&amp;#039;s probably not all, because rsync will probably complain that it can&amp;#039;t set the timestamp. You&amp;#039;ll need to mount your USB stick so it ignores a user check that FAT can&amp;#039;t enforce:&lt;br /&gt;
 mount -o remount,allow_utime=2 /mnt/usb-stick&lt;br /&gt;
&lt;br /&gt;
==Update your groups without logging out and in again==&lt;br /&gt;
&lt;br /&gt;
When adding yourself to some new group, refresh your current shell session&amp;#039;s idea of what groups you&amp;#039;re in:&lt;br /&gt;
 sudo usermod -aG &amp;#039;&amp;#039;somegroup&amp;#039;&amp;#039; &amp;#039;&amp;#039;me&amp;#039;&amp;#039;&lt;br /&gt;
 newgrp &amp;#039;&amp;#039;somegroup&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
==Notes==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;/div&gt;</summary>
		<author><name>Johnno</name></author>
	</entry>
	<entry>
		<id>https://wiki.jon.geek.nz/index.php?title=NextCloud&amp;diff=2520</id>
		<title>NextCloud</title>
		<link rel="alternate" type="text/html" href="https://wiki.jon.geek.nz/index.php?title=NextCloud&amp;diff=2520"/>
		<updated>2025-09-16T23:47:22Z</updated>

		<summary type="html">&lt;p&gt;Johnno: /* NextCloud Office */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Assumes Ubuntu 20.04, stable20 branch, and installing in {{code|/var/www/nextcloud}} for a cloud.&amp;#039;&amp;#039;&amp;#039;example.com&amp;#039;&amp;#039;&amp;#039; URL (c. December 2020).&lt;br /&gt;
&lt;br /&gt;
== Prerequisites ==&lt;br /&gt;
&lt;br /&gt;
Install some stuff first. This NextCloud recipe uses [[PostgreSQL]], Redis, Apache 2.4, FastCGI with PHP FPM, and Dehydrated for [[Letsencrypt]] SSL certificate maangement.&lt;br /&gt;
&lt;br /&gt;
 sudo apt install apache2 libapache2-mod-fcgid \&lt;br /&gt;
    php7.4-{bcmath,bz2,curl,gd,fpm,gmp,intl,json,mbstring,opcache,pgsql,tidy,xmlrpc,xsl,zip}&lt;br /&gt;
    php-{imagick,redis} composer dehydrated postgresql redis-server&lt;br /&gt;
&lt;br /&gt;
;NOTE: NextCloud works fine under nginx, I just can&amp;#039;t be bothered maintaining what goes in {{code|.htaccess}} which NextCloud expects to be writeable to keep itself updated.&lt;br /&gt;
&lt;br /&gt;
== Configuring Apache and PHP ==&lt;br /&gt;
&lt;br /&gt;
: &amp;#039;&amp;#039;See the [[PHP]] page for setting up PHP with Apache, FPM and Event MPM.&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
=== Add a virtual host for NextCloud ===&lt;br /&gt;
&lt;br /&gt;
It should look something like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;apache&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;VirtualHost *:443&amp;gt;&lt;br /&gt;
   ServerName cloud.example.com&lt;br /&gt;
   DocumentRoot /var/www/nextcloud &lt;br /&gt;
 &lt;br /&gt;
   &amp;lt;Directory &amp;quot;/var/www/nexcloud&amp;quot;&amp;gt;&lt;br /&gt;
     Options FollowSymLinks MultiViews&lt;br /&gt;
     AllowOverride All&lt;br /&gt;
     Require all granted&lt;br /&gt;
     Satisfy Any &lt;br /&gt;
     SetEnv HOME /var/www/nextcloud&lt;br /&gt;
     SetEnv HTTP_HOME /var/www/nextcloud&lt;br /&gt;
 &lt;br /&gt;
     &amp;lt;IfModule mod_dav.c&amp;gt;&lt;br /&gt;
       Dav off&lt;br /&gt;
     &amp;lt;/IfModule&amp;gt;&lt;br /&gt;
   &amp;lt;/Directory&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
   SSLEngine On&lt;br /&gt;
   SSLCertificateFile ...&lt;br /&gt;
 &amp;lt;/VirtualHost&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== PHP settings ===&lt;br /&gt;
&lt;br /&gt;
Enable the opcache, increase the memory limit, and increase the maximum POST and file upload size so you can upload large files.&lt;br /&gt;
&lt;br /&gt;
== Create a database ==&lt;br /&gt;
&lt;br /&gt;
Create a database in [[PostgreSQL]]:&lt;br /&gt;
&lt;br /&gt;
 sudo -u postgres createuser -SDRP &amp;#039;&amp;#039;&amp;lt;nextcloud-user&amp;gt;&amp;#039;&amp;#039;&lt;br /&gt;
 sudo -u postgres createdb -E UTF8 -O &amp;#039;&amp;#039;&amp;lt;nextcloud-user&amp;gt;&amp;#039;&amp;#039; &amp;#039;&amp;#039;&amp;lt;nextcloud-dbname&amp;gt;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
== Install NextCloud ==&lt;br /&gt;
&lt;br /&gt;
We can just clone it from git:&lt;br /&gt;
&lt;br /&gt;
 git clone &amp;lt;nowiki&amp;gt;https://&amp;lt;/nowiki&amp;gt;github.com/nextcloud/server.git nextcloud&lt;br /&gt;
 cd nextcloud&lt;br /&gt;
 git checkout stable20  &amp;#039;&amp;#039;# or whatever the latest stable version is&amp;#039;&amp;#039;&lt;br /&gt;
 git submodule update --init --recursive&lt;br /&gt;
 chown www-data:www-data config apps .htaccess&lt;br /&gt;
&lt;br /&gt;
Create a directory for the cache and user data, which should not reside under the web root:&lt;br /&gt;
&lt;br /&gt;
 mkdir -p /var/lib/nextcloud/data /var/cache/nextcloud&lt;br /&gt;
 chown -R www-data:www-data /var/lib/nextcloud /var/cache/nextcloud&lt;br /&gt;
&lt;br /&gt;
== Configure NextCloud ==&lt;br /&gt;
&lt;br /&gt;
Edit the configuration file in {{code|config/config.php}} and check or consider these settings, and add the database and SMTP connection details:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
 $config =&amp;gt; [&lt;br /&gt;
   # ...&lt;br /&gt;
   #&lt;br /&gt;
   &amp;#039;passwordsalt&amp;#039; =&amp;gt; &amp;quot;&amp;lt;very long random string&amp;gt;&amp;quot;,&lt;br /&gt;
   &amp;#039;secret&amp;#039; =&amp;gt; &amp;quot;&amp;lt;a different very long random string&amp;gt;&amp;quot;,&lt;br /&gt;
   &amp;#039;trusted_domains&amp;#039; =&amp;gt; [&lt;br /&gt;
     0 =&amp;gt; &amp;quot;cloud.example.com&amp;quot;,&lt;br /&gt;
   ],&lt;br /&gt;
   &amp;#039;datadirectory&amp;#039; =&amp;gt; &amp;#039;/var/lib/nextcloud/data&amp;#039;,&lt;br /&gt;
   &amp;#039;overwrite.cli.url&amp;#039; =&amp;gt; &amp;#039;&amp;lt;nowiki&amp;gt;https://&amp;lt;/nowiki&amp;gt;cloud.example.com/&amp;#039;,&lt;br /&gt;
   &amp;#039;htaccess.RewriteBase&amp;#039; =&amp;gt; &amp;#039;/&amp;#039;,&lt;br /&gt;
 &lt;br /&gt;
   # Database connection details&lt;br /&gt;
   &amp;#039;dbtype&amp;#039; =&amp;gt; &amp;#039;pgsql&amp;#039;,&lt;br /&gt;
   &amp;#039;dbhost&amp;#039; =&amp;gt; &amp;#039;localhost&amp;#039;,&lt;br /&gt;
   &amp;#039;dbuser&amp;#039; =&amp;gt; &amp;quot;&amp;lt;nextcloud-dbuser&amp;gt;&amp;quot;,&lt;br /&gt;
   &amp;#039;dbpassword&amp;#039; =&amp;gt; &amp;quot;&amp;lt;password&amp;gt;&amp;quot;,&lt;br /&gt;
   &amp;#039;dbname&amp;#039; =&amp;gt; &amp;quot;&amp;lt;nextcloud-dbname&amp;gt;&amp;quot;,&lt;br /&gt;
   &amp;#039;dbtableprefix&amp;#039; =&amp;gt; &amp;#039;oc_&amp;#039;,&lt;br /&gt;
 &lt;br /&gt;
   # Force all URLs to use SSL or it may trip up things like OAuth&lt;br /&gt;
   &amp;#039;overwriteprotocol&amp;#039; =&amp;gt; &amp;#039;https&amp;#039;,&lt;br /&gt;
 &lt;br /&gt;
   # Use Redis and caching to make everything go faster&lt;br /&gt;
   &amp;#039;memcache.local&amp;#039; =&amp;gt; &amp;#039;\\OC\\Memcache\\Redis&amp;#039;,&lt;br /&gt;
   &amp;#039;memcache.locking&amp;#039; =&amp;gt; &amp;#039;\\OC\\Memcache\\Redis&amp;#039;,&lt;br /&gt;
   &amp;#039;redis&amp;#039; =&amp;gt; [&lt;br /&gt;
     &amp;#039;host&amp;#039; =&amp;gt; &amp;#039;localhost&amp;#039;,&lt;br /&gt;
     &amp;#039;port&amp;#039; =&amp;gt; 6379,&lt;br /&gt;
   ],&lt;br /&gt;
   &amp;#039;cache_path&amp;#039; =&amp;gt; &amp;#039;/var/cache/nextcloud&amp;#039;,&lt;br /&gt;
 &lt;br /&gt;
   # Send email details&lt;br /&gt;
   &amp;#039;mail_smtpmode&amp;#039; =&amp;gt; &amp;#039;smtp&amp;#039;,&lt;br /&gt;
   &amp;#039;mail_smtpsecure&amp;#039; =&amp;gt; &amp;#039;tls&amp;#039;,&lt;br /&gt;
   &amp;#039;mail_sendmailmode&amp;#039; =&amp;gt; &amp;#039;smtp&amp;#039;,&lt;br /&gt;
   &amp;#039;mail_from_address&amp;#039; =&amp;gt; &amp;quot;nexcloud@example.com&amp;quot;,&lt;br /&gt;
   &amp;#039;mail_domain&amp;#039; =&amp;gt; &amp;quot;example.com&amp;quot;,&lt;br /&gt;
   &amp;#039;mail_smtpauthtype&amp;#039; =&amp;gt; &amp;#039;PLAIN&amp;#039;,&lt;br /&gt;
   &amp;#039;mail_smtpauth&amp;#039; =&amp;gt; 1,&lt;br /&gt;
   &amp;#039;mail_smtphost&amp;#039; =&amp;gt; &amp;quot;mail.example.com&amp;quot;,&lt;br /&gt;
   &amp;#039;mail_smtpport&amp;#039; =&amp;gt; 587,&lt;br /&gt;
   &amp;#039;mail_smtpname&amp;#039; =&amp;gt; &amp;quot;&amp;lt;emailuser&amp;gt;&amp;quot;,&lt;br /&gt;
   &amp;#039;mail_smtppassword&amp;#039; =&amp;gt; &amp;quot;&amp;lt;emailpassword&amp;gt;&amp;quot;,&lt;br /&gt;
 &lt;br /&gt;
   # ...&lt;br /&gt;
 ]  &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then navigate to the URL in the browser to install (or run the NextCloud {{code | ./occ}} tool from the command line).&lt;br /&gt;
&lt;br /&gt;
;Note: Make sure that the directory used for {{code|cache_path}} exists and is writeable, or you will get weird seemingly unrelated 403 MKCOL errors to do with [https://docs.nextcloud.com/server/26/admin_manual/configuration_files/big_file_upload_configuration.html chunked uploads].&lt;br /&gt;
&lt;br /&gt;
=== Clean URLs ===&lt;br /&gt;
&lt;br /&gt;
For clean URLs, make sure {{code | AllowOverride All}} is set for the parent directory; the {{code | /var/www}} definition is in the main {{code | /etc/apache2/apache.conf}}. Then run the follwing OCC command to enable the rewrite rules:&lt;br /&gt;
&lt;br /&gt;
 sudo -u www-data ./occ maintenance:update:htaccess&lt;br /&gt;
&lt;br /&gt;
=== Previews of other file types ===&lt;br /&gt;
&lt;br /&gt;
Edit {{code|/etc/ImageMagick/policy.xml}} and remove this line to get PDF previews to work:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;policy domain=&amp;quot;coder&amp;quot; rights=&amp;quot;none&amp;quot; pattern=&amp;quot;PDF&amp;quot; /&amp;gt; &amp;lt;!-- remove this line --&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then add the following to {{code|config.php}} to get lots of other useful file previews:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
   &amp;#039;enabledPreviewProviders&amp;#039; =&amp;gt; [&lt;br /&gt;
     # ...&lt;br /&gt;
     8 =&amp;gt; &amp;#039;OC\\Preview\\MarkDown&amp;#039;,&lt;br /&gt;
     9 =&amp;gt; &amp;#039;OC\\Preview\\Movie&amp;#039;,&lt;br /&gt;
     10 =&amp;gt; &amp;#039;OC\\Preview\\PDF&amp;#039;,&lt;br /&gt;
     11 =&amp;gt; &amp;#039;OC\\Preview\\OpenDocument&amp;#039;,&lt;br /&gt;
     12 =&amp;gt; &amp;#039;OC\\Preview\\MSOfficeDoc&amp;#039;,&lt;br /&gt;
     13 =&amp;gt; &amp;#039;OC\\Preview\\MSOffice2003&amp;#039;,&lt;br /&gt;
     14 =&amp;gt; &amp;#039;OC\\Preview\\MSOffice2007&amp;#039;,&lt;br /&gt;
   ],&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Photos ===&lt;br /&gt;
&lt;br /&gt;
Photos replaces the Gallery app, and is installed separately through the NC store or you can use git to manage it as a submodule. If it doesn&amp;#039;t work you might need to build its JavaScript resources by running {{code|make}} in its {{code|apps/photos}} directory. Alternatively you can resuscitate the Gallery app, which stopped working after NextCloud version 17, by updating its JavaScript dompurify library to a [https://raw.githubusercontent.com/nextcloud/gallery/ecb26a812f30a3f516964808ccfa6430be09b45e/js/vendor/dompurify/src/purify.js newer version] and bumping the app max version in {{code|apps/galleryappinfo/info.xml}} as follows (See also [https://github.com/nextcloud/gallery/pull/570/ pull request #570]):&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nextcloud min-version=&amp;quot;17&amp;quot; max-version=&amp;quot;&amp;#039;&amp;#039;&amp;#039;20&amp;#039;&amp;#039;&amp;#039;&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== NextCloud Talk ===&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;Note:&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039; &amp;#039;&amp;#039;A TURN server can also be used for other things, like your own [https://matrix-org.github.io/synapse/v1.41/turn-howto.html Matrix] chat server.&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
To be at all useful, you need a TURN server. This is easiest achieved by installing and correctly configuring coturn, which also acts as a STUN server. STUN is for clients to figure out their external IP address, and TURN is for relaying UDP packets, e.g. for WebRTC.&lt;br /&gt;
&lt;br /&gt;
 sudo apt install coturn&lt;br /&gt;
&lt;br /&gt;
For it to actually do anything (it is disabled by default!) you need to edit {{code|/etc/default/coturn}} and make sure it contains the following, and is not commented out:&lt;br /&gt;
&lt;br /&gt;
 TURNSERVER_ENABLED=1&lt;br /&gt;
&lt;br /&gt;
Then in {{code|/etc/turnserver.conf}} you need to configure its domain name, IP addresses and ports, SSL certificate, and how TURN authenticates. See GitHub for a fully documented example [https://github.com/coturn/coturn/blob/master/examples/etc/turnserver.conf turnserver.conf] file. This example uses the same domain as the NextCloud instance, on the standard STUN and TURN ports, but if you want to host it on port 443 to support people behind restrictive firewalls, you will need a different subdomain and/or IP address:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;ini&amp;quot;&amp;gt;&lt;br /&gt;
 server-name=cloud.example.com&lt;br /&gt;
 realm=cloud.example.com&lt;br /&gt;
 &lt;br /&gt;
 # When hosted on an internal LAN or DMZ, it might look like this: &lt;br /&gt;
 listening-ip=192.168.1.100&lt;br /&gt;
 relay-ip=192.168.1.100&lt;br /&gt;
 external-ip=123.45.67.8&lt;br /&gt;
 &lt;br /&gt;
 # Or use the short-hand:&lt;br /&gt;
 external-ip=123.45.67.8/192.168.1.100&lt;br /&gt;
 &lt;br /&gt;
 # Specify listening ports; originally 3478 was unencrypted, and 5349 was TLS,&lt;br /&gt;
 # but now TLS is supported on both. It is possible to listen on 443, which will&lt;br /&gt;
 # help to provide connectivity for people behind port-limited firewalls; this will&lt;br /&gt;
 # conflict with any HTTPS web hosting on the same server though, unless you set&lt;br /&gt;
 # up a second IP address for it.&lt;br /&gt;
 listening-port=3478&lt;br /&gt;
 tls-listening-port=5349&lt;br /&gt;
 #tls-listening-port=443&lt;br /&gt;
 &lt;br /&gt;
 # Specify a UDP port range and ensure they are exposed through the firewall/router&lt;br /&gt;
 min-port=53490&lt;br /&gt;
 max-port=59999&lt;br /&gt;
 &lt;br /&gt;
 # SSL setup; &lt;br /&gt;
 cert=/path/to/cloud.example.com/fullchain.cert&lt;br /&gt;
 pkey=/path/to/cloud.example.com/privkey.pem&lt;br /&gt;
 no-tlsv1&lt;br /&gt;
 no-tlsv1_1&lt;br /&gt;
 &lt;br /&gt;
 # To use with NextCloud, set a shared secret here.&lt;br /&gt;
 use-auth-secret&lt;br /&gt;
 static-auth-secret=your-shared-secret-string-here&lt;br /&gt;
 stale-nonce=600&lt;br /&gt;
 &lt;br /&gt;
 # Limit STUN amplification/gain attacks (coturn 4.5.2+)&lt;br /&gt;
 no-stun-backward-compatibility&lt;br /&gt;
 response-origin-only-with-rfc5780&lt;br /&gt;
 &lt;br /&gt;
 # RFC-5780 support requires two listening IP addresses and is for serious-cat&lt;br /&gt;
 # usage, so you can safely disable it for a small home NextCloud instance.&lt;br /&gt;
 no-rfc5780&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that the coturn user can&amp;#039;t read certificates in &amp;lt;code&amp;gt;/etc/ssl/letsencrypt&amp;lt;/code&amp;gt; so you will need a deploy hook script to copy them safely to somewhere it can read them:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;sh&amp;quot;&amp;gt;&lt;br /&gt;
#!/bin/sh&lt;br /&gt;
# /etc/letsencrypt/renewal-hooks/deploy/coturn&lt;br /&gt;
set -e&lt;br /&gt;
for domain in $RENEWED_DOMAINS; do&lt;br /&gt;
    case $domain in&lt;br /&gt;
    cloud.example.com)&lt;br /&gt;
        certs=/etc/coturn/certs&lt;br /&gt;
        fullchain=&amp;quot;${certs}/${domain}_fullchain.pem&amp;quot;&lt;br /&gt;
        key=&amp;quot;${certs}/${domain}_privkey.pem&amp;quot;&lt;br /&gt;
&lt;br /&gt;
        # certificate and private key files are never world readable&lt;br /&gt;
        umask 077&lt;br /&gt;
        cp &amp;quot;${RENEWED_LINEAGE}/fullchain.pem&amp;quot; &amp;quot;$fullchain&amp;quot;&lt;br /&gt;
        cp &amp;quot;${RENEWED_LINEAGE}/privkey.pem&amp;quot; &amp;quot;$key&amp;quot;&lt;br /&gt;
&lt;br /&gt;
        chown turnserver:turnserver &amp;quot;$fullchain&amp;quot; &amp;quot;$key&amp;quot;&lt;br /&gt;
        chmod 400 &amp;quot;$fullchain&amp;quot; &amp;quot;$key&amp;quot;&lt;br /&gt;
&lt;br /&gt;
        systemctl restart coturn &amp;gt; /dev/null&lt;br /&gt;
        ;;&lt;br /&gt;
    esac&lt;br /&gt;
done&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In your NextCloud Administration section, you can now configure Talk to use the STUN/TURN server, using your server URLs, and provide the same shared secret you configured above. For maximum compatibility, use both UDP and TCP, and both turn and turns (TLS) connections:&lt;br /&gt;
&lt;br /&gt;
 stun: &amp;#039;&amp;#039;&amp;#039;cloud.example.com&amp;#039;&amp;#039;&amp;#039;:5349&lt;br /&gt;
 turn and turns: &amp;#039;&amp;#039;&amp;#039;cloud.example.com&amp;#039;&amp;#039;&amp;#039;:5349&lt;br /&gt;
&lt;br /&gt;
Test your server [https://webrtc.github.io/samples/src/content/peerconnection/trickle-ice/ here]. If STUN is working, you should get {{code|srflx}} candidates, and {{code|relay}} candidates if TURN is working.&lt;br /&gt;
&lt;br /&gt;
Sources and further reading:&lt;br /&gt;
* NextCloud Talk documentation: [https://nextcloud-talk.readthedocs.io/en/latest/TURN/ TURN], [https://nextcloud-talk.readthedocs.io/en/latest/coturn coturn]&lt;br /&gt;
* NextCloud Help, [https://help.nextcloud.com/t/howto-setup-nextcloud-talk-with-turn-server/30794 1] [https://help.nextcloud.com/t/nextcloud-talk-app-could-not-establish-a-connection-a-turn-server/131069/31 2]&lt;br /&gt;
* Stack Overflow [https://stackoverflow.com/questions/42801361/install-rfc5766-turn-server-trying-to-bind-fd-to-ip-address-errno-99 1]&lt;br /&gt;
* [https://ourcodeworld.com/articles/read/1526/how-to-test-online-whether-a-stun-turn-server-is-working-properly-or-not Testing STUN/TURN]&lt;br /&gt;
* Serverfault, question [https://serverfault.com/questions/849683/how-to-setup-coturn-with-letsencrypt #849683].&lt;br /&gt;
&lt;br /&gt;
=== NextCloud Office ===&lt;br /&gt;
&lt;br /&gt;
Install Collabora Office Online (COOL) which emerged from the smoking ruins of LibreOffice Online (LOOL):&lt;br /&gt;
&lt;br /&gt;
 apt install coolwsd code-brand&lt;br /&gt;
&lt;br /&gt;
Use an Apache reverse proxy to handle the host and SSL, disable SSL in WOPI setup; restrict NextCloud and coolwsd requests to their respective endpoints, IP addresses; see [https://c-nergy.be/blog/?p=18055 &amp;quot;Install CODE on NextCloud on Ubuntu 22.04&amp;quot;]&lt;br /&gt;
&lt;br /&gt;
For some reason the Debian package on Ubuntu 24.04 does not install the Apparmor profile, which prevents it from starting (unable to mount unprivileged child user namespaces).&lt;br /&gt;
&lt;br /&gt;
 &amp;#039;&amp;#039;# AppArmor policy for coolwsd:&amp;#039;&amp;#039;&lt;br /&gt;
 &amp;#039;&amp;#039;# /etc/apparmor.d/usr.bin.coolwsd&amp;#039;&amp;#039;&lt;br /&gt;
 abi &amp;lt;abi/4.0&amp;gt;,&lt;br /&gt;
 include &amp;lt;tunables/global&amp;gt;&lt;br /&gt;
 profile coolwsd /usr/bin/coolwsd flags=(unconfined) {&lt;br /&gt;
   userns,&lt;br /&gt;
   include if exists &amp;lt;local/coolwsd&amp;gt;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
You may also need to set &amp;lt;code&amp;gt;kernel.unprivileged_userns_clone=1&amp;lt;/code&amp;gt; in sysctl if it still doesn&amp;#039;t work.&lt;br /&gt;
&lt;br /&gt;
== Maintenance ==&lt;br /&gt;
&lt;br /&gt;
Keep the git checkout of NextCloud and its submodules up to date with git, and run the OCC upgrade command:&lt;br /&gt;
&lt;br /&gt;
 cd /var/www/nextcloud&lt;br /&gt;
 git pull&lt;br /&gt;
 git submodule update --init --recursive&lt;br /&gt;
 sudo -u www-data ./occ upgrade&lt;br /&gt;
&lt;br /&gt;
=== Cron job ===&lt;br /&gt;
&lt;br /&gt;
In the administrator settings select cron rather than other methods, and put this in {{code|/etc/cron.d/nextcloud}}&lt;br /&gt;
&lt;br /&gt;
 */5 * * * * www-data /usr/bin/php /var/www/nextcloud/cron.php&lt;/div&gt;</summary>
		<author><name>Johnno</name></author>
	</entry>
	<entry>
		<id>https://wiki.jon.geek.nz/index.php?title=NextCloud&amp;diff=2519</id>
		<title>NextCloud</title>
		<link rel="alternate" type="text/html" href="https://wiki.jon.geek.nz/index.php?title=NextCloud&amp;diff=2519"/>
		<updated>2025-09-16T23:35:00Z</updated>

		<summary type="html">&lt;p&gt;Johnno: /* NextCloud Talk */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Assumes Ubuntu 20.04, stable20 branch, and installing in {{code|/var/www/nextcloud}} for a cloud.&amp;#039;&amp;#039;&amp;#039;example.com&amp;#039;&amp;#039;&amp;#039; URL (c. December 2020).&lt;br /&gt;
&lt;br /&gt;
== Prerequisites ==&lt;br /&gt;
&lt;br /&gt;
Install some stuff first. This NextCloud recipe uses [[PostgreSQL]], Redis, Apache 2.4, FastCGI with PHP FPM, and Dehydrated for [[Letsencrypt]] SSL certificate maangement.&lt;br /&gt;
&lt;br /&gt;
 sudo apt install apache2 libapache2-mod-fcgid \&lt;br /&gt;
    php7.4-{bcmath,bz2,curl,gd,fpm,gmp,intl,json,mbstring,opcache,pgsql,tidy,xmlrpc,xsl,zip}&lt;br /&gt;
    php-{imagick,redis} composer dehydrated postgresql redis-server&lt;br /&gt;
&lt;br /&gt;
;NOTE: NextCloud works fine under nginx, I just can&amp;#039;t be bothered maintaining what goes in {{code|.htaccess}} which NextCloud expects to be writeable to keep itself updated.&lt;br /&gt;
&lt;br /&gt;
== Configuring Apache and PHP ==&lt;br /&gt;
&lt;br /&gt;
: &amp;#039;&amp;#039;See the [[PHP]] page for setting up PHP with Apache, FPM and Event MPM.&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
=== Add a virtual host for NextCloud ===&lt;br /&gt;
&lt;br /&gt;
It should look something like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;apache&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;VirtualHost *:443&amp;gt;&lt;br /&gt;
   ServerName cloud.example.com&lt;br /&gt;
   DocumentRoot /var/www/nextcloud &lt;br /&gt;
 &lt;br /&gt;
   &amp;lt;Directory &amp;quot;/var/www/nexcloud&amp;quot;&amp;gt;&lt;br /&gt;
     Options FollowSymLinks MultiViews&lt;br /&gt;
     AllowOverride All&lt;br /&gt;
     Require all granted&lt;br /&gt;
     Satisfy Any &lt;br /&gt;
     SetEnv HOME /var/www/nextcloud&lt;br /&gt;
     SetEnv HTTP_HOME /var/www/nextcloud&lt;br /&gt;
 &lt;br /&gt;
     &amp;lt;IfModule mod_dav.c&amp;gt;&lt;br /&gt;
       Dav off&lt;br /&gt;
     &amp;lt;/IfModule&amp;gt;&lt;br /&gt;
   &amp;lt;/Directory&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
   SSLEngine On&lt;br /&gt;
   SSLCertificateFile ...&lt;br /&gt;
 &amp;lt;/VirtualHost&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== PHP settings ===&lt;br /&gt;
&lt;br /&gt;
Enable the opcache, increase the memory limit, and increase the maximum POST and file upload size so you can upload large files.&lt;br /&gt;
&lt;br /&gt;
== Create a database ==&lt;br /&gt;
&lt;br /&gt;
Create a database in [[PostgreSQL]]:&lt;br /&gt;
&lt;br /&gt;
 sudo -u postgres createuser -SDRP &amp;#039;&amp;#039;&amp;lt;nextcloud-user&amp;gt;&amp;#039;&amp;#039;&lt;br /&gt;
 sudo -u postgres createdb -E UTF8 -O &amp;#039;&amp;#039;&amp;lt;nextcloud-user&amp;gt;&amp;#039;&amp;#039; &amp;#039;&amp;#039;&amp;lt;nextcloud-dbname&amp;gt;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
== Install NextCloud ==&lt;br /&gt;
&lt;br /&gt;
We can just clone it from git:&lt;br /&gt;
&lt;br /&gt;
 git clone &amp;lt;nowiki&amp;gt;https://&amp;lt;/nowiki&amp;gt;github.com/nextcloud/server.git nextcloud&lt;br /&gt;
 cd nextcloud&lt;br /&gt;
 git checkout stable20  &amp;#039;&amp;#039;# or whatever the latest stable version is&amp;#039;&amp;#039;&lt;br /&gt;
 git submodule update --init --recursive&lt;br /&gt;
 chown www-data:www-data config apps .htaccess&lt;br /&gt;
&lt;br /&gt;
Create a directory for the cache and user data, which should not reside under the web root:&lt;br /&gt;
&lt;br /&gt;
 mkdir -p /var/lib/nextcloud/data /var/cache/nextcloud&lt;br /&gt;
 chown -R www-data:www-data /var/lib/nextcloud /var/cache/nextcloud&lt;br /&gt;
&lt;br /&gt;
== Configure NextCloud ==&lt;br /&gt;
&lt;br /&gt;
Edit the configuration file in {{code|config/config.php}} and check or consider these settings, and add the database and SMTP connection details:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
 $config =&amp;gt; [&lt;br /&gt;
   # ...&lt;br /&gt;
   #&lt;br /&gt;
   &amp;#039;passwordsalt&amp;#039; =&amp;gt; &amp;quot;&amp;lt;very long random string&amp;gt;&amp;quot;,&lt;br /&gt;
   &amp;#039;secret&amp;#039; =&amp;gt; &amp;quot;&amp;lt;a different very long random string&amp;gt;&amp;quot;,&lt;br /&gt;
   &amp;#039;trusted_domains&amp;#039; =&amp;gt; [&lt;br /&gt;
     0 =&amp;gt; &amp;quot;cloud.example.com&amp;quot;,&lt;br /&gt;
   ],&lt;br /&gt;
   &amp;#039;datadirectory&amp;#039; =&amp;gt; &amp;#039;/var/lib/nextcloud/data&amp;#039;,&lt;br /&gt;
   &amp;#039;overwrite.cli.url&amp;#039; =&amp;gt; &amp;#039;&amp;lt;nowiki&amp;gt;https://&amp;lt;/nowiki&amp;gt;cloud.example.com/&amp;#039;,&lt;br /&gt;
   &amp;#039;htaccess.RewriteBase&amp;#039; =&amp;gt; &amp;#039;/&amp;#039;,&lt;br /&gt;
 &lt;br /&gt;
   # Database connection details&lt;br /&gt;
   &amp;#039;dbtype&amp;#039; =&amp;gt; &amp;#039;pgsql&amp;#039;,&lt;br /&gt;
   &amp;#039;dbhost&amp;#039; =&amp;gt; &amp;#039;localhost&amp;#039;,&lt;br /&gt;
   &amp;#039;dbuser&amp;#039; =&amp;gt; &amp;quot;&amp;lt;nextcloud-dbuser&amp;gt;&amp;quot;,&lt;br /&gt;
   &amp;#039;dbpassword&amp;#039; =&amp;gt; &amp;quot;&amp;lt;password&amp;gt;&amp;quot;,&lt;br /&gt;
   &amp;#039;dbname&amp;#039; =&amp;gt; &amp;quot;&amp;lt;nextcloud-dbname&amp;gt;&amp;quot;,&lt;br /&gt;
   &amp;#039;dbtableprefix&amp;#039; =&amp;gt; &amp;#039;oc_&amp;#039;,&lt;br /&gt;
 &lt;br /&gt;
   # Force all URLs to use SSL or it may trip up things like OAuth&lt;br /&gt;
   &amp;#039;overwriteprotocol&amp;#039; =&amp;gt; &amp;#039;https&amp;#039;,&lt;br /&gt;
 &lt;br /&gt;
   # Use Redis and caching to make everything go faster&lt;br /&gt;
   &amp;#039;memcache.local&amp;#039; =&amp;gt; &amp;#039;\\OC\\Memcache\\Redis&amp;#039;,&lt;br /&gt;
   &amp;#039;memcache.locking&amp;#039; =&amp;gt; &amp;#039;\\OC\\Memcache\\Redis&amp;#039;,&lt;br /&gt;
   &amp;#039;redis&amp;#039; =&amp;gt; [&lt;br /&gt;
     &amp;#039;host&amp;#039; =&amp;gt; &amp;#039;localhost&amp;#039;,&lt;br /&gt;
     &amp;#039;port&amp;#039; =&amp;gt; 6379,&lt;br /&gt;
   ],&lt;br /&gt;
   &amp;#039;cache_path&amp;#039; =&amp;gt; &amp;#039;/var/cache/nextcloud&amp;#039;,&lt;br /&gt;
 &lt;br /&gt;
   # Send email details&lt;br /&gt;
   &amp;#039;mail_smtpmode&amp;#039; =&amp;gt; &amp;#039;smtp&amp;#039;,&lt;br /&gt;
   &amp;#039;mail_smtpsecure&amp;#039; =&amp;gt; &amp;#039;tls&amp;#039;,&lt;br /&gt;
   &amp;#039;mail_sendmailmode&amp;#039; =&amp;gt; &amp;#039;smtp&amp;#039;,&lt;br /&gt;
   &amp;#039;mail_from_address&amp;#039; =&amp;gt; &amp;quot;nexcloud@example.com&amp;quot;,&lt;br /&gt;
   &amp;#039;mail_domain&amp;#039; =&amp;gt; &amp;quot;example.com&amp;quot;,&lt;br /&gt;
   &amp;#039;mail_smtpauthtype&amp;#039; =&amp;gt; &amp;#039;PLAIN&amp;#039;,&lt;br /&gt;
   &amp;#039;mail_smtpauth&amp;#039; =&amp;gt; 1,&lt;br /&gt;
   &amp;#039;mail_smtphost&amp;#039; =&amp;gt; &amp;quot;mail.example.com&amp;quot;,&lt;br /&gt;
   &amp;#039;mail_smtpport&amp;#039; =&amp;gt; 587,&lt;br /&gt;
   &amp;#039;mail_smtpname&amp;#039; =&amp;gt; &amp;quot;&amp;lt;emailuser&amp;gt;&amp;quot;,&lt;br /&gt;
   &amp;#039;mail_smtppassword&amp;#039; =&amp;gt; &amp;quot;&amp;lt;emailpassword&amp;gt;&amp;quot;,&lt;br /&gt;
 &lt;br /&gt;
   # ...&lt;br /&gt;
 ]  &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then navigate to the URL in the browser to install (or run the NextCloud {{code | ./occ}} tool from the command line).&lt;br /&gt;
&lt;br /&gt;
;Note: Make sure that the directory used for {{code|cache_path}} exists and is writeable, or you will get weird seemingly unrelated 403 MKCOL errors to do with [https://docs.nextcloud.com/server/26/admin_manual/configuration_files/big_file_upload_configuration.html chunked uploads].&lt;br /&gt;
&lt;br /&gt;
=== Clean URLs ===&lt;br /&gt;
&lt;br /&gt;
For clean URLs, make sure {{code | AllowOverride All}} is set for the parent directory; the {{code | /var/www}} definition is in the main {{code | /etc/apache2/apache.conf}}. Then run the follwing OCC command to enable the rewrite rules:&lt;br /&gt;
&lt;br /&gt;
 sudo -u www-data ./occ maintenance:update:htaccess&lt;br /&gt;
&lt;br /&gt;
=== Previews of other file types ===&lt;br /&gt;
&lt;br /&gt;
Edit {{code|/etc/ImageMagick/policy.xml}} and remove this line to get PDF previews to work:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;policy domain=&amp;quot;coder&amp;quot; rights=&amp;quot;none&amp;quot; pattern=&amp;quot;PDF&amp;quot; /&amp;gt; &amp;lt;!-- remove this line --&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then add the following to {{code|config.php}} to get lots of other useful file previews:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
   &amp;#039;enabledPreviewProviders&amp;#039; =&amp;gt; [&lt;br /&gt;
     # ...&lt;br /&gt;
     8 =&amp;gt; &amp;#039;OC\\Preview\\MarkDown&amp;#039;,&lt;br /&gt;
     9 =&amp;gt; &amp;#039;OC\\Preview\\Movie&amp;#039;,&lt;br /&gt;
     10 =&amp;gt; &amp;#039;OC\\Preview\\PDF&amp;#039;,&lt;br /&gt;
     11 =&amp;gt; &amp;#039;OC\\Preview\\OpenDocument&amp;#039;,&lt;br /&gt;
     12 =&amp;gt; &amp;#039;OC\\Preview\\MSOfficeDoc&amp;#039;,&lt;br /&gt;
     13 =&amp;gt; &amp;#039;OC\\Preview\\MSOffice2003&amp;#039;,&lt;br /&gt;
     14 =&amp;gt; &amp;#039;OC\\Preview\\MSOffice2007&amp;#039;,&lt;br /&gt;
   ],&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Photos ===&lt;br /&gt;
&lt;br /&gt;
Photos replaces the Gallery app, and is installed separately through the NC store or you can use git to manage it as a submodule. If it doesn&amp;#039;t work you might need to build its JavaScript resources by running {{code|make}} in its {{code|apps/photos}} directory. Alternatively you can resuscitate the Gallery app, which stopped working after NextCloud version 17, by updating its JavaScript dompurify library to a [https://raw.githubusercontent.com/nextcloud/gallery/ecb26a812f30a3f516964808ccfa6430be09b45e/js/vendor/dompurify/src/purify.js newer version] and bumping the app max version in {{code|apps/galleryappinfo/info.xml}} as follows (See also [https://github.com/nextcloud/gallery/pull/570/ pull request #570]):&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nextcloud min-version=&amp;quot;17&amp;quot; max-version=&amp;quot;&amp;#039;&amp;#039;&amp;#039;20&amp;#039;&amp;#039;&amp;#039;&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== NextCloud Talk ===&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;Note:&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039; &amp;#039;&amp;#039;A TURN server can also be used for other things, like your own [https://matrix-org.github.io/synapse/v1.41/turn-howto.html Matrix] chat server.&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
To be at all useful, you need a TURN server. This is easiest achieved by installing and correctly configuring coturn, which also acts as a STUN server. STUN is for clients to figure out their external IP address, and TURN is for relaying UDP packets, e.g. for WebRTC.&lt;br /&gt;
&lt;br /&gt;
 sudo apt install coturn&lt;br /&gt;
&lt;br /&gt;
For it to actually do anything (it is disabled by default!) you need to edit {{code|/etc/default/coturn}} and make sure it contains the following, and is not commented out:&lt;br /&gt;
&lt;br /&gt;
 TURNSERVER_ENABLED=1&lt;br /&gt;
&lt;br /&gt;
Then in {{code|/etc/turnserver.conf}} you need to configure its domain name, IP addresses and ports, SSL certificate, and how TURN authenticates. See GitHub for a fully documented example [https://github.com/coturn/coturn/blob/master/examples/etc/turnserver.conf turnserver.conf] file. This example uses the same domain as the NextCloud instance, on the standard STUN and TURN ports, but if you want to host it on port 443 to support people behind restrictive firewalls, you will need a different subdomain and/or IP address:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;ini&amp;quot;&amp;gt;&lt;br /&gt;
 server-name=cloud.example.com&lt;br /&gt;
 realm=cloud.example.com&lt;br /&gt;
 &lt;br /&gt;
 # When hosted on an internal LAN or DMZ, it might look like this: &lt;br /&gt;
 listening-ip=192.168.1.100&lt;br /&gt;
 relay-ip=192.168.1.100&lt;br /&gt;
 external-ip=123.45.67.8&lt;br /&gt;
 &lt;br /&gt;
 # Or use the short-hand:&lt;br /&gt;
 external-ip=123.45.67.8/192.168.1.100&lt;br /&gt;
 &lt;br /&gt;
 # Specify listening ports; originally 3478 was unencrypted, and 5349 was TLS,&lt;br /&gt;
 # but now TLS is supported on both. It is possible to listen on 443, which will&lt;br /&gt;
 # help to provide connectivity for people behind port-limited firewalls; this will&lt;br /&gt;
 # conflict with any HTTPS web hosting on the same server though, unless you set&lt;br /&gt;
 # up a second IP address for it.&lt;br /&gt;
 listening-port=3478&lt;br /&gt;
 tls-listening-port=5349&lt;br /&gt;
 #tls-listening-port=443&lt;br /&gt;
 &lt;br /&gt;
 # Specify a UDP port range and ensure they are exposed through the firewall/router&lt;br /&gt;
 min-port=53490&lt;br /&gt;
 max-port=59999&lt;br /&gt;
 &lt;br /&gt;
 # SSL setup; &lt;br /&gt;
 cert=/path/to/cloud.example.com/fullchain.cert&lt;br /&gt;
 pkey=/path/to/cloud.example.com/privkey.pem&lt;br /&gt;
 no-tlsv1&lt;br /&gt;
 no-tlsv1_1&lt;br /&gt;
 &lt;br /&gt;
 # To use with NextCloud, set a shared secret here.&lt;br /&gt;
 use-auth-secret&lt;br /&gt;
 static-auth-secret=your-shared-secret-string-here&lt;br /&gt;
 stale-nonce=600&lt;br /&gt;
 &lt;br /&gt;
 # Limit STUN amplification/gain attacks (coturn 4.5.2+)&lt;br /&gt;
 no-stun-backward-compatibility&lt;br /&gt;
 response-origin-only-with-rfc5780&lt;br /&gt;
 &lt;br /&gt;
 # RFC-5780 support requires two listening IP addresses and is for serious-cat&lt;br /&gt;
 # usage, so you can safely disable it for a small home NextCloud instance.&lt;br /&gt;
 no-rfc5780&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that the coturn user can&amp;#039;t read certificates in &amp;lt;code&amp;gt;/etc/ssl/letsencrypt&amp;lt;/code&amp;gt; so you will need a deploy hook script to copy them safely to somewhere it can read them:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;sh&amp;quot;&amp;gt;&lt;br /&gt;
#!/bin/sh&lt;br /&gt;
# /etc/letsencrypt/renewal-hooks/deploy/coturn&lt;br /&gt;
set -e&lt;br /&gt;
for domain in $RENEWED_DOMAINS; do&lt;br /&gt;
    case $domain in&lt;br /&gt;
    cloud.example.com)&lt;br /&gt;
        certs=/etc/coturn/certs&lt;br /&gt;
        fullchain=&amp;quot;${certs}/${domain}_fullchain.pem&amp;quot;&lt;br /&gt;
        key=&amp;quot;${certs}/${domain}_privkey.pem&amp;quot;&lt;br /&gt;
&lt;br /&gt;
        # certificate and private key files are never world readable&lt;br /&gt;
        umask 077&lt;br /&gt;
        cp &amp;quot;${RENEWED_LINEAGE}/fullchain.pem&amp;quot; &amp;quot;$fullchain&amp;quot;&lt;br /&gt;
        cp &amp;quot;${RENEWED_LINEAGE}/privkey.pem&amp;quot; &amp;quot;$key&amp;quot;&lt;br /&gt;
&lt;br /&gt;
        chown turnserver:turnserver &amp;quot;$fullchain&amp;quot; &amp;quot;$key&amp;quot;&lt;br /&gt;
        chmod 400 &amp;quot;$fullchain&amp;quot; &amp;quot;$key&amp;quot;&lt;br /&gt;
&lt;br /&gt;
        systemctl restart coturn &amp;gt; /dev/null&lt;br /&gt;
        ;;&lt;br /&gt;
    esac&lt;br /&gt;
done&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In your NextCloud Administration section, you can now configure Talk to use the STUN/TURN server, using your server URLs, and provide the same shared secret you configured above. For maximum compatibility, use both UDP and TCP, and both turn and turns (TLS) connections:&lt;br /&gt;
&lt;br /&gt;
 stun: &amp;#039;&amp;#039;&amp;#039;cloud.example.com&amp;#039;&amp;#039;&amp;#039;:5349&lt;br /&gt;
 turn and turns: &amp;#039;&amp;#039;&amp;#039;cloud.example.com&amp;#039;&amp;#039;&amp;#039;:5349&lt;br /&gt;
&lt;br /&gt;
Test your server [https://webrtc.github.io/samples/src/content/peerconnection/trickle-ice/ here]. If STUN is working, you should get {{code|srflx}} candidates, and {{code|relay}} candidates if TURN is working.&lt;br /&gt;
&lt;br /&gt;
Sources and further reading:&lt;br /&gt;
* NextCloud Talk documentation: [https://nextcloud-talk.readthedocs.io/en/latest/TURN/ TURN], [https://nextcloud-talk.readthedocs.io/en/latest/coturn coturn]&lt;br /&gt;
* NextCloud Help, [https://help.nextcloud.com/t/howto-setup-nextcloud-talk-with-turn-server/30794 1] [https://help.nextcloud.com/t/nextcloud-talk-app-could-not-establish-a-connection-a-turn-server/131069/31 2]&lt;br /&gt;
* Stack Overflow [https://stackoverflow.com/questions/42801361/install-rfc5766-turn-server-trying-to-bind-fd-to-ip-address-errno-99 1]&lt;br /&gt;
* [https://ourcodeworld.com/articles/read/1526/how-to-test-online-whether-a-stun-turn-server-is-working-properly-or-not Testing STUN/TURN]&lt;br /&gt;
* Serverfault, question [https://serverfault.com/questions/849683/how-to-setup-coturn-with-letsencrypt #849683].&lt;br /&gt;
&lt;br /&gt;
=== NextCloud Office ===&lt;br /&gt;
&lt;br /&gt;
Install Collabora Office Online (COOL) which emerged from the smoking ruins of LibreOffice Online (LOOL):&lt;br /&gt;
&lt;br /&gt;
 apt install coolwsd code-brand&lt;br /&gt;
&lt;br /&gt;
Use an Apache reverse proxy to handle the host and SSL, disable SSL in WOPI setup; restrict NextCloud and coolwsd requests to their respective endpoints, IP addresses; see [https://c-nergy.be/blog/?p=18055 &amp;quot;Install CODE on NextCloud on Ubuntu 22.04&amp;quot;]&lt;br /&gt;
&lt;br /&gt;
== Maintenance ==&lt;br /&gt;
&lt;br /&gt;
Keep the git checkout of NextCloud and its submodules up to date with git, and run the OCC upgrade command:&lt;br /&gt;
&lt;br /&gt;
 cd /var/www/nextcloud&lt;br /&gt;
 git pull&lt;br /&gt;
 git submodule update --init --recursive&lt;br /&gt;
 sudo -u www-data ./occ upgrade&lt;br /&gt;
&lt;br /&gt;
=== Cron job ===&lt;br /&gt;
&lt;br /&gt;
In the administrator settings select cron rather than other methods, and put this in {{code|/etc/cron.d/nextcloud}}&lt;br /&gt;
&lt;br /&gt;
 */5 * * * * www-data /usr/bin/php /var/www/nextcloud/cron.php&lt;/div&gt;</summary>
		<author><name>Johnno</name></author>
	</entry>
	<entry>
		<id>https://wiki.jon.geek.nz/index.php?title=NextCloud&amp;diff=2518</id>
		<title>NextCloud</title>
		<link rel="alternate" type="text/html" href="https://wiki.jon.geek.nz/index.php?title=NextCloud&amp;diff=2518"/>
		<updated>2025-09-16T23:33:50Z</updated>

		<summary type="html">&lt;p&gt;Johnno: /* NextCloud Talk */ add LetsEncrypt cert fix&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Assumes Ubuntu 20.04, stable20 branch, and installing in {{code|/var/www/nextcloud}} for a cloud.&amp;#039;&amp;#039;&amp;#039;example.com&amp;#039;&amp;#039;&amp;#039; URL (c. December 2020).&lt;br /&gt;
&lt;br /&gt;
== Prerequisites ==&lt;br /&gt;
&lt;br /&gt;
Install some stuff first. This NextCloud recipe uses [[PostgreSQL]], Redis, Apache 2.4, FastCGI with PHP FPM, and Dehydrated for [[Letsencrypt]] SSL certificate maangement.&lt;br /&gt;
&lt;br /&gt;
 sudo apt install apache2 libapache2-mod-fcgid \&lt;br /&gt;
    php7.4-{bcmath,bz2,curl,gd,fpm,gmp,intl,json,mbstring,opcache,pgsql,tidy,xmlrpc,xsl,zip}&lt;br /&gt;
    php-{imagick,redis} composer dehydrated postgresql redis-server&lt;br /&gt;
&lt;br /&gt;
;NOTE: NextCloud works fine under nginx, I just can&amp;#039;t be bothered maintaining what goes in {{code|.htaccess}} which NextCloud expects to be writeable to keep itself updated.&lt;br /&gt;
&lt;br /&gt;
== Configuring Apache and PHP ==&lt;br /&gt;
&lt;br /&gt;
: &amp;#039;&amp;#039;See the [[PHP]] page for setting up PHP with Apache, FPM and Event MPM.&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
=== Add a virtual host for NextCloud ===&lt;br /&gt;
&lt;br /&gt;
It should look something like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;apache&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;VirtualHost *:443&amp;gt;&lt;br /&gt;
   ServerName cloud.example.com&lt;br /&gt;
   DocumentRoot /var/www/nextcloud &lt;br /&gt;
 &lt;br /&gt;
   &amp;lt;Directory &amp;quot;/var/www/nexcloud&amp;quot;&amp;gt;&lt;br /&gt;
     Options FollowSymLinks MultiViews&lt;br /&gt;
     AllowOverride All&lt;br /&gt;
     Require all granted&lt;br /&gt;
     Satisfy Any &lt;br /&gt;
     SetEnv HOME /var/www/nextcloud&lt;br /&gt;
     SetEnv HTTP_HOME /var/www/nextcloud&lt;br /&gt;
 &lt;br /&gt;
     &amp;lt;IfModule mod_dav.c&amp;gt;&lt;br /&gt;
       Dav off&lt;br /&gt;
     &amp;lt;/IfModule&amp;gt;&lt;br /&gt;
   &amp;lt;/Directory&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
   SSLEngine On&lt;br /&gt;
   SSLCertificateFile ...&lt;br /&gt;
 &amp;lt;/VirtualHost&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== PHP settings ===&lt;br /&gt;
&lt;br /&gt;
Enable the opcache, increase the memory limit, and increase the maximum POST and file upload size so you can upload large files.&lt;br /&gt;
&lt;br /&gt;
== Create a database ==&lt;br /&gt;
&lt;br /&gt;
Create a database in [[PostgreSQL]]:&lt;br /&gt;
&lt;br /&gt;
 sudo -u postgres createuser -SDRP &amp;#039;&amp;#039;&amp;lt;nextcloud-user&amp;gt;&amp;#039;&amp;#039;&lt;br /&gt;
 sudo -u postgres createdb -E UTF8 -O &amp;#039;&amp;#039;&amp;lt;nextcloud-user&amp;gt;&amp;#039;&amp;#039; &amp;#039;&amp;#039;&amp;lt;nextcloud-dbname&amp;gt;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
== Install NextCloud ==&lt;br /&gt;
&lt;br /&gt;
We can just clone it from git:&lt;br /&gt;
&lt;br /&gt;
 git clone &amp;lt;nowiki&amp;gt;https://&amp;lt;/nowiki&amp;gt;github.com/nextcloud/server.git nextcloud&lt;br /&gt;
 cd nextcloud&lt;br /&gt;
 git checkout stable20  &amp;#039;&amp;#039;# or whatever the latest stable version is&amp;#039;&amp;#039;&lt;br /&gt;
 git submodule update --init --recursive&lt;br /&gt;
 chown www-data:www-data config apps .htaccess&lt;br /&gt;
&lt;br /&gt;
Create a directory for the cache and user data, which should not reside under the web root:&lt;br /&gt;
&lt;br /&gt;
 mkdir -p /var/lib/nextcloud/data /var/cache/nextcloud&lt;br /&gt;
 chown -R www-data:www-data /var/lib/nextcloud /var/cache/nextcloud&lt;br /&gt;
&lt;br /&gt;
== Configure NextCloud ==&lt;br /&gt;
&lt;br /&gt;
Edit the configuration file in {{code|config/config.php}} and check or consider these settings, and add the database and SMTP connection details:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
 $config =&amp;gt; [&lt;br /&gt;
   # ...&lt;br /&gt;
   #&lt;br /&gt;
   &amp;#039;passwordsalt&amp;#039; =&amp;gt; &amp;quot;&amp;lt;very long random string&amp;gt;&amp;quot;,&lt;br /&gt;
   &amp;#039;secret&amp;#039; =&amp;gt; &amp;quot;&amp;lt;a different very long random string&amp;gt;&amp;quot;,&lt;br /&gt;
   &amp;#039;trusted_domains&amp;#039; =&amp;gt; [&lt;br /&gt;
     0 =&amp;gt; &amp;quot;cloud.example.com&amp;quot;,&lt;br /&gt;
   ],&lt;br /&gt;
   &amp;#039;datadirectory&amp;#039; =&amp;gt; &amp;#039;/var/lib/nextcloud/data&amp;#039;,&lt;br /&gt;
   &amp;#039;overwrite.cli.url&amp;#039; =&amp;gt; &amp;#039;&amp;lt;nowiki&amp;gt;https://&amp;lt;/nowiki&amp;gt;cloud.example.com/&amp;#039;,&lt;br /&gt;
   &amp;#039;htaccess.RewriteBase&amp;#039; =&amp;gt; &amp;#039;/&amp;#039;,&lt;br /&gt;
 &lt;br /&gt;
   # Database connection details&lt;br /&gt;
   &amp;#039;dbtype&amp;#039; =&amp;gt; &amp;#039;pgsql&amp;#039;,&lt;br /&gt;
   &amp;#039;dbhost&amp;#039; =&amp;gt; &amp;#039;localhost&amp;#039;,&lt;br /&gt;
   &amp;#039;dbuser&amp;#039; =&amp;gt; &amp;quot;&amp;lt;nextcloud-dbuser&amp;gt;&amp;quot;,&lt;br /&gt;
   &amp;#039;dbpassword&amp;#039; =&amp;gt; &amp;quot;&amp;lt;password&amp;gt;&amp;quot;,&lt;br /&gt;
   &amp;#039;dbname&amp;#039; =&amp;gt; &amp;quot;&amp;lt;nextcloud-dbname&amp;gt;&amp;quot;,&lt;br /&gt;
   &amp;#039;dbtableprefix&amp;#039; =&amp;gt; &amp;#039;oc_&amp;#039;,&lt;br /&gt;
 &lt;br /&gt;
   # Force all URLs to use SSL or it may trip up things like OAuth&lt;br /&gt;
   &amp;#039;overwriteprotocol&amp;#039; =&amp;gt; &amp;#039;https&amp;#039;,&lt;br /&gt;
 &lt;br /&gt;
   # Use Redis and caching to make everything go faster&lt;br /&gt;
   &amp;#039;memcache.local&amp;#039; =&amp;gt; &amp;#039;\\OC\\Memcache\\Redis&amp;#039;,&lt;br /&gt;
   &amp;#039;memcache.locking&amp;#039; =&amp;gt; &amp;#039;\\OC\\Memcache\\Redis&amp;#039;,&lt;br /&gt;
   &amp;#039;redis&amp;#039; =&amp;gt; [&lt;br /&gt;
     &amp;#039;host&amp;#039; =&amp;gt; &amp;#039;localhost&amp;#039;,&lt;br /&gt;
     &amp;#039;port&amp;#039; =&amp;gt; 6379,&lt;br /&gt;
   ],&lt;br /&gt;
   &amp;#039;cache_path&amp;#039; =&amp;gt; &amp;#039;/var/cache/nextcloud&amp;#039;,&lt;br /&gt;
 &lt;br /&gt;
   # Send email details&lt;br /&gt;
   &amp;#039;mail_smtpmode&amp;#039; =&amp;gt; &amp;#039;smtp&amp;#039;,&lt;br /&gt;
   &amp;#039;mail_smtpsecure&amp;#039; =&amp;gt; &amp;#039;tls&amp;#039;,&lt;br /&gt;
   &amp;#039;mail_sendmailmode&amp;#039; =&amp;gt; &amp;#039;smtp&amp;#039;,&lt;br /&gt;
   &amp;#039;mail_from_address&amp;#039; =&amp;gt; &amp;quot;nexcloud@example.com&amp;quot;,&lt;br /&gt;
   &amp;#039;mail_domain&amp;#039; =&amp;gt; &amp;quot;example.com&amp;quot;,&lt;br /&gt;
   &amp;#039;mail_smtpauthtype&amp;#039; =&amp;gt; &amp;#039;PLAIN&amp;#039;,&lt;br /&gt;
   &amp;#039;mail_smtpauth&amp;#039; =&amp;gt; 1,&lt;br /&gt;
   &amp;#039;mail_smtphost&amp;#039; =&amp;gt; &amp;quot;mail.example.com&amp;quot;,&lt;br /&gt;
   &amp;#039;mail_smtpport&amp;#039; =&amp;gt; 587,&lt;br /&gt;
   &amp;#039;mail_smtpname&amp;#039; =&amp;gt; &amp;quot;&amp;lt;emailuser&amp;gt;&amp;quot;,&lt;br /&gt;
   &amp;#039;mail_smtppassword&amp;#039; =&amp;gt; &amp;quot;&amp;lt;emailpassword&amp;gt;&amp;quot;,&lt;br /&gt;
 &lt;br /&gt;
   # ...&lt;br /&gt;
 ]  &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then navigate to the URL in the browser to install (or run the NextCloud {{code | ./occ}} tool from the command line).&lt;br /&gt;
&lt;br /&gt;
;Note: Make sure that the directory used for {{code|cache_path}} exists and is writeable, or you will get weird seemingly unrelated 403 MKCOL errors to do with [https://docs.nextcloud.com/server/26/admin_manual/configuration_files/big_file_upload_configuration.html chunked uploads].&lt;br /&gt;
&lt;br /&gt;
=== Clean URLs ===&lt;br /&gt;
&lt;br /&gt;
For clean URLs, make sure {{code | AllowOverride All}} is set for the parent directory; the {{code | /var/www}} definition is in the main {{code | /etc/apache2/apache.conf}}. Then run the follwing OCC command to enable the rewrite rules:&lt;br /&gt;
&lt;br /&gt;
 sudo -u www-data ./occ maintenance:update:htaccess&lt;br /&gt;
&lt;br /&gt;
=== Previews of other file types ===&lt;br /&gt;
&lt;br /&gt;
Edit {{code|/etc/ImageMagick/policy.xml}} and remove this line to get PDF previews to work:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;policy domain=&amp;quot;coder&amp;quot; rights=&amp;quot;none&amp;quot; pattern=&amp;quot;PDF&amp;quot; /&amp;gt; &amp;lt;!-- remove this line --&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then add the following to {{code|config.php}} to get lots of other useful file previews:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
   &amp;#039;enabledPreviewProviders&amp;#039; =&amp;gt; [&lt;br /&gt;
     # ...&lt;br /&gt;
     8 =&amp;gt; &amp;#039;OC\\Preview\\MarkDown&amp;#039;,&lt;br /&gt;
     9 =&amp;gt; &amp;#039;OC\\Preview\\Movie&amp;#039;,&lt;br /&gt;
     10 =&amp;gt; &amp;#039;OC\\Preview\\PDF&amp;#039;,&lt;br /&gt;
     11 =&amp;gt; &amp;#039;OC\\Preview\\OpenDocument&amp;#039;,&lt;br /&gt;
     12 =&amp;gt; &amp;#039;OC\\Preview\\MSOfficeDoc&amp;#039;,&lt;br /&gt;
     13 =&amp;gt; &amp;#039;OC\\Preview\\MSOffice2003&amp;#039;,&lt;br /&gt;
     14 =&amp;gt; &amp;#039;OC\\Preview\\MSOffice2007&amp;#039;,&lt;br /&gt;
   ],&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Photos ===&lt;br /&gt;
&lt;br /&gt;
Photos replaces the Gallery app, and is installed separately through the NC store or you can use git to manage it as a submodule. If it doesn&amp;#039;t work you might need to build its JavaScript resources by running {{code|make}} in its {{code|apps/photos}} directory. Alternatively you can resuscitate the Gallery app, which stopped working after NextCloud version 17, by updating its JavaScript dompurify library to a [https://raw.githubusercontent.com/nextcloud/gallery/ecb26a812f30a3f516964808ccfa6430be09b45e/js/vendor/dompurify/src/purify.js newer version] and bumping the app max version in {{code|apps/galleryappinfo/info.xml}} as follows (See also [https://github.com/nextcloud/gallery/pull/570/ pull request #570]):&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nextcloud min-version=&amp;quot;17&amp;quot; max-version=&amp;quot;&amp;#039;&amp;#039;&amp;#039;20&amp;#039;&amp;#039;&amp;#039;&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== NextCloud Talk ===&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;Note:&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039; &amp;#039;&amp;#039;A TURN server can also be used for other things, like your own [https://matrix-org.github.io/synapse/v1.41/turn-howto.html Matrix] chat server.&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
To be at all useful, you need a TURN server. This is easiest achieved by installing and correctly configuring coturn, which also acts as a STUN server. STUN is for clients to figure out their external IP address, and TURN is for relaying UDP packets, e.g. for WebRTC.&lt;br /&gt;
&lt;br /&gt;
 sudo apt install coturn&lt;br /&gt;
&lt;br /&gt;
For it to actually do anything (it is disabled by default!) you need to edit {{code|/etc/default/coturn}} and make sure it contains the following, and is not commented out:&lt;br /&gt;
&lt;br /&gt;
 TURNSERVER_ENABLED=1&lt;br /&gt;
&lt;br /&gt;
Then in {{code|/etc/turnserver.conf}} you need to configure its domain name, IP addresses and ports, SSL certificate, and how TURN authenticates. See GitHub for a fully documented example [https://github.com/coturn/coturn/blob/master/examples/etc/turnserver.conf turnserver.conf] file. This example uses the same domain as the NextCloud instance, on the standard STUN and TURN ports, but if you want to host it on port 443 to support people behind restrictive firewalls, you will need a different subdomain and/or IP address:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;ini&amp;quot;&amp;gt;&lt;br /&gt;
 server-name=cloud.example.com&lt;br /&gt;
 realm=cloud.example.com&lt;br /&gt;
 &lt;br /&gt;
 # When hosted on an internal LAN or DMZ, it might look like this: &lt;br /&gt;
 listening-ip=192.168.1.100&lt;br /&gt;
 relay-ip=192.168.1.100&lt;br /&gt;
 external-ip=123.45.67.8&lt;br /&gt;
 &lt;br /&gt;
 # Or use the short-hand:&lt;br /&gt;
 external-ip=123.45.67.8/192.168.1.100&lt;br /&gt;
 &lt;br /&gt;
 # Specify listening ports; originally 3478 was unencrypted, and 5349 was TLS,&lt;br /&gt;
 # but now TLS is supported on both. It is possible to listen on 443, which will&lt;br /&gt;
 # help to provide connectivity for people behind port-limited firewalls; this will&lt;br /&gt;
 # conflict with any HTTPS web hosting on the same server though, unless you set&lt;br /&gt;
 # up a second IP address for it.&lt;br /&gt;
 listening-port=3478&lt;br /&gt;
 tls-listening-port=5349&lt;br /&gt;
 #tls-listening-port=443&lt;br /&gt;
 &lt;br /&gt;
 # Specify a UDP port range and ensure they are exposed through the firewall/router&lt;br /&gt;
 min-port=53490&lt;br /&gt;
 max-port=59999&lt;br /&gt;
 &lt;br /&gt;
 # SSL setup; &lt;br /&gt;
 cert=/path/to/cloud.example.com/fullchain.cert&lt;br /&gt;
 pkey=/path/to/cloud.example.com/privkey.pem&lt;br /&gt;
 no-tlsv1&lt;br /&gt;
 no-tlsv1_1&lt;br /&gt;
 &lt;br /&gt;
 # To use with NextCloud, set a shared secret here.&lt;br /&gt;
 use-auth-secret&lt;br /&gt;
 static-auth-secret=your-shared-secret-string-here&lt;br /&gt;
 stale-nonce=600&lt;br /&gt;
 &lt;br /&gt;
 # Limit STUN amplification/gain attacks (coturn 4.5.2+)&lt;br /&gt;
 no-stun-backward-compatibility&lt;br /&gt;
 response-origin-only-with-rfc5780&lt;br /&gt;
 &lt;br /&gt;
 # RFC-5780 support requires two listening IP addresses and is for serious-cat&lt;br /&gt;
 # usage, so you can safely disable it for a small home NextCloud instance.&lt;br /&gt;
 no-rfc5780&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that the coturn user can&amp;#039;t read certificates in &amp;lt;code&amp;gt;/etc/ssl/letsencrypt&amp;lt;/code&amp;gt; so you will need a deploy hook script to copy them safely to somewhere it can read them:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;sh&amp;quot;&amp;gt;&lt;br /&gt;
#!/bin/sh&lt;br /&gt;
# /etc/letsencrypt/renewal-hooks/deploy/coturn&lt;br /&gt;
set -e&lt;br /&gt;
for domain in $RENEWED_DOMAINS; do&lt;br /&gt;
    case $domain in&lt;br /&gt;
    cloud.example.com)&lt;br /&gt;
        certs=/etc/coturn/certs&lt;br /&gt;
        fullchain=&amp;quot;${certs}/${domain}_fullchain.pem&amp;quot;&lt;br /&gt;
        key=&amp;quot;${certs}/${domain}_privkey.pem&amp;quot;&lt;br /&gt;
&lt;br /&gt;
        # certificate and private key files are never world readable&lt;br /&gt;
        umask 077&lt;br /&gt;
        cp &amp;quot;${RENEWED_LINEAGE}/fullchain.pem&amp;quot; &amp;quot;$fullchain&amp;quot;&lt;br /&gt;
        cp &amp;quot;${RENEWED_LINEAGE}/privkey.pem&amp;quot; &amp;quot;$key&amp;quot;&lt;br /&gt;
&lt;br /&gt;
        chown turnserver:turnserver &amp;quot;$fullchain&amp;quot; &amp;quot;$key&amp;quot;&lt;br /&gt;
        chmod 400 &amp;quot;$fullchain&amp;quot; &amp;quot;$key&amp;quot;&lt;br /&gt;
&lt;br /&gt;
        service coturn restart &amp;gt; /dev/null&lt;br /&gt;
        ;;&lt;br /&gt;
    esac&lt;br /&gt;
done&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In your NextCloud Administration section, you can now configure Talk to use the STUN/TURN server, using your server URLs, and provide the same shared secret you configured above. For maximum compatibility, use both UDP and TCP, and both turn and turns (TLS) connections:&lt;br /&gt;
&lt;br /&gt;
 stun: &amp;#039;&amp;#039;&amp;#039;cloud.example.com&amp;#039;&amp;#039;&amp;#039;:5349&lt;br /&gt;
 turn and turns: &amp;#039;&amp;#039;&amp;#039;cloud.example.com&amp;#039;&amp;#039;&amp;#039;:5349&lt;br /&gt;
&lt;br /&gt;
Test your server [https://webrtc.github.io/samples/src/content/peerconnection/trickle-ice/ here]. If STUN is working, you should get {{code|srflx}} candidates, and {{code|relay}} candidates if TURN is working.&lt;br /&gt;
&lt;br /&gt;
Sources and further reading:&lt;br /&gt;
* NextCloud Talk documentation: [https://nextcloud-talk.readthedocs.io/en/latest/TURN/ TURN], [https://nextcloud-talk.readthedocs.io/en/latest/coturn coturn]&lt;br /&gt;
* NextCloud Help, [https://help.nextcloud.com/t/howto-setup-nextcloud-talk-with-turn-server/30794 1] [https://help.nextcloud.com/t/nextcloud-talk-app-could-not-establish-a-connection-a-turn-server/131069/31 2]&lt;br /&gt;
* Stack Overflow [https://stackoverflow.com/questions/42801361/install-rfc5766-turn-server-trying-to-bind-fd-to-ip-address-errno-99 1]&lt;br /&gt;
* [https://ourcodeworld.com/articles/read/1526/how-to-test-online-whether-a-stun-turn-server-is-working-properly-or-not Testing STUN/TURN]&lt;br /&gt;
* Serverfault, question [https://serverfault.com/questions/849683/how-to-setup-coturn-with-letsencrypt #849683].&lt;br /&gt;
&lt;br /&gt;
=== NextCloud Office ===&lt;br /&gt;
&lt;br /&gt;
Install Collabora Office Online (COOL) which emerged from the smoking ruins of LibreOffice Online (LOOL):&lt;br /&gt;
&lt;br /&gt;
 apt install coolwsd code-brand&lt;br /&gt;
&lt;br /&gt;
Use an Apache reverse proxy to handle the host and SSL, disable SSL in WOPI setup; restrict NextCloud and coolwsd requests to their respective endpoints, IP addresses; see [https://c-nergy.be/blog/?p=18055 &amp;quot;Install CODE on NextCloud on Ubuntu 22.04&amp;quot;]&lt;br /&gt;
&lt;br /&gt;
== Maintenance ==&lt;br /&gt;
&lt;br /&gt;
Keep the git checkout of NextCloud and its submodules up to date with git, and run the OCC upgrade command:&lt;br /&gt;
&lt;br /&gt;
 cd /var/www/nextcloud&lt;br /&gt;
 git pull&lt;br /&gt;
 git submodule update --init --recursive&lt;br /&gt;
 sudo -u www-data ./occ upgrade&lt;br /&gt;
&lt;br /&gt;
=== Cron job ===&lt;br /&gt;
&lt;br /&gt;
In the administrator settings select cron rather than other methods, and put this in {{code|/etc/cron.d/nextcloud}}&lt;br /&gt;
&lt;br /&gt;
 */5 * * * * www-data /usr/bin/php /var/www/nextcloud/cron.php&lt;/div&gt;</summary>
		<author><name>Johnno</name></author>
	</entry>
	<entry>
		<id>https://wiki.jon.geek.nz/index.php?title=PHP&amp;diff=2517</id>
		<title>PHP</title>
		<link rel="alternate" type="text/html" href="https://wiki.jon.geek.nz/index.php?title=PHP&amp;diff=2517"/>
		<updated>2025-05-07T00:52:36Z</updated>

		<summary type="html">&lt;p&gt;Johnno: /* Keep your PHP custom settings and tweaks separate */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;: &amp;#039;&amp;#039;These instructions assume Ubuntu LTS (24.04, c. May 2025) but are easily adapted to Debian, a Docker or other container definition, Ansible playbook, etc.&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
There&amp;#039;s a lot of talk about using Nginx instead of Apache, and for some things it&amp;#039;s probably easier to configure or maintain, especially if you&amp;#039;re writing IaC, but some things still assume or prefer Apache, particularly in PHP land. [[WordPress]] and [[NextCloud]] are example PHP applications that want to modify their {{code|.htaccess}} files in-place, for example to keep up with security developments.&lt;br /&gt;
&lt;br /&gt;
Perhaps part of the reason for the currently fashionable dim view of Apache&amp;#039;s performance is that PHP is often run in production using mod-php, which &amp;#039;&amp;#039;at best&amp;#039;&amp;#039; should only be used on a development workstation, if at all. Apart from being incompatible with HTTP/2, it is a CPU and memory hog, since it can only run using Apache&amp;#039;s horribly inefficient prefork multi-process management (MPM). Apache has several modules for dealing with MPM, but can only have one MPM module enabled at a time. Other much better, multithreaded, more efficient and fast MPM modules have been around for nearly two decades, and since version 5.4 of PHP (late 2011) we can use Apache&amp;#039;s Event MPM and FastCGI modules with PHP-FPM. More information is available on the Apache [https://cwiki.apache.org/confluence/display/httpd/PHP-FPM httpd wiki].&lt;br /&gt;
&lt;br /&gt;
With PHP processes being handled much more efficiently, and by being able to finally enable HTTP/2 in Apache, it all actually goes like the clappers.&lt;br /&gt;
&lt;br /&gt;
== Prerequisites ==&lt;br /&gt;
&lt;br /&gt;
Install at least the following packages:&lt;br /&gt;
&lt;br /&gt;
 sudo apt install apache2 libapache2-mod-fcgid php-fpm php8.3-{fpm,opcache}&lt;br /&gt;
&lt;br /&gt;
You&amp;#039;ll need various PHP extensions to host a real PHP application; for example [[NextCloud]] requires PHP composer, [[PostgreSQL]], Redis, and Dehydrated is useful for managing [[Letsencrypt]] SSL certificates.&lt;br /&gt;
&lt;br /&gt;
 sudo apt install php-{imagick,redis} \&lt;br /&gt;
     php8.3-{bcmath,bz2,curl,gd,gmp,intl,json,mbstring,pgsql,soap,tidy,xmlrpc,xsl,zip} \&lt;br /&gt;
     composer postgresql redis-server dehydrated&lt;br /&gt;
&lt;br /&gt;
== Set up Apache == &lt;br /&gt;
&lt;br /&gt;
Enable the required Apache configurations and modules:&lt;br /&gt;
&lt;br /&gt;
 a2enconf php8.3-fpm&lt;br /&gt;
 a2enmod dir env headers http2 mpm_event proxy_fcgi rewrite setenvif ssl&lt;br /&gt;
 systemctl restart apache2&lt;br /&gt;
&lt;br /&gt;
You should now be able to define your virtual hosts in {{code|/etc/apache2/sites-available}} and enable them, with PHP support.&lt;br /&gt;
&lt;br /&gt;
=== Deny access to git repositories ===&lt;br /&gt;
&lt;br /&gt;
Add a global config to deny access to git repositories and other hidden stuff, in {{code|/etc/apache2/conf-available/deny-git.conf}}:&lt;br /&gt;
&lt;br /&gt;
 &amp;#039;&amp;#039;# /etc/apache2/conf-available/deny-git.conf&amp;#039;&amp;#039;&lt;br /&gt;
 &amp;lt;LocationMatch &amp;quot;/\.(git|hg|bzr|svn|cvs|tag|ht)&amp;quot;&amp;gt;&lt;br /&gt;
   # Old apache:&lt;br /&gt;
   # Order deny,allow&lt;br /&gt;
   # deny from all&lt;br /&gt;
   Require all denied&lt;br /&gt;
 &amp;lt;/LocationMatch&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then enable it with:&lt;br /&gt;
&lt;br /&gt;
 a2enconf deny-git&lt;br /&gt;
 systemctl reload apache2&lt;br /&gt;
&lt;br /&gt;
=== Add a virtual host ===&lt;br /&gt;
&lt;br /&gt;
A virtual host for a typical PHP web application should look something like this:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;VirtualHost *:443&amp;gt;&lt;br /&gt;
   ServerName app.&amp;#039;&amp;#039;&amp;#039;example.com&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   DocumentRoot /var/www/app&lt;br /&gt;
 &lt;br /&gt;
   &amp;lt;Directory &amp;quot;/var/www/app&amp;quot;&amp;gt;&lt;br /&gt;
     Options FollowSymLinks MultiViews&lt;br /&gt;
     AllowOverride All&lt;br /&gt;
     Require all granted&lt;br /&gt;
   &amp;lt;/Directory&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
   SSLEngine On&lt;br /&gt;
   SSLCertificateFile ...&lt;br /&gt;
 &amp;lt;/VirtualHost&amp;gt;&lt;br /&gt;
&lt;br /&gt;
See the [[Letsencrypt]] page for how to sort out your SSL certificates on pet servers.&lt;br /&gt;
&lt;br /&gt;
== Configure PHP ==&lt;br /&gt;
&lt;br /&gt;
The configuration for PHP code hosted by Apache using PHP-FPM is located under {{code|/etc/php/8.3/fpm}}.&lt;br /&gt;
&lt;br /&gt;
You will not be able to use mod-php {{code|php_value}} directives in Apache configuration; either try and do without, or set environment variables instead.&lt;br /&gt;
&lt;br /&gt;
PHP works a lot better with a few extra things configured. Enable the opcache, increase the memory limit, and depending on what you&amp;#039;re hosting, increase the maximum POST size so users can upload photos and other large files. Other fun helpful things include using Redis for PHP sessions, and tuning the FPM process parameters to make stuff more efficient under load.&lt;br /&gt;
&lt;br /&gt;
=== Keep your PHP custom settings and tweaks separate ===&lt;br /&gt;
&lt;br /&gt;
Since Debian/Ubuntu now moves files around with each new version of PHP, you can keep your customisations to the {{code|php.ini}} file in a local configuration. For example, instead of editing {{code|/etc/php/8.3/fpm/php.ini}}, put these settings in {{code|/etc/php/local/php.ini}}:&lt;br /&gt;
&lt;br /&gt;
 ; /etc/php/local/php.ini&lt;br /&gt;
 ; Override settings in the dist php.ini here&lt;br /&gt;
 ; make a symbolic link to this file in /etc/php/&amp;#039;&amp;#039;&amp;lt;version&amp;gt;&amp;#039;&amp;#039;/fpm/conf.d/99-local.ini&lt;br /&gt;
 max_execution_time = 60&lt;br /&gt;
 memory_limit = 512M&lt;br /&gt;
 post_max_size = 500M&lt;br /&gt;
 upload_max_filesize = 500M&lt;br /&gt;
 opcache.enable=1&lt;br /&gt;
&lt;br /&gt;
Then we add a symbolic link in the {{code|conf.d}} directory where it is needed, for example when new versions of PHP are released.&lt;br /&gt;
&lt;br /&gt;
 ln -s /etc/php/local/php.ini /etc/php/8.3/fpm/conf.d/99-local.ini&lt;/div&gt;</summary>
		<author><name>Johnno</name></author>
	</entry>
	<entry>
		<id>https://wiki.jon.geek.nz/index.php?title=PHP&amp;diff=2516</id>
		<title>PHP</title>
		<link rel="alternate" type="text/html" href="https://wiki.jon.geek.nz/index.php?title=PHP&amp;diff=2516"/>
		<updated>2025-05-07T00:38:03Z</updated>

		<summary type="html">&lt;p&gt;Johnno: Update to 24.04 LTS and PHP 8.3&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;: &amp;#039;&amp;#039;These instructions assume Ubuntu LTS (24.04, c. May 2025) but are easily adapted to Debian, a Docker or other container definition, Ansible playbook, etc.&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
There&amp;#039;s a lot of talk about using Nginx instead of Apache, and for some things it&amp;#039;s probably easier to configure or maintain, especially if you&amp;#039;re writing IaC, but some things still assume or prefer Apache, particularly in PHP land. [[WordPress]] and [[NextCloud]] are example PHP applications that want to modify their {{code|.htaccess}} files in-place, for example to keep up with security developments.&lt;br /&gt;
&lt;br /&gt;
Perhaps part of the reason for the currently fashionable dim view of Apache&amp;#039;s performance is that PHP is often run in production using mod-php, which &amp;#039;&amp;#039;at best&amp;#039;&amp;#039; should only be used on a development workstation, if at all. Apart from being incompatible with HTTP/2, it is a CPU and memory hog, since it can only run using Apache&amp;#039;s horribly inefficient prefork multi-process management (MPM). Apache has several modules for dealing with MPM, but can only have one MPM module enabled at a time. Other much better, multithreaded, more efficient and fast MPM modules have been around for nearly two decades, and since version 5.4 of PHP (late 2011) we can use Apache&amp;#039;s Event MPM and FastCGI modules with PHP-FPM. More information is available on the Apache [https://cwiki.apache.org/confluence/display/httpd/PHP-FPM httpd wiki].&lt;br /&gt;
&lt;br /&gt;
With PHP processes being handled much more efficiently, and by being able to finally enable HTTP/2 in Apache, it all actually goes like the clappers.&lt;br /&gt;
&lt;br /&gt;
== Prerequisites ==&lt;br /&gt;
&lt;br /&gt;
Install at least the following packages:&lt;br /&gt;
&lt;br /&gt;
 sudo apt install apache2 libapache2-mod-fcgid php-fpm php8.3-{fpm,opcache}&lt;br /&gt;
&lt;br /&gt;
You&amp;#039;ll need various PHP extensions to host a real PHP application; for example [[NextCloud]] requires PHP composer, [[PostgreSQL]], Redis, and Dehydrated is useful for managing [[Letsencrypt]] SSL certificates.&lt;br /&gt;
&lt;br /&gt;
 sudo apt install php-{imagick,redis} \&lt;br /&gt;
     php8.3-{bcmath,bz2,curl,gd,gmp,intl,json,mbstring,pgsql,soap,tidy,xmlrpc,xsl,zip} \&lt;br /&gt;
     composer postgresql redis-server dehydrated&lt;br /&gt;
&lt;br /&gt;
== Set up Apache == &lt;br /&gt;
&lt;br /&gt;
Enable the required Apache configurations and modules:&lt;br /&gt;
&lt;br /&gt;
 a2enconf php8.3-fpm&lt;br /&gt;
 a2enmod dir env headers http2 mpm_event proxy_fcgi rewrite setenvif ssl&lt;br /&gt;
 systemctl restart apache2&lt;br /&gt;
&lt;br /&gt;
You should now be able to define your virtual hosts in {{code|/etc/apache2/sites-available}} and enable them, with PHP support.&lt;br /&gt;
&lt;br /&gt;
=== Deny access to git repositories ===&lt;br /&gt;
&lt;br /&gt;
Add a global config to deny access to git repositories and other hidden stuff, in {{code|/etc/apache2/conf-available/deny-git.conf}}:&lt;br /&gt;
&lt;br /&gt;
 &amp;#039;&amp;#039;# /etc/apache2/conf-available/deny-git.conf&amp;#039;&amp;#039;&lt;br /&gt;
 &amp;lt;LocationMatch &amp;quot;/\.(git|hg|bzr|svn|cvs|tag|ht)&amp;quot;&amp;gt;&lt;br /&gt;
   # Old apache:&lt;br /&gt;
   # Order deny,allow&lt;br /&gt;
   # deny from all&lt;br /&gt;
   Require all denied&lt;br /&gt;
 &amp;lt;/LocationMatch&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then enable it with:&lt;br /&gt;
&lt;br /&gt;
 a2enconf deny-git&lt;br /&gt;
 systemctl reload apache2&lt;br /&gt;
&lt;br /&gt;
=== Add a virtual host ===&lt;br /&gt;
&lt;br /&gt;
A virtual host for a typical PHP web application should look something like this:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;VirtualHost *:443&amp;gt;&lt;br /&gt;
   ServerName app.&amp;#039;&amp;#039;&amp;#039;example.com&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   DocumentRoot /var/www/app&lt;br /&gt;
 &lt;br /&gt;
   &amp;lt;Directory &amp;quot;/var/www/app&amp;quot;&amp;gt;&lt;br /&gt;
     Options FollowSymLinks MultiViews&lt;br /&gt;
     AllowOverride All&lt;br /&gt;
     Require all granted&lt;br /&gt;
   &amp;lt;/Directory&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
   SSLEngine On&lt;br /&gt;
   SSLCertificateFile ...&lt;br /&gt;
 &amp;lt;/VirtualHost&amp;gt;&lt;br /&gt;
&lt;br /&gt;
See the [[Letsencrypt]] page for how to sort out your SSL certificates on pet servers.&lt;br /&gt;
&lt;br /&gt;
== Configure PHP ==&lt;br /&gt;
&lt;br /&gt;
The configuration for PHP code hosted by Apache using PHP-FPM is located under {{code|/etc/php/8.3/fpm}}.&lt;br /&gt;
&lt;br /&gt;
You will not be able to use mod-php {{code|php_value}} directives in Apache configuration; either try and do without, or set environment variables instead.&lt;br /&gt;
&lt;br /&gt;
PHP works a lot better with a few extra things configured. Enable the opcache, increase the memory limit, and depending on what you&amp;#039;re hosting, increase the maximum POST size so users can upload photos and other large files. Other fun helpful things include using Redis for PHP sessions, and tuning the FPM process parameters to make stuff more efficient under load.&lt;br /&gt;
&lt;br /&gt;
=== Keep your PHP custom settings and tweaks separate ===&lt;br /&gt;
&lt;br /&gt;
Since Debian/Ubuntu now moves files around with each new version of PHP, you can keep your customisations to the {{code|php.ini}} file in a local configuration. For example, instead of editing {{code|/etc/php/8.3/fpm/php.ini}}, put these settings in {{code|/etc/php/local/php.ini}}:&lt;br /&gt;
&lt;br /&gt;
 ; /etc/php/local/php.ini&lt;br /&gt;
 ; Override settings in the dist php.ini here&lt;br /&gt;
 ; make a symbolic link to this file in /etc/php/&amp;#039;&amp;#039;&amp;lt;version&amp;gt;&amp;#039;&amp;#039;/fpm/conf.d/99-local.ini&lt;br /&gt;
 max_execution_time = 60&lt;br /&gt;
 memory_limit = 512M&lt;br /&gt;
 post_max_size = 500M&lt;br /&gt;
 upload_max_filesize = 500M&lt;br /&gt;
 opcache.enable=1&lt;br /&gt;
&lt;br /&gt;
Then we add a symbolic link in the {{code|conf.d}} directory where you need it, for example:&lt;br /&gt;
&lt;br /&gt;
 ln -s /etc/php/local/php.ini /etc/php/8.3/fpm/conf.d/99-local.ini&lt;/div&gt;</summary>
		<author><name>Johnno</name></author>
	</entry>
	<entry>
		<id>https://wiki.jon.geek.nz/index.php?title=LXC&amp;diff=2515</id>
		<title>LXC</title>
		<link rel="alternate" type="text/html" href="https://wiki.jon.geek.nz/index.php?title=LXC&amp;diff=2515"/>
		<updated>2025-03-17T20:29:40Z</updated>

		<summary type="html">&lt;p&gt;Johnno: /* Set up a SSH shortcut for containers */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;#039;&amp;#039;&amp;#039;LXC&amp;#039;&amp;#039;&amp;#039;, or &amp;#039;&amp;#039;&amp;#039;Linux Containers&amp;#039;&amp;#039;&amp;#039;, is a lightweight chroot-style virtual machine emulation in the main Linux kernel; most modern distributions should have it. The [https://help.ubuntu.com/serverguide/lxc.html LXC Ubuntu Server Guide] is very good and contains pretty much all you need to know. A lot of work has been done on 14.04 to make it very simple to get started and now supports unprivileged containers. These instructions assume Ubuntu 14.04 LTS.&lt;br /&gt;
&lt;br /&gt;
== Install and set up LXC containers ==&lt;br /&gt;
&lt;br /&gt;
In sum, we install LXC and create a base container, set it up nicely, then clone project containers from it as required. Here&amp;#039;s roughly what I had to do to set up LXC nicely.&lt;br /&gt;
&lt;br /&gt;
 sudo apt-get install lxc&lt;br /&gt;
&lt;br /&gt;
=== Optional: user configuration for unprivileged containers ===&lt;br /&gt;
&lt;br /&gt;
You can use unprivileged containers, i.e. you don&amp;#039;t need to use sudo all the time, and the containers live in your &amp;lt;code&amp;gt;~/.local/share/lxc&amp;lt;/code&amp;gt; directory. The Ubuntu Server Guide tells you all you need to know to set this up; the short version is that unprivileged containers use user namespaces, so you need to create a subuid and subgid mapping for your user and allow your user to access the bridge network:&lt;br /&gt;
&lt;br /&gt;
 sudo usermod -v 100000-200000 -w 100000-200000 $USER&lt;br /&gt;
 echo &amp;quot;$USER veth lxcbr0 2&amp;quot; | sudo tee -a /etc/lxc/lxc-usernet&lt;br /&gt;
&lt;br /&gt;
Then configure your user account for LXC containers, :&lt;br /&gt;
&lt;br /&gt;
 mkdir -p ~/.config/lxc&lt;br /&gt;
 echo &amp;quot;lxc.include = /etc/lxc/default.conf&lt;br /&gt;
 lxc.idmap = u 0 100000 65536&lt;br /&gt;
 lxc.idmap = g 0 100000 65536&amp;quot; &amp;gt; ~/.config/lxc/default.conf&lt;br /&gt;
&lt;br /&gt;
=== Create a base container to serve as a template ===&lt;br /&gt;
&lt;br /&gt;
The -d -r and -a options are distribution, release, and architecture.&lt;br /&gt;
&lt;br /&gt;
 lxc-create -t download -n base -- -d ubuntu -r trusty -a amd64&lt;br /&gt;
 lxc-start -n base&lt;br /&gt;
&lt;br /&gt;
Log in with the default account, (username ubuntu, password &amp;#039;&amp;#039;ubuntu&amp;#039;&amp;#039;), then add yourself as a user with sudo:&lt;br /&gt;
&lt;br /&gt;
 sudo adduser &amp;#039;&amp;#039;&amp;#039;username&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
 sudo adduser &amp;#039;&amp;#039;&amp;#039;username&amp;#039;&amp;#039;&amp;#039; sudo&lt;br /&gt;
&lt;br /&gt;
This installs some nifty default guff, fixes the probably broken UTC timezone, and fixes locales BEFORE you install things that expect UTF-8 locales, but in particular [[PostgreSQL]] (otherwise you end up with SQL_ASCII encoding and nobody wants that):&lt;br /&gt;
&lt;br /&gt;
 sudo apt-get install git bash-completion language-pack-en openssh-server&lt;br /&gt;
 sudo dpkg-reconfigure tzdata&lt;br /&gt;
&lt;br /&gt;
=== Set up a SSH shortcut for containers ===&lt;br /&gt;
&lt;br /&gt;
Back on your host workstation, set up an SSH shortcut. If you add the following to your ~/.ssh/config, you will be able to ssh to your containers nice and easily:&lt;br /&gt;
&lt;br /&gt;
 # LXC containers&lt;br /&gt;
 Host *.lxc&lt;br /&gt;
   StrictHostKeyChecking no&lt;br /&gt;
   UserKnownHostsFile /dev/null&lt;br /&gt;
   ProxyCommand nc $(host -t A $(echo %h | sed &amp;quot;s/\.lxc//g&amp;quot;) 10.0.3.1 | tail -1 | awk &amp;#039;{print $NF}&amp;#039;) %p&lt;br /&gt;
&lt;br /&gt;
Then one can ssh to the containers by appending .lxc to the container name:&lt;br /&gt;
&lt;br /&gt;
 ssh myproject.lxc&lt;br /&gt;
&lt;br /&gt;
and then schlepp your handy stuff over:&lt;br /&gt;
&lt;br /&gt;
 scp -rp ~/.bashrc ~/.vim* ~/.gitconfig base.lxc:&lt;br /&gt;
 scp ~/.ssh/authorized_keys base.lxc:.ssh/authorized_keys&lt;br /&gt;
&lt;br /&gt;
=== Clone a new project container from the template ===&lt;br /&gt;
&lt;br /&gt;
Now you should have a useful base container, so clone it for your &amp;#039;&amp;#039;nifty-kitten&amp;#039;&amp;#039; project and start it (most usefully in a screen session):&lt;br /&gt;
&lt;br /&gt;
 lxc-shutdown -n base&lt;br /&gt;
 lxc-clone -o base -n &amp;#039;&amp;#039;&amp;#039;nifty-kitten&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
 screen&lt;br /&gt;
 lxc-start -n &amp;#039;&amp;#039;&amp;#039;nifty-kitten&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
 &amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;[Ctrl-a] [d]&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039; &amp;#039;&amp;#039;to detach&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
 ssh nifty-kitten.lxc&lt;/div&gt;</summary>
		<author><name>Johnno</name></author>
	</entry>
	<entry>
		<id>https://wiki.jon.geek.nz/index.php?title=Git&amp;diff=2514</id>
		<title>Git</title>
		<link rel="alternate" type="text/html" href="https://wiki.jon.geek.nz/index.php?title=Git&amp;diff=2514"/>
		<updated>2025-03-03T00:24:59Z</updated>

		<summary type="html">&lt;p&gt;Johnno: /* Installing Gitea */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Handy git configuration ==&lt;br /&gt;
&lt;br /&gt;
Put this in your ~/.gitconfig&lt;br /&gt;
&lt;br /&gt;
 [alias]&lt;br /&gt;
     lol = log --graph --decorate --oneline&lt;br /&gt;
     cdiff = diff --word-diff-regex=.&lt;br /&gt;
     cshow = show --word-diff-regex=.&lt;br /&gt;
     wdiff = diff --word-diff-regex=[^[:space:]]+&lt;br /&gt;
     wshow = show --word-diff-regex=[^[:space:]]+ [color]&lt;br /&gt;
 [color]&lt;br /&gt;
     diff = auto&lt;br /&gt;
     branch = auto&lt;br /&gt;
     log = auto&lt;br /&gt;
     status = auto&lt;br /&gt;
 [push]&lt;br /&gt;
     default = current&lt;br /&gt;
 [user]&lt;br /&gt;
     name = Harry Potter&lt;br /&gt;
     email = harry@hogwarts.school.uk&lt;br /&gt;
 [core]&lt;br /&gt;
     autocrlf = input&lt;br /&gt;
     pager = less -F -X&lt;br /&gt;
&lt;br /&gt;
Bung these in your ~/.bashrc&lt;br /&gt;
&lt;br /&gt;
 export GIT_AUTHOR_NAME=&amp;#039;Harry Potter&amp;#039;&lt;br /&gt;
 export GIT_AUTHOR_EMAIL=&amp;#039;harry@hogwarts.school.uk&amp;#039;&lt;br /&gt;
 export GIT_COMMITTER_NAME=$GIT_AUTHOR_NAME&lt;br /&gt;
 export GIT_COMMITTER_EMAIL=$GIT_AUTHOR_EMAIL&lt;br /&gt;
 export GIT_PS1_SHOWDIRTYSTATE=1&lt;br /&gt;
 export GIT_PS1_SHOWUNTRACKEDFILES=1&lt;br /&gt;
 export GIT_PS1_SHOWUPSTREAM=auto&lt;br /&gt;
 &lt;br /&gt;
 # very handy to have your git branch and checkout status in your prompt:&lt;br /&gt;
 export PS1=&amp;#039;\[\e[1m\]\u@\h:\w\[\e[32;1m\]$(__git_ps1 &amp;quot;(%s)&amp;quot;)\[\e[m\e[1m\]\$\[\e[m\] &amp;#039;&lt;br /&gt;
&lt;br /&gt;
== Track Mercurial transparently with git ==&lt;br /&gt;
&lt;br /&gt;
To track a project hosted in a Mercurial repository, we can use the nifty hg-fast-export package. Install Mercurial and its fast export:&lt;br /&gt;
&lt;br /&gt;
 sudo apt-get install mercurial hg-fast-export&lt;br /&gt;
&lt;br /&gt;
Use the Mercurial subcommand to clone your upstream Mercurial repository (Note the // in the path) into git.&lt;br /&gt;
&lt;br /&gt;
 git hg clone &amp;lt;nowiki&amp;gt;ssh://jack@beanstalk.net//var/lib/mercurial/magicbeans&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Updating is easy:&lt;br /&gt;
&lt;br /&gt;
 cd &amp;#039;&amp;#039;magicbeans&amp;#039;&amp;#039;&lt;br /&gt;
 git hg fetch&lt;br /&gt;
&lt;br /&gt;
== Importing a CVS project from SourceForge into git ==&lt;br /&gt;
&lt;br /&gt;
First, grab a clone of the remote CVS repository. The easiest way to do this with a SourceForge project, without having to actually use CVS and its pserver logins and whatnot, is to use rsync:&lt;br /&gt;
&lt;br /&gt;
 rsync -avz rsync://meta-extractor.cvs.sourceforge.net/cvsroot/meta-extractor cvs-clone&lt;br /&gt;
&lt;br /&gt;
Now we&amp;#039;re going to import the history of the relevant CVS module (in this case, &amp;quot;metadata-extractor&amp;quot;) into a new git repository.&lt;br /&gt;
&lt;br /&gt;
 sudo apt-get install git-cvsimport&lt;br /&gt;
 git cvsimport -C meta-extractor.git -p x -v -d $(pwd)/cvs-clone metadata-extractor&lt;br /&gt;
&lt;br /&gt;
Now you can push your new git project to Github or somewhere:&lt;br /&gt;
&lt;br /&gt;
 cd meta-extractor.git&lt;br /&gt;
 git remote add origin &amp;lt;your-new-git-repo&amp;gt;&lt;br /&gt;
 git push --tags master&lt;br /&gt;
&lt;br /&gt;
You&amp;#039;re good to go!&lt;br /&gt;
&lt;br /&gt;
== Installing Forgejo ==&lt;br /&gt;
&lt;br /&gt;
[https://forgejo.org/ Forgejo] is a [https://forgejo.org/2022-12-15-hello-forgejo/ community fork] of Gitea, which itself forked the quasi-abandoned Gogs project. It is not currently packaged, but it is a monolithic Go binary and therefore easy enough to stand up by following the [https://forgejo.org/docs/latest/admin/installation-binary/ binary install docs]. In sum, grab it (grab the .asc and verify with PGP):&lt;br /&gt;
&lt;br /&gt;
 wget -O /usr/local/bin/forgejo &amp;lt;nowiki&amp;gt;https://codeberg.org/forgejo/forgejo/releases/download/v10.0.1/forgejo-10.0.1-linux-amd64&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then install:&lt;br /&gt;
&lt;br /&gt;
 adduser --system --shell /bin/bash --gecos &amp;#039;Git Version Control&amp;#039; --group --disabled-password --home /home/git git&lt;br /&gt;
 mkdir -p /var/lib/forgejo/{custom,data,repositories} /var/log/forgejo /etc/forgejo&lt;br /&gt;
 chown -R git:git /var/lib/forgejo&lt;br /&gt;
 chown git:adm /var/log/forgejo&lt;br /&gt;
 chown root:git /etc/forgejo&lt;br /&gt;
 chmod -R 750 /var/lib/forgejo /var/log/forgejo /etc/forgejo&lt;br /&gt;
&lt;br /&gt;
Edit &amp;lt;tt&amp;gt;/etc/systemd/system/forgejo.service&amp;lt;/tt&amp;gt; using the [https://codeberg.org/forgejo/forgejo/src/branch/forgejo/contrib/systemd/forgejo.service example forgejo.service file] from the documentation as a guide. Set up an Apache or Nginx proxy definition:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;VirtualHost *:80&amp;gt;&lt;br /&gt;
   ServerName git.&amp;#039;&amp;#039;&amp;#039;mydomain.com&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   RewriteEngine On&lt;br /&gt;
   RewriteCond %{HTTPS} off&lt;br /&gt;
   RedirectMatch 301 ^(?!/\.well-known/acme-challenge/).* &amp;lt;nowiki&amp;gt;https://&amp;lt;/nowiki&amp;gt;git.&amp;#039;&amp;#039;&amp;#039;mydomain.com&amp;#039;&amp;#039;&amp;#039;$0&lt;br /&gt;
   Alias &amp;quot;/.well-known/acme-challenge/&amp;quot; &amp;quot;/var/www/acme-challenges/&amp;quot;&lt;br /&gt;
 &amp;lt;/VirtualHost&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;VirtualHost *:443&amp;gt;&lt;br /&gt;
   SSLEngine On&lt;br /&gt;
   SSLCertificateFile /etc/ssl/letsencrypt/git.&amp;#039;&amp;#039;&amp;#039;mydomain.com&amp;#039;&amp;#039;&amp;#039;/cert.pem&lt;br /&gt;
   SSLCertificateChainFile /etc/ssl/letsencrypt/git.&amp;#039;&amp;#039;&amp;#039;mydomain.com&amp;#039;&amp;#039;&amp;#039;/chain.pem&lt;br /&gt;
   SSLCertificateKeyFile /etc/ssl/letsencrypt/git.&amp;#039;&amp;#039;&amp;#039;mydomain.com&amp;#039;&amp;#039;&amp;#039;/privkey.pem&lt;br /&gt;
   Header always set Strict-Transport-Security &amp;quot;max-age=15768000&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
   ServerName git.&amp;#039;&amp;#039;&amp;#039;mydomain.com&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   ServerAdmin webmaster@&amp;#039;&amp;#039;&amp;#039;mydomain.com&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
 &lt;br /&gt;
   ProxyRequests Off&lt;br /&gt;
   ProxyPreserveHost On&lt;br /&gt;
   ProxyPass         /  &amp;lt;nowiki&amp;gt;http://localhost:3000/&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
   ProxyPassReverse  /  &amp;lt;nowiki&amp;gt;http://localhost:3000/&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
   ErrorLog /var/log/apache2/forgejo/error.log&lt;br /&gt;
   CustomLog /var/log/apache2/forgejo/access.log combined&lt;br /&gt;
 &amp;lt;/VirtualHost&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Updating Forgejo versions ===&lt;br /&gt;
&lt;br /&gt;
 sudo -u git forgejo --config /etc/forgejo/app.ini doctor check --all --log-file /tmp/doctor.log&lt;br /&gt;
 # fix any errors&lt;br /&gt;
 sudo -u git forgejo --config /etc/forgejo/app.ini manager flush-queues&lt;br /&gt;
 wget &amp;lt;nowiki&amp;gt;https://codeberg.org/forgejo/.../forgejo-&amp;#039;&amp;#039;latest&amp;#039;&amp;#039;-linux-amd64&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 mv forgejo-&amp;#039;&amp;#039;latest&amp;#039;&amp;#039;-linux-amd64 /var/lib/forgejo/bin&lt;br /&gt;
 chmod +x /var/lib/forgejo/bin/forgejo-&amp;#039;&amp;#039;latest&amp;#039;&amp;#039;-linux-amd64&lt;br /&gt;
 systemctl stop forgejo.service&lt;br /&gt;
 ln -sf /var/lib/forgejo/bin/forgejo-&amp;#039;&amp;#039;latest&amp;#039;&amp;#039;-linux-amd64 /usr/local/bin/forgejo&lt;br /&gt;
 sudo -u git forgejo --config /etc/forgejo/app.ini migrate&lt;br /&gt;
 sudo -u git forgejo --config /etc/forgejo/app.ini doctor check --all --log-file /tmp/doctor.log&lt;br /&gt;
 # fix any errors&lt;br /&gt;
 systemctl start forgejo.service&lt;/div&gt;</summary>
		<author><name>Johnno</name></author>
	</entry>
	<entry>
		<id>https://wiki.jon.geek.nz/index.php?title=Git&amp;diff=2513</id>
		<title>Git</title>
		<link rel="alternate" type="text/html" href="https://wiki.jon.geek.nz/index.php?title=Git&amp;diff=2513"/>
		<updated>2025-03-03T00:11:58Z</updated>

		<summary type="html">&lt;p&gt;Johnno: /* Migrating to Forgejo */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Handy git configuration ==&lt;br /&gt;
&lt;br /&gt;
Put this in your ~/.gitconfig&lt;br /&gt;
&lt;br /&gt;
 [alias]&lt;br /&gt;
     lol = log --graph --decorate --oneline&lt;br /&gt;
     cdiff = diff --word-diff-regex=.&lt;br /&gt;
     cshow = show --word-diff-regex=.&lt;br /&gt;
     wdiff = diff --word-diff-regex=[^[:space:]]+&lt;br /&gt;
     wshow = show --word-diff-regex=[^[:space:]]+ [color]&lt;br /&gt;
 [color]&lt;br /&gt;
     diff = auto&lt;br /&gt;
     branch = auto&lt;br /&gt;
     log = auto&lt;br /&gt;
     status = auto&lt;br /&gt;
 [push]&lt;br /&gt;
     default = current&lt;br /&gt;
 [user]&lt;br /&gt;
     name = Harry Potter&lt;br /&gt;
     email = harry@hogwarts.school.uk&lt;br /&gt;
 [core]&lt;br /&gt;
     autocrlf = input&lt;br /&gt;
     pager = less -F -X&lt;br /&gt;
&lt;br /&gt;
Bung these in your ~/.bashrc&lt;br /&gt;
&lt;br /&gt;
 export GIT_AUTHOR_NAME=&amp;#039;Harry Potter&amp;#039;&lt;br /&gt;
 export GIT_AUTHOR_EMAIL=&amp;#039;harry@hogwarts.school.uk&amp;#039;&lt;br /&gt;
 export GIT_COMMITTER_NAME=$GIT_AUTHOR_NAME&lt;br /&gt;
 export GIT_COMMITTER_EMAIL=$GIT_AUTHOR_EMAIL&lt;br /&gt;
 export GIT_PS1_SHOWDIRTYSTATE=1&lt;br /&gt;
 export GIT_PS1_SHOWUNTRACKEDFILES=1&lt;br /&gt;
 export GIT_PS1_SHOWUPSTREAM=auto&lt;br /&gt;
 &lt;br /&gt;
 # very handy to have your git branch and checkout status in your prompt:&lt;br /&gt;
 export PS1=&amp;#039;\[\e[1m\]\u@\h:\w\[\e[32;1m\]$(__git_ps1 &amp;quot;(%s)&amp;quot;)\[\e[m\e[1m\]\$\[\e[m\] &amp;#039;&lt;br /&gt;
&lt;br /&gt;
== Track Mercurial transparently with git ==&lt;br /&gt;
&lt;br /&gt;
To track a project hosted in a Mercurial repository, we can use the nifty hg-fast-export package. Install Mercurial and its fast export:&lt;br /&gt;
&lt;br /&gt;
 sudo apt-get install mercurial hg-fast-export&lt;br /&gt;
&lt;br /&gt;
Use the Mercurial subcommand to clone your upstream Mercurial repository (Note the // in the path) into git.&lt;br /&gt;
&lt;br /&gt;
 git hg clone &amp;lt;nowiki&amp;gt;ssh://jack@beanstalk.net//var/lib/mercurial/magicbeans&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Updating is easy:&lt;br /&gt;
&lt;br /&gt;
 cd &amp;#039;&amp;#039;magicbeans&amp;#039;&amp;#039;&lt;br /&gt;
 git hg fetch&lt;br /&gt;
&lt;br /&gt;
== Importing a CVS project from SourceForge into git ==&lt;br /&gt;
&lt;br /&gt;
First, grab a clone of the remote CVS repository. The easiest way to do this with a SourceForge project, without having to actually use CVS and its pserver logins and whatnot, is to use rsync:&lt;br /&gt;
&lt;br /&gt;
 rsync -avz rsync://meta-extractor.cvs.sourceforge.net/cvsroot/meta-extractor cvs-clone&lt;br /&gt;
&lt;br /&gt;
Now we&amp;#039;re going to import the history of the relevant CVS module (in this case, &amp;quot;metadata-extractor&amp;quot;) into a new git repository.&lt;br /&gt;
&lt;br /&gt;
 sudo apt-get install git-cvsimport&lt;br /&gt;
 git cvsimport -C meta-extractor.git -p x -v -d $(pwd)/cvs-clone metadata-extractor&lt;br /&gt;
&lt;br /&gt;
Now you can push your new git project to Github or somewhere:&lt;br /&gt;
&lt;br /&gt;
 cd meta-extractor.git&lt;br /&gt;
 git remote add origin &amp;lt;your-new-git-repo&amp;gt;&lt;br /&gt;
 git push --tags master&lt;br /&gt;
&lt;br /&gt;
You&amp;#039;re good to go!&lt;br /&gt;
&lt;br /&gt;
== Installing Gitea ==&lt;br /&gt;
&lt;br /&gt;
[https://gitea.io/ Gitea] is an active fork of the quasi-abandoned Gogs project, and it is not currently packaged. It&amp;#039;s a monolithic Go binary, so it&amp;#039;s easy enough to stand up by following the [https://docs.gitea.io/en-us/install-from-binary/ binary install docs]. In sum, grab it (grab the .asc and verify with PGP):&lt;br /&gt;
&lt;br /&gt;
 wget -O /usr/local/bin/gitea &amp;lt;nowiki&amp;gt;https://dl.gitea.io/gitea/1.11.3/gitea-1.11.3-linux-amd64&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then install:&lt;br /&gt;
&lt;br /&gt;
 adduser --system --shell /bin/bash --gecos &amp;#039;Git Version Control&amp;#039; --group --disabled-password --home /home/git git&lt;br /&gt;
 mkdir -p /var/lib/gitea/{custom,data,repositories} /var/log/gitea /etc/gitea&lt;br /&gt;
 chown -R git:git /var/lib/gitea&lt;br /&gt;
 chown git:adm /var/log/gitea&lt;br /&gt;
 chown root:git /etc/gitea&lt;br /&gt;
 chmod -R 750 /var/lib/gitea /var/log/gitea /etc/gitea&lt;br /&gt;
&lt;br /&gt;
Edit &amp;lt;tt&amp;gt;/etc/systemd/system/gitea.service&amp;lt;/tt&amp;gt; using the [https://github.com/go-gitea/gitea/blob/master/contrib/systemd/gitea.service example gitea.service file] from the documentation as a guide. Set up an Apache or Nginx proxy definition:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;VirtualHost *:80&amp;gt;&lt;br /&gt;
   ServerName git.&amp;#039;&amp;#039;&amp;#039;mydomain.com&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   RewriteEngine On&lt;br /&gt;
   RewriteCond %{HTTPS} off&lt;br /&gt;
   RedirectMatch 301 ^(?!/\.well-known/acme-challenge/).* &amp;lt;nowiki&amp;gt;https://&amp;lt;/nowiki&amp;gt;git.&amp;#039;&amp;#039;&amp;#039;mydomain.com&amp;#039;&amp;#039;&amp;#039;$0&lt;br /&gt;
   Alias &amp;quot;/.well-known/acme-challenge/&amp;quot; &amp;quot;/var/www/acme-challenges/&amp;quot;&lt;br /&gt;
 &amp;lt;/VirtualHost&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;VirtualHost *:443&amp;gt;&lt;br /&gt;
   SSLEngine On&lt;br /&gt;
   SSLCertificateFile /etc/ssl/letsencrypt/git.&amp;#039;&amp;#039;&amp;#039;mydomain.com&amp;#039;&amp;#039;&amp;#039;/cert.pem&lt;br /&gt;
   SSLCertificateChainFile /etc/ssl/letsencrypt/git.&amp;#039;&amp;#039;&amp;#039;mydomain.com&amp;#039;&amp;#039;&amp;#039;/chain.pem&lt;br /&gt;
   SSLCertificateKeyFile /etc/ssl/letsencrypt/git.&amp;#039;&amp;#039;&amp;#039;mydomain.com&amp;#039;&amp;#039;&amp;#039;/privkey.pem&lt;br /&gt;
   Header always set Strict-Transport-Security &amp;quot;max-age=15768000&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
   ServerName git.&amp;#039;&amp;#039;&amp;#039;mydomain.com&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   ServerAdmin webmaster@&amp;#039;&amp;#039;&amp;#039;mydomain.com&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
 &lt;br /&gt;
   ProxyRequests Off&lt;br /&gt;
   ProxyPreserveHost On&lt;br /&gt;
   ProxyPass         /  &amp;lt;nowiki&amp;gt;http://localhost:3000/&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
   ProxyPassReverse  /  &amp;lt;nowiki&amp;gt;http://localhost:3000/&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
   ErrorLog /var/log/apache2/gitea/error.log&lt;br /&gt;
   CustomLog /var/log/apache2/gitea/access.log combined&lt;br /&gt;
 &amp;lt;/VirtualHost&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Migrating to Forgejo ===&lt;br /&gt;
&lt;br /&gt;
...and here we go again.&lt;br /&gt;
&lt;br /&gt;
 sudo -u git forgejo --config /etc/forgejo/app.ini doctor check --all --log-file /tmp/doctor.log&lt;br /&gt;
 # fix any errors&lt;br /&gt;
 sudo -u git forgejo --config /etc/forgejo/app.ini manager flush-queues&lt;br /&gt;
 wget &amp;lt;nowiki&amp;gt;https://codeberg.org/forgejo/.../forgejo-&amp;#039;&amp;#039;latest&amp;#039;&amp;#039;-linux-amd64&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 mv forgejo-&amp;#039;&amp;#039;latest&amp;#039;&amp;#039;-linux-amd64 /var/lib/forgejo/bin&lt;br /&gt;
 chmod +x /var/lib/forgejo/bin/forgejo-&amp;#039;&amp;#039;latest&amp;#039;&amp;#039;-linux-amd64&lt;br /&gt;
 systemctl stop forgejo.service&lt;br /&gt;
 ln -sf /var/lib/forgejo/bin/forgejo-&amp;#039;&amp;#039;latest&amp;#039;&amp;#039;-linux-amd64 /usr/local/bin/forgejo&lt;br /&gt;
 sudo -u git forgejo --config /etc/forgejo/app.ini migrate&lt;br /&gt;
 sudo -u git forgejo --config /etc/forgejo/app.ini doctor check --all --log-file /tmp/doctor.log&lt;br /&gt;
 # fix any errors&lt;br /&gt;
 systemctl start forgejo.service&lt;/div&gt;</summary>
		<author><name>Johnno</name></author>
	</entry>
	<entry>
		<id>https://wiki.jon.geek.nz/index.php?title=Git&amp;diff=2512</id>
		<title>Git</title>
		<link rel="alternate" type="text/html" href="https://wiki.jon.geek.nz/index.php?title=Git&amp;diff=2512"/>
		<updated>2025-03-03T00:10:48Z</updated>

		<summary type="html">&lt;p&gt;Johnno: /* Installing Gitea */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Handy git configuration ==&lt;br /&gt;
&lt;br /&gt;
Put this in your ~/.gitconfig&lt;br /&gt;
&lt;br /&gt;
 [alias]&lt;br /&gt;
     lol = log --graph --decorate --oneline&lt;br /&gt;
     cdiff = diff --word-diff-regex=.&lt;br /&gt;
     cshow = show --word-diff-regex=.&lt;br /&gt;
     wdiff = diff --word-diff-regex=[^[:space:]]+&lt;br /&gt;
     wshow = show --word-diff-regex=[^[:space:]]+ [color]&lt;br /&gt;
 [color]&lt;br /&gt;
     diff = auto&lt;br /&gt;
     branch = auto&lt;br /&gt;
     log = auto&lt;br /&gt;
     status = auto&lt;br /&gt;
 [push]&lt;br /&gt;
     default = current&lt;br /&gt;
 [user]&lt;br /&gt;
     name = Harry Potter&lt;br /&gt;
     email = harry@hogwarts.school.uk&lt;br /&gt;
 [core]&lt;br /&gt;
     autocrlf = input&lt;br /&gt;
     pager = less -F -X&lt;br /&gt;
&lt;br /&gt;
Bung these in your ~/.bashrc&lt;br /&gt;
&lt;br /&gt;
 export GIT_AUTHOR_NAME=&amp;#039;Harry Potter&amp;#039;&lt;br /&gt;
 export GIT_AUTHOR_EMAIL=&amp;#039;harry@hogwarts.school.uk&amp;#039;&lt;br /&gt;
 export GIT_COMMITTER_NAME=$GIT_AUTHOR_NAME&lt;br /&gt;
 export GIT_COMMITTER_EMAIL=$GIT_AUTHOR_EMAIL&lt;br /&gt;
 export GIT_PS1_SHOWDIRTYSTATE=1&lt;br /&gt;
 export GIT_PS1_SHOWUNTRACKEDFILES=1&lt;br /&gt;
 export GIT_PS1_SHOWUPSTREAM=auto&lt;br /&gt;
 &lt;br /&gt;
 # very handy to have your git branch and checkout status in your prompt:&lt;br /&gt;
 export PS1=&amp;#039;\[\e[1m\]\u@\h:\w\[\e[32;1m\]$(__git_ps1 &amp;quot;(%s)&amp;quot;)\[\e[m\e[1m\]\$\[\e[m\] &amp;#039;&lt;br /&gt;
&lt;br /&gt;
== Track Mercurial transparently with git ==&lt;br /&gt;
&lt;br /&gt;
To track a project hosted in a Mercurial repository, we can use the nifty hg-fast-export package. Install Mercurial and its fast export:&lt;br /&gt;
&lt;br /&gt;
 sudo apt-get install mercurial hg-fast-export&lt;br /&gt;
&lt;br /&gt;
Use the Mercurial subcommand to clone your upstream Mercurial repository (Note the // in the path) into git.&lt;br /&gt;
&lt;br /&gt;
 git hg clone &amp;lt;nowiki&amp;gt;ssh://jack@beanstalk.net//var/lib/mercurial/magicbeans&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Updating is easy:&lt;br /&gt;
&lt;br /&gt;
 cd &amp;#039;&amp;#039;magicbeans&amp;#039;&amp;#039;&lt;br /&gt;
 git hg fetch&lt;br /&gt;
&lt;br /&gt;
== Importing a CVS project from SourceForge into git ==&lt;br /&gt;
&lt;br /&gt;
First, grab a clone of the remote CVS repository. The easiest way to do this with a SourceForge project, without having to actually use CVS and its pserver logins and whatnot, is to use rsync:&lt;br /&gt;
&lt;br /&gt;
 rsync -avz rsync://meta-extractor.cvs.sourceforge.net/cvsroot/meta-extractor cvs-clone&lt;br /&gt;
&lt;br /&gt;
Now we&amp;#039;re going to import the history of the relevant CVS module (in this case, &amp;quot;metadata-extractor&amp;quot;) into a new git repository.&lt;br /&gt;
&lt;br /&gt;
 sudo apt-get install git-cvsimport&lt;br /&gt;
 git cvsimport -C meta-extractor.git -p x -v -d $(pwd)/cvs-clone metadata-extractor&lt;br /&gt;
&lt;br /&gt;
Now you can push your new git project to Github or somewhere:&lt;br /&gt;
&lt;br /&gt;
 cd meta-extractor.git&lt;br /&gt;
 git remote add origin &amp;lt;your-new-git-repo&amp;gt;&lt;br /&gt;
 git push --tags master&lt;br /&gt;
&lt;br /&gt;
You&amp;#039;re good to go!&lt;br /&gt;
&lt;br /&gt;
== Installing Gitea ==&lt;br /&gt;
&lt;br /&gt;
[https://gitea.io/ Gitea] is an active fork of the quasi-abandoned Gogs project, and it is not currently packaged. It&amp;#039;s a monolithic Go binary, so it&amp;#039;s easy enough to stand up by following the [https://docs.gitea.io/en-us/install-from-binary/ binary install docs]. In sum, grab it (grab the .asc and verify with PGP):&lt;br /&gt;
&lt;br /&gt;
 wget -O /usr/local/bin/gitea &amp;lt;nowiki&amp;gt;https://dl.gitea.io/gitea/1.11.3/gitea-1.11.3-linux-amd64&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then install:&lt;br /&gt;
&lt;br /&gt;
 adduser --system --shell /bin/bash --gecos &amp;#039;Git Version Control&amp;#039; --group --disabled-password --home /home/git git&lt;br /&gt;
 mkdir -p /var/lib/gitea/{custom,data,repositories} /var/log/gitea /etc/gitea&lt;br /&gt;
 chown -R git:git /var/lib/gitea&lt;br /&gt;
 chown git:adm /var/log/gitea&lt;br /&gt;
 chown root:git /etc/gitea&lt;br /&gt;
 chmod -R 750 /var/lib/gitea /var/log/gitea /etc/gitea&lt;br /&gt;
&lt;br /&gt;
Edit &amp;lt;tt&amp;gt;/etc/systemd/system/gitea.service&amp;lt;/tt&amp;gt; using the [https://github.com/go-gitea/gitea/blob/master/contrib/systemd/gitea.service example gitea.service file] from the documentation as a guide. Set up an Apache or Nginx proxy definition:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;VirtualHost *:80&amp;gt;&lt;br /&gt;
   ServerName git.&amp;#039;&amp;#039;&amp;#039;mydomain.com&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   RewriteEngine On&lt;br /&gt;
   RewriteCond %{HTTPS} off&lt;br /&gt;
   RedirectMatch 301 ^(?!/\.well-known/acme-challenge/).* &amp;lt;nowiki&amp;gt;https://&amp;lt;/nowiki&amp;gt;git.&amp;#039;&amp;#039;&amp;#039;mydomain.com&amp;#039;&amp;#039;&amp;#039;$0&lt;br /&gt;
   Alias &amp;quot;/.well-known/acme-challenge/&amp;quot; &amp;quot;/var/www/acme-challenges/&amp;quot;&lt;br /&gt;
 &amp;lt;/VirtualHost&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;VirtualHost *:443&amp;gt;&lt;br /&gt;
   SSLEngine On&lt;br /&gt;
   SSLCertificateFile /etc/ssl/letsencrypt/git.&amp;#039;&amp;#039;&amp;#039;mydomain.com&amp;#039;&amp;#039;&amp;#039;/cert.pem&lt;br /&gt;
   SSLCertificateChainFile /etc/ssl/letsencrypt/git.&amp;#039;&amp;#039;&amp;#039;mydomain.com&amp;#039;&amp;#039;&amp;#039;/chain.pem&lt;br /&gt;
   SSLCertificateKeyFile /etc/ssl/letsencrypt/git.&amp;#039;&amp;#039;&amp;#039;mydomain.com&amp;#039;&amp;#039;&amp;#039;/privkey.pem&lt;br /&gt;
   Header always set Strict-Transport-Security &amp;quot;max-age=15768000&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
   ServerName git.&amp;#039;&amp;#039;&amp;#039;mydomain.com&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   ServerAdmin webmaster@&amp;#039;&amp;#039;&amp;#039;mydomain.com&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
 &lt;br /&gt;
   ProxyRequests Off&lt;br /&gt;
   ProxyPreserveHost On&lt;br /&gt;
   ProxyPass         /  &amp;lt;nowiki&amp;gt;http://localhost:3000/&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
   ProxyPassReverse  /  &amp;lt;nowiki&amp;gt;http://localhost:3000/&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
   ErrorLog /var/log/apache2/gitea/error.log&lt;br /&gt;
   CustomLog /var/log/apache2/gitea/access.log combined&lt;br /&gt;
 &amp;lt;/VirtualHost&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Migrating to Forgejo ===&lt;br /&gt;
&lt;br /&gt;
...and here we go again.&lt;br /&gt;
&lt;br /&gt;
 sudo -u git forgejo --config /etc/forgejo/app.ini doctor check --all --log-file /tmp/doctor.log&lt;br /&gt;
 # fix any errors&lt;br /&gt;
 sudo -u git forgejo --config /etc/forgejo/app.ini manager flush-queues&lt;br /&gt;
 wget &amp;lt;nowiki&amp;gt;https://codeberg.org/forgejo/.../forgejo-&amp;#039;&amp;#039;latest&amp;#039;&amp;#039;-linux-amd64&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 mv forgejo-&amp;#039;&amp;#039;latest&amp;#039;&amp;#039;-linux-amd64 /var/lib/forgejo/bin&lt;br /&gt;
 chmod +x /var/lib/forgejo/bin/forgejo-&amp;#039;&amp;#039;latest&amp;#039;&amp;#039;-linux-amd64&lt;br /&gt;
 sudo systemctl stop forgejo.service&lt;br /&gt;
 ln -sf /var/lib/forgejo/bin/forgejo-&amp;#039;&amp;#039;latest&amp;#039;&amp;#039;-linux-amd64 /usr/local/bin/forgejo&lt;br /&gt;
 sudo -u git forgejo --config /etc/forgejo/app.ini migrate&lt;br /&gt;
 sudo -u git forgejo --config /etc/forgejo/app.ini doctor check --all --log-file /tmp/doctor.log&lt;br /&gt;
 # fix any errors&lt;br /&gt;
 sudo systemctl start forgejo.service&lt;/div&gt;</summary>
		<author><name>Johnno</name></author>
	</entry>
	<entry>
		<id>https://wiki.jon.geek.nz/index.php?title=Hacks&amp;diff=2511</id>
		<title>Hacks</title>
		<link rel="alternate" type="text/html" href="https://wiki.jon.geek.nz/index.php?title=Hacks&amp;diff=2511"/>
		<updated>2024-12-16T21:10:29Z</updated>

		<summary type="html">&lt;p&gt;Johnno: /* Fancy PostgreSQL prompts */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Image renaming by create date ==&lt;br /&gt;
&lt;br /&gt;
When you have a bunch of files from your old Android phone with a timestamp filename (e.g. 1388042328550.jpg), you can rename them thus:&lt;br /&gt;
&lt;br /&gt;
 for f in 1*.jpg; do&lt;br /&gt;
   mv $f $(date +IMG_%Y%m%d_%H%M%S.jpg -d @$(echo $f|cut -c 1-10))&lt;br /&gt;
 done&lt;br /&gt;
&lt;br /&gt;
Otherwise, we can fish out the Create Date from the EXIF data, using exiftool:&lt;br /&gt;
&lt;br /&gt;
 exiftool &amp;#039;-FileName&amp;lt;CreateDate&amp;#039; -d %Y%m%d_%H%M%S%%-c.%%e .&lt;br /&gt;
&lt;br /&gt;
== Use etckeeper ==&lt;br /&gt;
&lt;br /&gt;
It saves your bacon. Store changes to the {{path|/etc}} directory in git, uses hooks to commit changes when packages are updated, puppet runs, etc. Stash your own changes with useful commit messages. Look up stuff in history when something goes wrong, figure out what changes happened when packages are added or updated.&lt;br /&gt;
&lt;br /&gt;
=== Fix the daily commit bug ===&lt;br /&gt;
&lt;br /&gt;
Unfortunately since about 18.04 there is a bug where a systemd timer and a cron.daily task compete to commit a daily commit if needed; unfortunately one of them doesn&amp;#039;t bother to check the {{path|etckeeper.conf}} file to see whether you&amp;#039;ve disabled it. If you have &amp;lt;code&amp;gt;DISABLE_DAILY_AUTOCOMMITS=1&amp;lt;/code&amp;gt; in your config file, then you probably don&amp;#039;t want daily auto commits. If this is so, run this to disable the systemd timer:&lt;br /&gt;
&lt;br /&gt;
 systemctl disable --now etckeeper.timer&lt;br /&gt;
&lt;br /&gt;
== Repair broken or rotated phone videos ==&lt;br /&gt;
&lt;br /&gt;
You can fix broken video .tmp files from your Android phone using [https://github.com/ponchio/untrunc/ untrunc]. This will create a fixed.mp4 file in cwd:&lt;br /&gt;
&lt;br /&gt;
 untrunc working_video_from_the_same_camera.mp4 broken.mk4.tmp&lt;br /&gt;
&lt;br /&gt;
Did your phone unhelpfully rotate your video? Fix the metadata:&lt;br /&gt;
&lt;br /&gt;
 ffmpeg -i original.mp4 -acodec copy -vcodec copy -metadata:s:v:0 rotate=0 unrotated.mp4&lt;br /&gt;
&lt;br /&gt;
Or, did you actually film your shit the wrong way up? You&amp;#039;ll need to re-encode it:&lt;br /&gt;
&lt;br /&gt;
 ffmpeg -i original.mp4 -acodec copy -vcodec libx264 -crf 20 -metadata:s:v:0 rotate=0 unrotated.mp4&lt;br /&gt;
&lt;br /&gt;
== Export your photos ==&lt;br /&gt;
&lt;br /&gt;
Before uploading your photos, remove all the EXIF tags, and reduce the resolution; nobody needs 5000x4000 pixels, much less corporations hoovering up your stuff to put in adverts.&lt;br /&gt;
&lt;br /&gt;
 mkdir tmp&lt;br /&gt;
 for f in $.jpg; do&lt;br /&gt;
   convert -resize 1600x1200 $f tmp/$f&lt;br /&gt;
   exiftool -all= -P -overwrite_original tmp/$f&lt;br /&gt;
 done&lt;br /&gt;
&lt;br /&gt;
== Clean out your revoked and expired PGP keys ==&lt;br /&gt;
&lt;br /&gt;
Spring-clean your gpg database, make it go faster. Just go:&lt;br /&gt;
&lt;br /&gt;
 gpg --delete-keys $(gpg --list-public-keys|grep -PB1 &amp;#039;expired|revoked&amp;#039;|grep &amp;#039;^\s&amp;#039;)&lt;br /&gt;
&lt;br /&gt;
Obviously. If you can&amp;#039;t be arsed confirming each key, add &amp;lt;tt&amp;gt;--batch --yes&amp;lt;/tt&amp;gt; to the first gpg call.&lt;br /&gt;
&lt;br /&gt;
== Firefox opening your shit in gedit ==&lt;br /&gt;
&lt;br /&gt;
I don&amp;#039;t know, who thought that was a good idea? Jesus.&lt;br /&gt;
&lt;br /&gt;
 sed -i &amp;#039;s#.*octet-stream.*#application/octet-stream=xdg-open#&amp;#039; ~/.local/share/applications/mimeapps.list ~/.config/mimeapps.list&lt;br /&gt;
&lt;br /&gt;
== GNOME not sorting your folders first ==&lt;br /&gt;
&lt;br /&gt;
It&amp;#039;s not in a dialog anywhere, and a pretty lame default behaviour.&lt;br /&gt;
 dconf write /org/gnome/nautilus/preferences/sort-directories-first true&lt;br /&gt;
&lt;br /&gt;
== GNOME not dealing with WebP images ==&lt;br /&gt;
&lt;br /&gt;
I mean, it&amp;#039;s 2021 and WebP is only what, ten years old? Jesus. See solution on [https://askubuntu.com/a/617068 AskUbuntu].&lt;br /&gt;
&lt;br /&gt;
== Restoring huge databases to PostgreSQL ==&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;See also:&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039; &amp;#039;&amp;#039;[[PostgreSQL]]&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Skip some huge tables by dumping the TOC, removing culprit large tables, and restore with the edited TOC, e.g.&lt;br /&gt;
&lt;br /&gt;
 pg_restore -l huge.dump &amp;gt; TOC&lt;br /&gt;
 # edit the TOC file...&lt;br /&gt;
 pg_restore -L TOC -d dbname huge.dump&lt;br /&gt;
&lt;br /&gt;
== Output PostgreSQL queries to CSV ==&lt;br /&gt;
&lt;br /&gt;
 COPY (SELECT &amp;lt;query&amp;gt; ...) TO STDOUT CSV HEADER;&lt;br /&gt;
&lt;br /&gt;
== Turn off the shitty default &amp;quot;visual&amp;quot; mouse mode in vim ==&lt;br /&gt;
&lt;br /&gt;
Add this to &amp;lt;code&amp;gt;/etc/vim/vimrc.local&amp;lt;/code&amp;gt; file:&amp;lt;ref&amp;gt;Böhnke, H (16 March 2019). [https://unix.stackexchange.com/a/506723 Answer 506723] on &amp;quot;Disabling mouse support in vim in a gnome-terminal environment&amp;quot;, Unix &amp;amp; Linux Stack Exchange.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &amp;quot; Use skip_defaults_vim from the master /etc/vim/vimrc file&lt;br /&gt;
 if ! exists(&amp;#039;skip_defaults_vim&amp;#039;)&lt;br /&gt;
   &amp;quot; Source the defaults file manually from here&lt;br /&gt;
   source $VIMRUNTIME/defaults.vim&lt;br /&gt;
 endif&lt;br /&gt;
 &lt;br /&gt;
 &amp;quot; Avoid loading the defaults twice&lt;br /&gt;
 let g:skip_defaults_vim = 1&lt;br /&gt;
 &lt;br /&gt;
 &amp;quot; Revert any unwanted changes the defaults file introduced&lt;br /&gt;
 set mouse=&lt;br /&gt;
&lt;br /&gt;
== Too many leftover git branches merged into master? Nukem! ==&lt;br /&gt;
&lt;br /&gt;
This will remove any branches on your local git repo that have been merged to master.&lt;br /&gt;
&lt;br /&gt;
 for i in $(for b in $(git branch|grep -v &amp;#039;\*&amp;#039;); do git branch $b --merged master; done); \&lt;br /&gt;
     do git branch -D $i; \&lt;br /&gt;
 done&lt;br /&gt;
&lt;br /&gt;
== Move your MySQL databases ==&lt;br /&gt;
&lt;br /&gt;
Used to be you could move your /var/lib/mysql directory somewhere else and symlink it. You can, but in newer distros with Apparmor you&amp;#039;ll need to declare it:&lt;br /&gt;
&lt;br /&gt;
 # In /etc/apparmor.d/tunables/alias&lt;br /&gt;
 alias /var/lib/mysql/ -&amp;gt; /mnt/wherever/mysql/,&lt;br /&gt;
&lt;br /&gt;
Note the trailing comma.&lt;br /&gt;
&lt;br /&gt;
== Split audio CD rips using the cue file ==&lt;br /&gt;
&lt;br /&gt;
Single-file FLAC or Ape files of a CD can be split up using the .cue file for both the timestamps and the tagging data. Also, install flacon (from a PPA).&lt;br /&gt;
&lt;br /&gt;
 sudo apt install shntool&lt;br /&gt;
 shnsplit -o flac cdimage.flac -f cdimage.cue -t &amp;#039;%n.%t&amp;#039;&lt;br /&gt;
&lt;br /&gt;
You may need to do tags again, if they didn&amp;#039;t stick:&lt;br /&gt;
&lt;br /&gt;
 sudo apt install cuetools&lt;br /&gt;
 cuetag cdimage.cue *.flac&lt;br /&gt;
&lt;br /&gt;
== Ditch Snap ==&lt;br /&gt;
&lt;br /&gt;
=== 1. Install Firefox properly ===&lt;br /&gt;
&lt;br /&gt;
Ubuntu 22.04 replaces the Firefox Debian package with a pseudo-package that installs it using Snap. This is no longer optional, and it is also stupid, annoying, slow, and potentially insecure for many reasons.&amp;lt;ref&amp;gt;Brandon Hopkins. [https://techhut.tv/flatpak-vs-snap-vs-appimage/ &amp;quot;Flatpak vs. Snap vs. AppImage - Linux Packaging Benchmarks&amp;quot;] TechHut, April 2022.&amp;lt;/ref&amp;gt; Several Firefox extensions that need to talk to other applications don&amp;#039;t currently work in Snap installed Firefox, including things like Zotero and Keepass.&lt;br /&gt;
&lt;br /&gt;
It also completely fails to find and import any existing Firefox profile. Snap apps for whatever stupid reason keep settings in a hard-coded ~/snap folder. Who thought that was a good idea? What&amp;#039;s wrong with ~/.config and/or ~/.local, or couldn&amp;#039;t they even use ~/.snap? Good grief.&lt;br /&gt;
&lt;br /&gt;
Luckily, we can use the Mozilla Team PPA instead.&amp;lt;ref&amp;gt;Ji M. [https://ubuntuhandbook.org/index.php/2022/04/install-firefox-deb-ubuntu-22-04/ &amp;quot;How to Install Latest Firefox as classic Deb in Ubuntu 22.04&amp;quot;] Ubuntu Handbook, April 2022.&amp;lt;/ref&amp;gt; In summary:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Remove Firefox entirely:&lt;br /&gt;
snap remove firefox&lt;br /&gt;
apt remove firefox&lt;br /&gt;
&lt;br /&gt;
# Add the Mozilla Team PPA and install:&lt;br /&gt;
add-apt-repository ppa:mozillateam/ppa&lt;br /&gt;
apt update&lt;br /&gt;
apt install -t &amp;#039;o=LP-PPA-mozillateam&amp;#039; firefox&lt;br /&gt;
&lt;br /&gt;
# Pin to the Mozilla Team PPA so we never get the Snap pseudo-package&lt;br /&gt;
echo &amp;#039;Package: firefox*&lt;br /&gt;
Pin: release o=LP-PPA-mozillateam&lt;br /&gt;
Pin-Priority: 501&amp;#039; &amp;gt; /etc/apt/preferences.d/mozillateam-ppa.pref&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 2. Remove snap ===&lt;br /&gt;
&lt;br /&gt;
You can also remove snap entirely as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# get a list of things installed with snap:&lt;br /&gt;
snap list&lt;br /&gt;
&lt;br /&gt;
# remove them one by one:&lt;br /&gt;
snap uninstall &amp;#039;&amp;#039;program1&amp;#039;&amp;#039;&lt;br /&gt;
snap uninstall &amp;#039;&amp;#039;program2&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
# once there&amp;#039;s nothing left, remove snap:&lt;br /&gt;
apt purge snapd&lt;br /&gt;
&lt;br /&gt;
# then prevent it ever being re-installed with a pin preference:&lt;br /&gt;
echo &amp;#039;Package: snapd&lt;br /&gt;
 Pin: release a=*&lt;br /&gt;
 Pin-Priority: -10&amp;#039; &amp;gt; /etc/apt/preferences.d/no-snap.pref&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Fancy PostgreSQL prompts==&lt;br /&gt;
&lt;br /&gt;
For a coloured prompt including what user, connection, and host you&amp;#039;re on, stick this in ~/.psqlrc or /etc/postgresql-common/psqlrc:&lt;br /&gt;
&lt;br /&gt;
 \set PROMPT1 &amp;#039;%[%033[1m%](%n@%[%033[1;35m%]%M%[%033[m%]%[%033[1m%] on %[%033[1;31m%]%`hostname`%[%033[m%]%[%033[1m%]) \n%/%R%#%[%033[m%] &amp;#039;&lt;br /&gt;
 \set PROMPT2 &amp;#039;%[%033[1m%]%/%R%#%[%033[m%] &amp;#039;&lt;br /&gt;
 \set PROMPT3 &amp;#039;%[%033[1m%]&amp;gt;&amp;gt;%[%033[m%] &amp;#039;&lt;br /&gt;
&lt;br /&gt;
Escape codes use &amp;#039;%&amp;#039; character, documented here: [https://www.postgresql.org/docs/current/app-psql.html#APP-PSQL-PROMPTING Psql Prompts].&lt;br /&gt;
&lt;br /&gt;
==Using rsync with FAT volumes (USB sticks and SD cards)==&lt;br /&gt;
&lt;br /&gt;
You might have noticed that all your files have today&amp;#039;s timestamp on them when using rsync thus:&lt;br /&gt;
 rsync -av /path/to/my/stuff /mnt/usb-stick/&lt;br /&gt;
&lt;br /&gt;
The -a option means -rlDtpog, which is recursive, include links and devices, preserving timestamps, permissions, owner and group. Which is what you want most of the time. Trouble is, FAT partitions have no concept of permissions, owners and groups, so you need to use:&lt;br /&gt;
 rsync -rtlDv /path/to/my/stuff /mnt/usb-stick/&lt;br /&gt;
&lt;br /&gt;
But that&amp;#039;s probably not all, because rsync will probably complain that it can&amp;#039;t set the timestamp. You&amp;#039;ll need to mount your USB stick so it ignores a user check that FAT can&amp;#039;t enforce:&lt;br /&gt;
 mount -o remount,allow_utime=2 /mnt/usb-stick&lt;br /&gt;
&lt;br /&gt;
==Notes==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;/div&gt;</summary>
		<author><name>Johnno</name></author>
	</entry>
	<entry>
		<id>https://wiki.jon.geek.nz/index.php?title=Hacks&amp;diff=2510</id>
		<title>Hacks</title>
		<link rel="alternate" type="text/html" href="https://wiki.jon.geek.nz/index.php?title=Hacks&amp;diff=2510"/>
		<updated>2024-12-16T21:10:12Z</updated>

		<summary type="html">&lt;p&gt;Johnno: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Image renaming by create date ==&lt;br /&gt;
&lt;br /&gt;
When you have a bunch of files from your old Android phone with a timestamp filename (e.g. 1388042328550.jpg), you can rename them thus:&lt;br /&gt;
&lt;br /&gt;
 for f in 1*.jpg; do&lt;br /&gt;
   mv $f $(date +IMG_%Y%m%d_%H%M%S.jpg -d @$(echo $f|cut -c 1-10))&lt;br /&gt;
 done&lt;br /&gt;
&lt;br /&gt;
Otherwise, we can fish out the Create Date from the EXIF data, using exiftool:&lt;br /&gt;
&lt;br /&gt;
 exiftool &amp;#039;-FileName&amp;lt;CreateDate&amp;#039; -d %Y%m%d_%H%M%S%%-c.%%e .&lt;br /&gt;
&lt;br /&gt;
== Use etckeeper ==&lt;br /&gt;
&lt;br /&gt;
It saves your bacon. Store changes to the {{path|/etc}} directory in git, uses hooks to commit changes when packages are updated, puppet runs, etc. Stash your own changes with useful commit messages. Look up stuff in history when something goes wrong, figure out what changes happened when packages are added or updated.&lt;br /&gt;
&lt;br /&gt;
=== Fix the daily commit bug ===&lt;br /&gt;
&lt;br /&gt;
Unfortunately since about 18.04 there is a bug where a systemd timer and a cron.daily task compete to commit a daily commit if needed; unfortunately one of them doesn&amp;#039;t bother to check the {{path|etckeeper.conf}} file to see whether you&amp;#039;ve disabled it. If you have &amp;lt;code&amp;gt;DISABLE_DAILY_AUTOCOMMITS=1&amp;lt;/code&amp;gt; in your config file, then you probably don&amp;#039;t want daily auto commits. If this is so, run this to disable the systemd timer:&lt;br /&gt;
&lt;br /&gt;
 systemctl disable --now etckeeper.timer&lt;br /&gt;
&lt;br /&gt;
== Repair broken or rotated phone videos ==&lt;br /&gt;
&lt;br /&gt;
You can fix broken video .tmp files from your Android phone using [https://github.com/ponchio/untrunc/ untrunc]. This will create a fixed.mp4 file in cwd:&lt;br /&gt;
&lt;br /&gt;
 untrunc working_video_from_the_same_camera.mp4 broken.mk4.tmp&lt;br /&gt;
&lt;br /&gt;
Did your phone unhelpfully rotate your video? Fix the metadata:&lt;br /&gt;
&lt;br /&gt;
 ffmpeg -i original.mp4 -acodec copy -vcodec copy -metadata:s:v:0 rotate=0 unrotated.mp4&lt;br /&gt;
&lt;br /&gt;
Or, did you actually film your shit the wrong way up? You&amp;#039;ll need to re-encode it:&lt;br /&gt;
&lt;br /&gt;
 ffmpeg -i original.mp4 -acodec copy -vcodec libx264 -crf 20 -metadata:s:v:0 rotate=0 unrotated.mp4&lt;br /&gt;
&lt;br /&gt;
== Export your photos ==&lt;br /&gt;
&lt;br /&gt;
Before uploading your photos, remove all the EXIF tags, and reduce the resolution; nobody needs 5000x4000 pixels, much less corporations hoovering up your stuff to put in adverts.&lt;br /&gt;
&lt;br /&gt;
 mkdir tmp&lt;br /&gt;
 for f in $.jpg; do&lt;br /&gt;
   convert -resize 1600x1200 $f tmp/$f&lt;br /&gt;
   exiftool -all= -P -overwrite_original tmp/$f&lt;br /&gt;
 done&lt;br /&gt;
&lt;br /&gt;
== Clean out your revoked and expired PGP keys ==&lt;br /&gt;
&lt;br /&gt;
Spring-clean your gpg database, make it go faster. Just go:&lt;br /&gt;
&lt;br /&gt;
 gpg --delete-keys $(gpg --list-public-keys|grep -PB1 &amp;#039;expired|revoked&amp;#039;|grep &amp;#039;^\s&amp;#039;)&lt;br /&gt;
&lt;br /&gt;
Obviously. If you can&amp;#039;t be arsed confirming each key, add &amp;lt;tt&amp;gt;--batch --yes&amp;lt;/tt&amp;gt; to the first gpg call.&lt;br /&gt;
&lt;br /&gt;
== Firefox opening your shit in gedit ==&lt;br /&gt;
&lt;br /&gt;
I don&amp;#039;t know, who thought that was a good idea? Jesus.&lt;br /&gt;
&lt;br /&gt;
 sed -i &amp;#039;s#.*octet-stream.*#application/octet-stream=xdg-open#&amp;#039; ~/.local/share/applications/mimeapps.list ~/.config/mimeapps.list&lt;br /&gt;
&lt;br /&gt;
== GNOME not sorting your folders first ==&lt;br /&gt;
&lt;br /&gt;
It&amp;#039;s not in a dialog anywhere, and a pretty lame default behaviour.&lt;br /&gt;
 dconf write /org/gnome/nautilus/preferences/sort-directories-first true&lt;br /&gt;
&lt;br /&gt;
== GNOME not dealing with WebP images ==&lt;br /&gt;
&lt;br /&gt;
I mean, it&amp;#039;s 2021 and WebP is only what, ten years old? Jesus. See solution on [https://askubuntu.com/a/617068 AskUbuntu].&lt;br /&gt;
&lt;br /&gt;
== Restoring huge databases to PostgreSQL ==&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;See also:&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039; &amp;#039;&amp;#039;[[PostgreSQL]]&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Skip some huge tables by dumping the TOC, removing culprit large tables, and restore with the edited TOC, e.g.&lt;br /&gt;
&lt;br /&gt;
 pg_restore -l huge.dump &amp;gt; TOC&lt;br /&gt;
 # edit the TOC file...&lt;br /&gt;
 pg_restore -L TOC -d dbname huge.dump&lt;br /&gt;
&lt;br /&gt;
== Output PostgreSQL queries to CSV ==&lt;br /&gt;
&lt;br /&gt;
 COPY (SELECT &amp;lt;query&amp;gt; ...) TO STDOUT CSV HEADER;&lt;br /&gt;
&lt;br /&gt;
== Turn off the shitty default &amp;quot;visual&amp;quot; mouse mode in vim ==&lt;br /&gt;
&lt;br /&gt;
Add this to &amp;lt;code&amp;gt;/etc/vim/vimrc.local&amp;lt;/code&amp;gt; file:&amp;lt;ref&amp;gt;Böhnke, H (16 March 2019). [https://unix.stackexchange.com/a/506723 Answer 506723] on &amp;quot;Disabling mouse support in vim in a gnome-terminal environment&amp;quot;, Unix &amp;amp; Linux Stack Exchange.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &amp;quot; Use skip_defaults_vim from the master /etc/vim/vimrc file&lt;br /&gt;
 if ! exists(&amp;#039;skip_defaults_vim&amp;#039;)&lt;br /&gt;
   &amp;quot; Source the defaults file manually from here&lt;br /&gt;
   source $VIMRUNTIME/defaults.vim&lt;br /&gt;
 endif&lt;br /&gt;
 &lt;br /&gt;
 &amp;quot; Avoid loading the defaults twice&lt;br /&gt;
 let g:skip_defaults_vim = 1&lt;br /&gt;
 &lt;br /&gt;
 &amp;quot; Revert any unwanted changes the defaults file introduced&lt;br /&gt;
 set mouse=&lt;br /&gt;
&lt;br /&gt;
== Too many leftover git branches merged into master? Nukem! ==&lt;br /&gt;
&lt;br /&gt;
This will remove any branches on your local git repo that have been merged to master.&lt;br /&gt;
&lt;br /&gt;
 for i in $(for b in $(git branch|grep -v &amp;#039;\*&amp;#039;); do git branch $b --merged master; done); \&lt;br /&gt;
     do git branch -D $i; \&lt;br /&gt;
 done&lt;br /&gt;
&lt;br /&gt;
== Move your MySQL databases ==&lt;br /&gt;
&lt;br /&gt;
Used to be you could move your /var/lib/mysql directory somewhere else and symlink it. You can, but in newer distros with Apparmor you&amp;#039;ll need to declare it:&lt;br /&gt;
&lt;br /&gt;
 # In /etc/apparmor.d/tunables/alias&lt;br /&gt;
 alias /var/lib/mysql/ -&amp;gt; /mnt/wherever/mysql/,&lt;br /&gt;
&lt;br /&gt;
Note the trailing comma.&lt;br /&gt;
&lt;br /&gt;
== Split audio CD rips using the cue file ==&lt;br /&gt;
&lt;br /&gt;
Single-file FLAC or Ape files of a CD can be split up using the .cue file for both the timestamps and the tagging data. Also, install flacon (from a PPA).&lt;br /&gt;
&lt;br /&gt;
 sudo apt install shntool&lt;br /&gt;
 shnsplit -o flac cdimage.flac -f cdimage.cue -t &amp;#039;%n.%t&amp;#039;&lt;br /&gt;
&lt;br /&gt;
You may need to do tags again, if they didn&amp;#039;t stick:&lt;br /&gt;
&lt;br /&gt;
 sudo apt install cuetools&lt;br /&gt;
 cuetag cdimage.cue *.flac&lt;br /&gt;
&lt;br /&gt;
== Ditch Snap ==&lt;br /&gt;
&lt;br /&gt;
=== 1. Install Firefox properly ===&lt;br /&gt;
&lt;br /&gt;
Ubuntu 22.04 replaces the Firefox Debian package with a pseudo-package that installs it using Snap. This is no longer optional, and it is also stupid, annoying, slow, and potentially insecure for many reasons.&amp;lt;ref&amp;gt;Brandon Hopkins. [https://techhut.tv/flatpak-vs-snap-vs-appimage/ &amp;quot;Flatpak vs. Snap vs. AppImage - Linux Packaging Benchmarks&amp;quot;] TechHut, April 2022.&amp;lt;/ref&amp;gt; Several Firefox extensions that need to talk to other applications don&amp;#039;t currently work in Snap installed Firefox, including things like Zotero and Keepass.&lt;br /&gt;
&lt;br /&gt;
It also completely fails to find and import any existing Firefox profile. Snap apps for whatever stupid reason keep settings in a hard-coded ~/snap folder. Who thought that was a good idea? What&amp;#039;s wrong with ~/.config and/or ~/.local, or couldn&amp;#039;t they even use ~/.snap? Good grief.&lt;br /&gt;
&lt;br /&gt;
Luckily, we can use the Mozilla Team PPA instead.&amp;lt;ref&amp;gt;Ji M. [https://ubuntuhandbook.org/index.php/2022/04/install-firefox-deb-ubuntu-22-04/ &amp;quot;How to Install Latest Firefox as classic Deb in Ubuntu 22.04&amp;quot;] Ubuntu Handbook, April 2022.&amp;lt;/ref&amp;gt; In summary:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Remove Firefox entirely:&lt;br /&gt;
snap remove firefox&lt;br /&gt;
apt remove firefox&lt;br /&gt;
&lt;br /&gt;
# Add the Mozilla Team PPA and install:&lt;br /&gt;
add-apt-repository ppa:mozillateam/ppa&lt;br /&gt;
apt update&lt;br /&gt;
apt install -t &amp;#039;o=LP-PPA-mozillateam&amp;#039; firefox&lt;br /&gt;
&lt;br /&gt;
# Pin to the Mozilla Team PPA so we never get the Snap pseudo-package&lt;br /&gt;
echo &amp;#039;Package: firefox*&lt;br /&gt;
Pin: release o=LP-PPA-mozillateam&lt;br /&gt;
Pin-Priority: 501&amp;#039; &amp;gt; /etc/apt/preferences.d/mozillateam-ppa.pref&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 2. Remove snap ===&lt;br /&gt;
&lt;br /&gt;
You can also remove snap entirely as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# get a list of things installed with snap:&lt;br /&gt;
snap list&lt;br /&gt;
&lt;br /&gt;
# remove them one by one:&lt;br /&gt;
snap uninstall &amp;#039;&amp;#039;program1&amp;#039;&amp;#039;&lt;br /&gt;
snap uninstall &amp;#039;&amp;#039;program2&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
# once there&amp;#039;s nothing left, remove snap:&lt;br /&gt;
apt purge snapd&lt;br /&gt;
&lt;br /&gt;
# then prevent it ever being re-installed with a pin preference:&lt;br /&gt;
echo &amp;#039;Package: snapd&lt;br /&gt;
 Pin: release a=*&lt;br /&gt;
 Pin-Priority: -10&amp;#039; &amp;gt; /etc/apt/preferences.d/no-snap.pref&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Fancy PostgreSQL prompts==&lt;br /&gt;
&lt;br /&gt;
For a coloured prompt including what user, connection, and host you&amp;#039;re on, stick this in ~/.psqlrc or /etc/postgresql-common/psqlrc:&lt;br /&gt;
&lt;br /&gt;
 \set PROMPT1 &amp;#039;%[%033[1m%](%n@%[%033[1;35m%]%M%[%033[m%]%[%033[1m%] on %[%033[1;31m%]%`hostname`%[%033[m%]%[%033[1m%]) \n%/%R%#%[%033[m%] &amp;#039;&lt;br /&gt;
 \set PROMPT2 &amp;#039;%[%033[1m%]%/%R%#%[%033[m%] &amp;#039;&lt;br /&gt;
 \set PROMPT3 &amp;#039;%[%033[1m%]&amp;gt;&amp;gt;%[%033[m%] &amp;#039;&lt;br /&gt;
&lt;br /&gt;
Escape codes use &amp;#039;%&amp;#039; character, documented here: [https://www.postgresql.org/docs/current/app-psql.html#APP-PSQL-PROMPTING Psql Prompts].&lt;br /&gt;
&lt;br /&gt;
==Using rsync with FAT volumes (USB sticks and SD cards)&lt;br /&gt;
&lt;br /&gt;
You might have noticed that all your files have today&amp;#039;s timestamp on them when using rsync thus:&lt;br /&gt;
 rsync -av /path/to/my/stuff /mnt/usb-stick/&lt;br /&gt;
&lt;br /&gt;
The -a option means -rlDtpog, which is recursive, include links and devices, preserving timestamps, permissions, owner and group. Which is what you want most of the time. Trouble is, FAT partitions have no concept of permissions, owners and groups, so you need to use:&lt;br /&gt;
 rsync -rtlDv /path/to/my/stuff /mnt/usb-stick/&lt;br /&gt;
&lt;br /&gt;
But that&amp;#039;s probably not all, because rsync will probably complain that it can&amp;#039;t set the timestamp. You&amp;#039;ll need to mount your USB stick so it ignores a user check that FAT can&amp;#039;t enforce:&lt;br /&gt;
 mount -o remount,allow_utime=2 /mnt/usb-stick&lt;br /&gt;
&lt;br /&gt;
==Notes==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;/div&gt;</summary>
		<author><name>Johnno</name></author>
	</entry>
	<entry>
		<id>https://wiki.jon.geek.nz/index.php?title=PostgreSQL&amp;diff=2509</id>
		<title>PostgreSQL</title>
		<link rel="alternate" type="text/html" href="https://wiki.jon.geek.nz/index.php?title=PostgreSQL&amp;diff=2509"/>
		<updated>2024-09-19T00:24:17Z</updated>

		<summary type="html">&lt;p&gt;Johnno: /* Troubleshooting */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Documentation ==&lt;br /&gt;
&lt;br /&gt;
The online [http://www.postgresql.org/docs/current/ PostgreSQL Manual] is actually quite awesome and worth bookmarking.&lt;br /&gt;
&lt;br /&gt;
== Install and Configure ==&lt;br /&gt;
&lt;br /&gt;
Assuming Debian or Ubuntu, installation is:&lt;br /&gt;
 sudo apt-get install postgresql postgresql-client&lt;br /&gt;
&lt;br /&gt;
=== Check The Configuration ===&lt;br /&gt;
&lt;br /&gt;
You may end up with (and may require) several different versions of PostgreSQL on one box. If this is so, check that they are running on separate ports. The port is specified in &amp;lt;tt&amp;gt;/etc/postgresql/9.1/main/postgresql.conf&amp;lt;/tt&amp;gt;. For a development (&amp;#039;&amp;#039;&amp;#039;NOT&amp;#039;&amp;#039;&amp;#039; production!) environment, we can make life simple by making a change to &amp;lt;tt&amp;gt;/etc/postgresql/9.1/main/pg_hba.conf&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 local  all     all                            trust &lt;br /&gt;
 host   all     all         127.0.0.1/32       trust&lt;br /&gt;
&lt;br /&gt;
That is, changing the authentication from &amp;#039;&amp;#039;md5&amp;#039;&amp;#039; to &amp;#039;&amp;#039;trust&amp;#039;&amp;#039; for local socket-based connections and TCP connections from localhost. On production servers, &amp;lt;tt&amp;gt;pg_hba.conf&amp;lt;/tt&amp;gt; provides the means for a powerful and atomic user- and host-based authentication system to really lock the whole thing down nicely.&lt;br /&gt;
&lt;br /&gt;
;NOTE: If you have changed the port or anything else in &amp;lt;tt&amp;gt;postgresql.conf&amp;lt;/tt&amp;gt;, you will need to stop then start the service, as reload and restart are &amp;#039;&amp;#039;&amp;#039;not&amp;#039;&amp;#039;&amp;#039; sufficient! This is a nasty trap for young players.&lt;br /&gt;
&lt;br /&gt;
== Creating Users and Databases ==&lt;br /&gt;
&lt;br /&gt;
PostgreSQL system administration is somewhat different in approach to MySQL, but actually much less retarded once you get the hang of it.&lt;br /&gt;
&lt;br /&gt;
With PostgreSQL creating users and databases is done with shell level commands &amp;lt;tt&amp;gt;createuser&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;createdb&amp;lt;/tt&amp;gt;, rather than lame non-standard SQL commands (although you can also use SQL-ish statements like MySQL if you insist, but they are not covered here).&lt;br /&gt;
&lt;br /&gt;
=== Make Yourself A Superuser ===&lt;br /&gt;
&lt;br /&gt;
Out of the box, the PostgreSQL server runs as the postgres user, so to create yourself an administrator account, you need to run the createuser script as the postgres user:&lt;br /&gt;
&lt;br /&gt;
 sudo -u postgres createuser &amp;lt;yourusername&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Use your shell account name and answer &amp;#039;&amp;#039;Y&amp;#039;&amp;#039; to all questions to give yourself a superuser account. Unless told otherwise, PostgreSQL will try to use the shell account to save time. If you don&amp;#039;t want question prompts, you can go&lt;br /&gt;
&lt;br /&gt;
 sudo -u postgres createuser -srdP &amp;lt;username&amp;gt;&lt;br /&gt;
&lt;br /&gt;
;NOTE: Reload the PostgreSQL server to pick up the new privileges.&lt;br /&gt;
&lt;br /&gt;
==== Switches for createuser ====&lt;br /&gt;
&lt;br /&gt;
{| border=1&lt;br /&gt;
|-&lt;br /&gt;
|  &amp;#039;&amp;#039;&amp;#039;Switch&amp;#039;&amp;#039;&amp;#039;  ||  &amp;#039;&amp;#039;&amp;#039;Behaviour&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;-s&amp;#039;&amp;#039;  ||  User will be a superuser&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;-S&amp;#039;&amp;#039;  ||  User will not be a superuser&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;-r&amp;#039;&amp;#039;  ||  User can create other roles (users)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;-R&amp;#039;&amp;#039;  ||  User cannot create other roles (users)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;-d&amp;#039;&amp;#039;  ||  User can create databases&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;-D&amp;#039;&amp;#039;  ||  User cannot create databases&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;-P&amp;#039;&amp;#039;  ||  Prompt to create a password for the user&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Common Switches For All Commands ====&lt;br /&gt;
{| border=1&lt;br /&gt;
|-&lt;br /&gt;
|  &amp;#039;&amp;#039;&amp;#039;Switch&amp;#039;&amp;#039;&amp;#039;  ||  &amp;#039;&amp;#039;&amp;#039;Behaviour&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;-h&amp;#039;&amp;#039;  ||  Host - hostname of the PostgreSQL server &amp;#039;&amp;#039;(defaults to localhost)&amp;#039;&amp;#039;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;-p&amp;#039;&amp;#039;  ||  Port - PostgreSQL server port &amp;#039;&amp;#039;(defaults to 5432)&amp;#039;&amp;#039;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;-U&amp;#039;&amp;#039;  ||  User - specify the user to connect as &amp;#039;&amp;#039;(defaults to the shell user)&amp;#039;&amp;#039;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;-W&amp;#039;&amp;#039;  ||  Force PostgreSQL to ask you for a password before connecting&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Create Non-Privileged Users ===&lt;br /&gt;
&lt;br /&gt;
Usually, you give yourself admin rights, and then get your applications to use non-privileged accounts. For production boxes, that&amp;#039;s usually one account per different application and/or database, but for a development box we can often just use a single dev account:&lt;br /&gt;
&lt;br /&gt;
 createuser -SDRP devuser&lt;br /&gt;
&lt;br /&gt;
=== Drop Users ===&lt;br /&gt;
&lt;br /&gt;
You can also drop a user with the &amp;lt;tt&amp;gt;dropuser&amp;lt;/tt&amp;gt; shell command:&lt;br /&gt;
&lt;br /&gt;
 dropuser &amp;lt;username&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Create A Database ===&lt;br /&gt;
&lt;br /&gt;
Now we can create a database. Being 2008, we like to use UTF8 so we need to specify that, since the default is still ASCII.&lt;br /&gt;
&lt;br /&gt;
 createdb -O devuser -E UTF8 &amp;lt;databasename&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Switches for createdb ====&lt;br /&gt;
{| border=1&lt;br /&gt;
|-&lt;br /&gt;
|  &amp;#039;&amp;#039;&amp;#039;Switch&amp;#039;&amp;#039;&amp;#039;  ||  &amp;#039;&amp;#039;&amp;#039;Behaviour&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;-O&amp;#039;&amp;#039;  ||  Owner - the user that owns the database&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;-E&amp;#039;&amp;#039;  ||  Encoding - almost always UTF8&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Drop A Database ===&lt;br /&gt;
&lt;br /&gt;
You can also drop a database with the &amp;lt;tt&amp;gt;dropdb&amp;lt;/tt&amp;gt; shell command:&lt;br /&gt;
&lt;br /&gt;
 dropdb &amp;lt;databasename&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Using The Client ==&lt;br /&gt;
&lt;br /&gt;
The cli client is &amp;lt;tt&amp;gt;psql&amp;lt;/tt&amp;gt;. To get a list of databases on the system, you can use the &amp;#039;&amp;#039;-l&amp;#039;&amp;#039; switch:&lt;br /&gt;
&lt;br /&gt;
 psql -l&lt;br /&gt;
&lt;br /&gt;
=== Connect To A Database ===&lt;br /&gt;
&lt;br /&gt;
If your database has been created, you should be able to use the PostgreSQL client:&lt;br /&gt;
&lt;br /&gt;
 psql &amp;lt;databasename&amp;gt; [&amp;lt;username&amp;gt;]&lt;br /&gt;
&lt;br /&gt;
Since you are a superuser, you should be able to get amongst it without having to specify the username.&lt;br /&gt;
&lt;br /&gt;
=== Backslash Commands ===&lt;br /&gt;
&lt;br /&gt;
;TODO: once at the psql prompt, type \? for help with the various backslash commands, and \h for help with SQL syntax.&lt;br /&gt;
&lt;br /&gt;
{| border=1&lt;br /&gt;
|-&lt;br /&gt;
|  &amp;#039;&amp;#039;&amp;#039;Command&amp;#039;&amp;#039;&amp;#039;     || &amp;#039;&amp;#039;&amp;#039;Behaviour&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;\dt&amp;#039;&amp;#039;            || List the tables&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;\d &amp;lt;tablename&amp;gt;&amp;#039;&amp;#039; || Show table schema&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;\x&amp;#039;&amp;#039;             || Toggle to horizontal format when displaying rows&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;\i &amp;lt;filename&amp;gt;&amp;#039;&amp;#039;  || Execute a bunch of SQL in the file&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;\cd &amp;lt;path&amp;gt;&amp;#039;&amp;#039;     || Change directory (useful for \i)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;\l&amp;#039;&amp;#039;             || List all databases&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;\c &amp;lt;database&amp;gt;&amp;#039;&amp;#039;  || Connect to another database&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;\q&amp;#039;&amp;#039;             || Quit&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Backing Up And Restoring Databases ==&lt;br /&gt;
&lt;br /&gt;
We use the &amp;lt;tt&amp;gt;pg_dump&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;pg_restore&amp;lt;/tt&amp;gt; shell commands. Ownership of the database objects is probably the most common source of confusion here. Since most of the time ownership will not be more atomic than database-level, it is usually easiest to avoid the whole issue by not including ownership data in the dumps. It can then be safely determined by specifying the owner during the restore. This also means you can change the ownership if necessary, without unnecessary bloodshed.&lt;br /&gt;
&lt;br /&gt;
=== Backup ===&lt;br /&gt;
&lt;br /&gt;
To create a compressed format (-Fc) dump file (-f), that does not specify object ownerships (-O), execute the following:&lt;br /&gt;
&lt;br /&gt;
 pg_dump -Fc -O -f &amp;lt;dumpfile&amp;gt; &amp;lt;databasename&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Restore ===&lt;br /&gt;
&lt;br /&gt;
During a restore, the ownership is set to whichever user the restore command connects to the database as. So to restore a dump file into an existing database (-d), without using ownerships from the file (-O), but specifying the connecting user (-U) as the owner:&lt;br /&gt;
&lt;br /&gt;
 pg_restore -O -U &amp;lt;username&amp;gt; -d &amp;lt;databasename&amp;gt; &amp;lt;dumpfile&amp;gt;&lt;br /&gt;
&lt;br /&gt;
;NOTE: You usually want the database to be empty, having (re)created a new one for the restore.&lt;br /&gt;
&lt;br /&gt;
== Troubleshooting ==&lt;br /&gt;
&lt;br /&gt;
;I can&amp;#039;t drop the database!&lt;br /&gt;
:You may need to stop Apache before you can drop a database, otherwise PostgreSQL will complain that it is in use.&lt;br /&gt;
:Or, you can create a &amp;#039;&amp;#039;/usr/local/bin/pg_kill_connections&amp;#039;&amp;#039; script:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
#!/bin/sh&lt;br /&gt;
DATABASE=&amp;quot;$1&amp;quot;&lt;br /&gt;
&lt;br /&gt;
if [ -z &amp;quot;${DATABASE}&amp;quot; ];then&lt;br /&gt;
    echo &amp;quot;Usage: pg_kill_connections dbname&amp;quot;&lt;br /&gt;
    exit 1;&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
for i in $(su postgres -c \&lt;br /&gt;
       &amp;quot;psql -qt -c \&amp;quot;\\timing false\&amp;quot; \&lt;br /&gt;
             -c \&amp;quot;SELECT pid FROM pg_stat_activity WHERE datname=&amp;#039;${DATABASE}&amp;#039;\&amp;quot; \&lt;br /&gt;
             template1 | xargs -r kill&amp;quot;); do&lt;br /&gt;
    kill $i&lt;br /&gt;
done&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
;How do I rename a database?&lt;br /&gt;
:ALTER DATABASE &amp;quot;foo&amp;quot; RENAME TO &amp;quot;bar&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
;How do I concatenate strings?&lt;br /&gt;
:SELECT &amp;#039;Hello&amp;#039; || &amp;#039; &amp;#039; || &amp;#039;World&amp;#039;;&lt;br /&gt;
&lt;br /&gt;
== See Also ==&lt;br /&gt;
* [[PostgreSQL/From_MySQL]]&lt;br /&gt;
* [[PostgreSQL full text searching]]&lt;/div&gt;</summary>
		<author><name>Johnno</name></author>
	</entry>
	<entry>
		<id>https://wiki.jon.geek.nz/index.php?title=Hacks&amp;diff=2508</id>
		<title>Hacks</title>
		<link rel="alternate" type="text/html" href="https://wiki.jon.geek.nz/index.php?title=Hacks&amp;diff=2508"/>
		<updated>2024-06-12T23:57:32Z</updated>

		<summary type="html">&lt;p&gt;Johnno: /* Turn off the shitty default &amp;quot;visual&amp;quot; mouse mode in vim */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Image renaming by create date ==&lt;br /&gt;
&lt;br /&gt;
When you have a bunch of files from your old Android phone with a timestamp filename (e.g. 1388042328550.jpg), you can rename them thus:&lt;br /&gt;
&lt;br /&gt;
 for f in 1*.jpg; do&lt;br /&gt;
   mv $f $(date +IMG_%Y%m%d_%H%M%S.jpg -d @$(echo $f|cut -c 1-10))&lt;br /&gt;
 done&lt;br /&gt;
&lt;br /&gt;
Otherwise, we can fish out the Create Date from the EXIF data, using exiftool:&lt;br /&gt;
&lt;br /&gt;
 exiftool &amp;#039;-FileName&amp;lt;CreateDate&amp;#039; -d %Y%m%d_%H%M%S%%-c.%%e .&lt;br /&gt;
&lt;br /&gt;
== Use etckeeper ==&lt;br /&gt;
&lt;br /&gt;
It saves your bacon. Store changes to the {{path|/etc}} directory in git, uses hooks to commit changes when packages are updated, puppet runs, etc. Stash your own changes with useful commit messages. Look up stuff in history when something goes wrong, figure out what changes happened when packages are added or updated.&lt;br /&gt;
&lt;br /&gt;
=== Fix the daily commit bug ===&lt;br /&gt;
&lt;br /&gt;
Unfortunately since about 18.04 there is a bug where a systemd timer and a cron.daily task compete to commit a daily commit if needed; unfortunately one of them doesn&amp;#039;t bother to check the {{path|etckeeper.conf}} file to see whether you&amp;#039;ve disabled it. If you have &amp;lt;code&amp;gt;DISABLE_DAILY_AUTOCOMMITS=1&amp;lt;/code&amp;gt; in your config file, then you probably don&amp;#039;t want daily auto commits. If this is so, run this to disable the systemd timer:&lt;br /&gt;
&lt;br /&gt;
 systemctl disable --now etckeeper.timer&lt;br /&gt;
&lt;br /&gt;
== Repair broken or rotated phone videos ==&lt;br /&gt;
&lt;br /&gt;
You can fix broken video .tmp files from your Android phone using [https://github.com/ponchio/untrunc/ untrunc]. This will create a fixed.mp4 file in cwd:&lt;br /&gt;
&lt;br /&gt;
 untrunc working_video_from_the_same_camera.mp4 broken.mk4.tmp&lt;br /&gt;
&lt;br /&gt;
Did your phone unhelpfully rotate your video? Fix the metadata:&lt;br /&gt;
&lt;br /&gt;
 ffmpeg -i original.mp4 -acodec copy -vcodec copy -metadata:s:v:0 rotate=0 unrotated.mp4&lt;br /&gt;
&lt;br /&gt;
Or, did you actually film your shit the wrong way up? You&amp;#039;ll need to re-encode it:&lt;br /&gt;
&lt;br /&gt;
 ffmpeg -i original.mp4 -acodec copy -vcodec libx264 -crf 20 -metadata:s:v:0 rotate=0 unrotated.mp4&lt;br /&gt;
&lt;br /&gt;
== Export your photos ==&lt;br /&gt;
&lt;br /&gt;
Before uploading your photos, remove all the EXIF tags, and reduce the resolution; nobody needs 5000x4000 pixels, much less corporations hoovering up your stuff to put in adverts.&lt;br /&gt;
&lt;br /&gt;
 mkdir tmp&lt;br /&gt;
 for f in $.jpg; do&lt;br /&gt;
   convert -resize 1600x1200 $f tmp/$f&lt;br /&gt;
   exiftool -all= -P -overwrite_original tmp/$f&lt;br /&gt;
 done&lt;br /&gt;
&lt;br /&gt;
== Clean out your revoked and expired PGP keys ==&lt;br /&gt;
&lt;br /&gt;
Spring-clean your gpg database, make it go faster. Just go:&lt;br /&gt;
&lt;br /&gt;
 gpg --delete-keys $(gpg --list-public-keys|grep -PB1 &amp;#039;expired|revoked&amp;#039;|grep &amp;#039;^\s&amp;#039;)&lt;br /&gt;
&lt;br /&gt;
Obviously. If you can&amp;#039;t be arsed confirming each key, add &amp;lt;tt&amp;gt;--batch --yes&amp;lt;/tt&amp;gt; to the first gpg call.&lt;br /&gt;
&lt;br /&gt;
== Firefox opening your shit in gedit ==&lt;br /&gt;
&lt;br /&gt;
I don&amp;#039;t know, who thought that was a good idea? Jesus.&lt;br /&gt;
&lt;br /&gt;
 sed -i &amp;#039;s#.*octet-stream.*#application/octet-stream=xdg-open#&amp;#039; ~/.local/share/applications/mimeapps.list ~/.config/mimeapps.list&lt;br /&gt;
&lt;br /&gt;
== GNOME not sorting your folders first ==&lt;br /&gt;
&lt;br /&gt;
It&amp;#039;s not in a dialog anywhere, and a pretty lame default behaviour.&lt;br /&gt;
 dconf write /org/gnome/nautilus/preferences/sort-directories-first true&lt;br /&gt;
&lt;br /&gt;
== GNOME not dealing with WebP images ==&lt;br /&gt;
&lt;br /&gt;
I mean, it&amp;#039;s 2021 and WebP is only what, ten years old? Jesus. See solution on [https://askubuntu.com/a/617068 AskUbuntu].&lt;br /&gt;
&lt;br /&gt;
== Restoring huge databases to PostgreSQL ==&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;See also:&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039; &amp;#039;&amp;#039;[[PostgreSQL]]&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Skip some huge tables by dumping the TOC, removing culprit large tables, and restore with the edited TOC, e.g.&lt;br /&gt;
&lt;br /&gt;
 pg_restore -l huge.dump &amp;gt; TOC&lt;br /&gt;
 # edit the TOC file...&lt;br /&gt;
 pg_restore -L TOC -d dbname huge.dump&lt;br /&gt;
&lt;br /&gt;
== Output PostgreSQL queries to CSV ==&lt;br /&gt;
&lt;br /&gt;
 COPY (SELECT &amp;lt;query&amp;gt; ...) TO STDOUT CSV HEADER;&lt;br /&gt;
&lt;br /&gt;
== Turn off the shitty default &amp;quot;visual&amp;quot; mouse mode in vim ==&lt;br /&gt;
&lt;br /&gt;
Add this to &amp;lt;code&amp;gt;/etc/vim/vimrc.local&amp;lt;/code&amp;gt; file:&amp;lt;ref&amp;gt;Böhnke, H (16 March 2019). [https://unix.stackexchange.com/a/506723 Answer 506723] on &amp;quot;Disabling mouse support in vim in a gnome-terminal environment&amp;quot;, Unix &amp;amp; Linux Stack Exchange.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &amp;quot; Use skip_defaults_vim from the master /etc/vim/vimrc file&lt;br /&gt;
 if ! exists(&amp;#039;skip_defaults_vim&amp;#039;)&lt;br /&gt;
   &amp;quot; Source the defaults file manually from here&lt;br /&gt;
   source $VIMRUNTIME/defaults.vim&lt;br /&gt;
 endif&lt;br /&gt;
 &lt;br /&gt;
 &amp;quot; Avoid loading the defaults twice&lt;br /&gt;
 let g:skip_defaults_vim = 1&lt;br /&gt;
 &lt;br /&gt;
 &amp;quot; Revert any unwanted changes the defaults file introduced&lt;br /&gt;
 set mouse=&lt;br /&gt;
&lt;br /&gt;
== Too many leftover git branches merged into master? Nukem! ==&lt;br /&gt;
&lt;br /&gt;
This will remove any branches on your local git repo that have been merged to master.&lt;br /&gt;
&lt;br /&gt;
 for i in $(for b in $(git branch|grep -v &amp;#039;\*&amp;#039;); do git branch $b --merged master; done); \&lt;br /&gt;
     do git branch -D $i; \&lt;br /&gt;
 done&lt;br /&gt;
&lt;br /&gt;
== Move your MySQL databases ==&lt;br /&gt;
&lt;br /&gt;
Used to be you could move your /var/lib/mysql directory somewhere else and symlink it. You can, but in newer distros with Apparmor you&amp;#039;ll need to declare it:&lt;br /&gt;
&lt;br /&gt;
 # In /etc/apparmor.d/tunables/alias&lt;br /&gt;
 alias /var/lib/mysql/ -&amp;gt; /mnt/wherever/mysql/,&lt;br /&gt;
&lt;br /&gt;
Note the trailing comma.&lt;br /&gt;
&lt;br /&gt;
== Split audio CD rips using the cue file ==&lt;br /&gt;
&lt;br /&gt;
Single-file FLAC or Ape files of a CD can be split up using the .cue file for both the timestamps and the tagging data. Also, install flacon (from a PPA).&lt;br /&gt;
&lt;br /&gt;
 sudo apt install shntool&lt;br /&gt;
 shnsplit -o flac cdimage.flac -f cdimage.cue -t &amp;#039;%n.%t&amp;#039;&lt;br /&gt;
&lt;br /&gt;
You may need to do tags again, if they didn&amp;#039;t stick:&lt;br /&gt;
&lt;br /&gt;
 sudo apt install cuetools&lt;br /&gt;
 cuetag cdimage.cue *.flac&lt;br /&gt;
&lt;br /&gt;
== Ditch Snap ==&lt;br /&gt;
&lt;br /&gt;
=== 1. Install Firefox properly ===&lt;br /&gt;
&lt;br /&gt;
Ubuntu 22.04 replaces the Firefox Debian package with a pseudo-package that installs it using Snap. This is no longer optional, and it is also stupid, annoying, slow, and potentially insecure for many reasons.&amp;lt;ref&amp;gt;Brandon Hopkins. [https://techhut.tv/flatpak-vs-snap-vs-appimage/ &amp;quot;Flatpak vs. Snap vs. AppImage - Linux Packaging Benchmarks&amp;quot;] TechHut, April 2022.&amp;lt;/ref&amp;gt; Several Firefox extensions that need to talk to other applications don&amp;#039;t currently work in Snap installed Firefox, including things like Zotero and Keepass.&lt;br /&gt;
&lt;br /&gt;
It also completely fails to find and import any existing Firefox profile. Snap apps for whatever stupid reason keep settings in a hard-coded ~/snap folder. Who thought that was a good idea? What&amp;#039;s wrong with ~/.config and/or ~/.local, or couldn&amp;#039;t they even use ~/.snap? Good grief.&lt;br /&gt;
&lt;br /&gt;
Luckily, we can use the Mozilla Team PPA instead.&amp;lt;ref&amp;gt;Ji M. [https://ubuntuhandbook.org/index.php/2022/04/install-firefox-deb-ubuntu-22-04/ &amp;quot;How to Install Latest Firefox as classic Deb in Ubuntu 22.04&amp;quot;] Ubuntu Handbook, April 2022.&amp;lt;/ref&amp;gt; In summary:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Remove Firefox entirely:&lt;br /&gt;
snap remove firefox&lt;br /&gt;
apt remove firefox&lt;br /&gt;
&lt;br /&gt;
# Add the Mozilla Team PPA and install:&lt;br /&gt;
add-apt-repository ppa:mozillateam/ppa&lt;br /&gt;
apt update&lt;br /&gt;
apt install -t &amp;#039;o=LP-PPA-mozillateam&amp;#039; firefox&lt;br /&gt;
&lt;br /&gt;
# Pin to the Mozilla Team PPA so we never get the Snap pseudo-package&lt;br /&gt;
echo &amp;#039;Package: firefox*&lt;br /&gt;
Pin: release o=LP-PPA-mozillateam&lt;br /&gt;
Pin-Priority: 501&amp;#039; &amp;gt; /etc/apt/preferences.d/mozillateam-ppa.pref&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 2. Remove snap ===&lt;br /&gt;
&lt;br /&gt;
You can also remove snap entirely as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# get a list of things installed with snap:&lt;br /&gt;
snap list&lt;br /&gt;
&lt;br /&gt;
# remove them one by one:&lt;br /&gt;
snap uninstall &amp;#039;&amp;#039;program1&amp;#039;&amp;#039;&lt;br /&gt;
snap uninstall &amp;#039;&amp;#039;program2&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
# once there&amp;#039;s nothing left, remove snap:&lt;br /&gt;
apt purge snapd&lt;br /&gt;
&lt;br /&gt;
# then prevent it ever being re-installed with a pin preference:&lt;br /&gt;
echo &amp;#039;Package: snapd&lt;br /&gt;
 Pin: release a=*&lt;br /&gt;
 Pin-Priority: -10&amp;#039; &amp;gt; /etc/apt/preferences.d/no-snap.pref&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Fancy PostgreSQL prompts==&lt;br /&gt;
&lt;br /&gt;
For a coloured prompt including what user, connection, and host you&amp;#039;re on, stick this in ~/.psqlrc or /etc/postgresql-common/psqlrc:&lt;br /&gt;
&lt;br /&gt;
 \set PROMPT1 &amp;#039;%[%033[1m%](%n@%[%033[1;35m%]%M%[%033[m%]%[%033[1m%] on %[%033[1;31m%]%`hostname`%[%033[m%]%[%033[1m%]) \n%/%R%#%[%033[m%] &amp;#039;&lt;br /&gt;
 \set PROMPT2 &amp;#039;%[%033[1m%]%/%R%#%[%033[m%] &amp;#039;&lt;br /&gt;
 \set PROMPT3 &amp;#039;%[%033[1m%]&amp;gt;&amp;gt;%[%033[m%] &amp;#039;&lt;br /&gt;
&lt;br /&gt;
Escape codes use &amp;#039;%&amp;#039; character, documented here: [https://www.postgresql.org/docs/current/app-psql.html#APP-PSQL-PROMPTING Psql Prompts].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Notes==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;/div&gt;</summary>
		<author><name>Johnno</name></author>
	</entry>
	<entry>
		<id>https://wiki.jon.geek.nz/index.php?title=NextCloud&amp;diff=2507</id>
		<title>NextCloud</title>
		<link rel="alternate" type="text/html" href="https://wiki.jon.geek.nz/index.php?title=NextCloud&amp;diff=2507"/>
		<updated>2023-10-23T20:57:57Z</updated>

		<summary type="html">&lt;p&gt;Johnno: /* Configure NextCloud */ cache chunked upload note&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Assumes Ubuntu 20.04, stable20 branch, and installing in {{code|/var/www/nextcloud}} for a cloud.&amp;#039;&amp;#039;&amp;#039;example.com&amp;#039;&amp;#039;&amp;#039; URL (c. December 2020).&lt;br /&gt;
&lt;br /&gt;
== Prerequisites ==&lt;br /&gt;
&lt;br /&gt;
Install some stuff first. This NextCloud recipe uses [[PostgreSQL]], Redis, Apache 2.4, FastCGI with PHP FPM, and Dehydrated for [[Letsencrypt]] SSL certificate maangement.&lt;br /&gt;
&lt;br /&gt;
 sudo apt install apache2 libapache2-mod-fcgid \&lt;br /&gt;
    php7.4-{bcmath,bz2,curl,gd,fpm,gmp,intl,json,mbstring,opcache,pgsql,tidy,xmlrpc,xsl,zip}&lt;br /&gt;
    php-{imagick,redis} composer dehydrated postgresql redis-server&lt;br /&gt;
&lt;br /&gt;
;NOTE: NextCloud works fine under nginx, I just can&amp;#039;t be bothered maintaining what goes in {{code|.htaccess}} which NextCloud expects to be writeable to keep itself updated.&lt;br /&gt;
&lt;br /&gt;
== Configuring Apache and PHP ==&lt;br /&gt;
&lt;br /&gt;
: &amp;#039;&amp;#039;See the [[PHP]] page for setting up PHP with Apache, FPM and Event MPM.&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
=== Add a virtual host for NextCloud ===&lt;br /&gt;
&lt;br /&gt;
It should look something like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;apache&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;VirtualHost *:443&amp;gt;&lt;br /&gt;
   ServerName cloud.example.com&lt;br /&gt;
   DocumentRoot /var/www/nextcloud &lt;br /&gt;
 &lt;br /&gt;
   &amp;lt;Directory &amp;quot;/var/www/nexcloud&amp;quot;&amp;gt;&lt;br /&gt;
     Options FollowSymLinks MultiViews&lt;br /&gt;
     AllowOverride All&lt;br /&gt;
     Require all granted&lt;br /&gt;
     Satisfy Any &lt;br /&gt;
     SetEnv HOME /var/www/nextcloud&lt;br /&gt;
     SetEnv HTTP_HOME /var/www/nextcloud&lt;br /&gt;
 &lt;br /&gt;
     &amp;lt;IfModule mod_dav.c&amp;gt;&lt;br /&gt;
       Dav off&lt;br /&gt;
     &amp;lt;/IfModule&amp;gt;&lt;br /&gt;
   &amp;lt;/Directory&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
   SSLEngine On&lt;br /&gt;
   SSLCertificateFile ...&lt;br /&gt;
 &amp;lt;/VirtualHost&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== PHP settings ===&lt;br /&gt;
&lt;br /&gt;
Enable the opcache, increase the memory limit, and increase the maximum POST and file upload size so you can upload large files.&lt;br /&gt;
&lt;br /&gt;
== Create a database ==&lt;br /&gt;
&lt;br /&gt;
Create a database in [[PostgreSQL]]:&lt;br /&gt;
&lt;br /&gt;
 sudo -u postgres createuser -SDRP &amp;#039;&amp;#039;&amp;lt;nextcloud-user&amp;gt;&amp;#039;&amp;#039;&lt;br /&gt;
 sudo -u postgres createdb -E UTF8 -O &amp;#039;&amp;#039;&amp;lt;nextcloud-user&amp;gt;&amp;#039;&amp;#039; &amp;#039;&amp;#039;&amp;lt;nextcloud-dbname&amp;gt;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
== Install NextCloud ==&lt;br /&gt;
&lt;br /&gt;
We can just clone it from git:&lt;br /&gt;
&lt;br /&gt;
 git clone &amp;lt;nowiki&amp;gt;https://&amp;lt;/nowiki&amp;gt;github.com/nextcloud/server.git nextcloud&lt;br /&gt;
 cd nextcloud&lt;br /&gt;
 git checkout stable20  &amp;#039;&amp;#039;# or whatever the latest stable version is&amp;#039;&amp;#039;&lt;br /&gt;
 git submodule update --init --recursive&lt;br /&gt;
 chown www-data:www-data config apps .htaccess&lt;br /&gt;
&lt;br /&gt;
Create a directory for the cache and user data, which should not reside under the web root:&lt;br /&gt;
&lt;br /&gt;
 mkdir -p /var/lib/nextcloud/data /var/cache/nextcloud&lt;br /&gt;
 chown -R www-data:www-data /var/lib/nextcloud /var/cache/nextcloud&lt;br /&gt;
&lt;br /&gt;
== Configure NextCloud ==&lt;br /&gt;
&lt;br /&gt;
Edit the configuration file in {{code|config/config.php}} and check or consider these settings, and add the database and SMTP connection details:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
 $config =&amp;gt; [&lt;br /&gt;
   # ...&lt;br /&gt;
   #&lt;br /&gt;
   &amp;#039;passwordsalt&amp;#039; =&amp;gt; &amp;quot;&amp;lt;very long random string&amp;gt;&amp;quot;,&lt;br /&gt;
   &amp;#039;secret&amp;#039; =&amp;gt; &amp;quot;&amp;lt;a different very long random string&amp;gt;&amp;quot;,&lt;br /&gt;
   &amp;#039;trusted_domains&amp;#039; =&amp;gt; [&lt;br /&gt;
     0 =&amp;gt; &amp;quot;cloud.example.com&amp;quot;,&lt;br /&gt;
   ],&lt;br /&gt;
   &amp;#039;datadirectory&amp;#039; =&amp;gt; &amp;#039;/var/lib/nextcloud/data&amp;#039;,&lt;br /&gt;
   &amp;#039;overwrite.cli.url&amp;#039; =&amp;gt; &amp;#039;&amp;lt;nowiki&amp;gt;https://&amp;lt;/nowiki&amp;gt;cloud.example.com/&amp;#039;,&lt;br /&gt;
   &amp;#039;htaccess.RewriteBase&amp;#039; =&amp;gt; &amp;#039;/&amp;#039;,&lt;br /&gt;
 &lt;br /&gt;
   # Database connection details&lt;br /&gt;
   &amp;#039;dbtype&amp;#039; =&amp;gt; &amp;#039;pgsql&amp;#039;,&lt;br /&gt;
   &amp;#039;dbhost&amp;#039; =&amp;gt; &amp;#039;localhost&amp;#039;,&lt;br /&gt;
   &amp;#039;dbuser&amp;#039; =&amp;gt; &amp;quot;&amp;lt;nextcloud-dbuser&amp;gt;&amp;quot;,&lt;br /&gt;
   &amp;#039;dbpassword&amp;#039; =&amp;gt; &amp;quot;&amp;lt;password&amp;gt;&amp;quot;,&lt;br /&gt;
   &amp;#039;dbname&amp;#039; =&amp;gt; &amp;quot;&amp;lt;nextcloud-dbname&amp;gt;&amp;quot;,&lt;br /&gt;
   &amp;#039;dbtableprefix&amp;#039; =&amp;gt; &amp;#039;oc_&amp;#039;,&lt;br /&gt;
 &lt;br /&gt;
   # Force all URLs to use SSL or it may trip up things like OAuth&lt;br /&gt;
   &amp;#039;overwriteprotocol&amp;#039; =&amp;gt; &amp;#039;https&amp;#039;,&lt;br /&gt;
 &lt;br /&gt;
   # Use Redis and caching to make everything go faster&lt;br /&gt;
   &amp;#039;memcache.local&amp;#039; =&amp;gt; &amp;#039;\\OC\\Memcache\\Redis&amp;#039;,&lt;br /&gt;
   &amp;#039;memcache.locking&amp;#039; =&amp;gt; &amp;#039;\\OC\\Memcache\\Redis&amp;#039;,&lt;br /&gt;
   &amp;#039;redis&amp;#039; =&amp;gt; [&lt;br /&gt;
     &amp;#039;host&amp;#039; =&amp;gt; &amp;#039;localhost&amp;#039;,&lt;br /&gt;
     &amp;#039;port&amp;#039; =&amp;gt; 6379,&lt;br /&gt;
   ],&lt;br /&gt;
   &amp;#039;cache_path&amp;#039; =&amp;gt; &amp;#039;/var/cache/nextcloud&amp;#039;,&lt;br /&gt;
 &lt;br /&gt;
   # Send email details&lt;br /&gt;
   &amp;#039;mail_smtpmode&amp;#039; =&amp;gt; &amp;#039;smtp&amp;#039;,&lt;br /&gt;
   &amp;#039;mail_smtpsecure&amp;#039; =&amp;gt; &amp;#039;tls&amp;#039;,&lt;br /&gt;
   &amp;#039;mail_sendmailmode&amp;#039; =&amp;gt; &amp;#039;smtp&amp;#039;,&lt;br /&gt;
   &amp;#039;mail_from_address&amp;#039; =&amp;gt; &amp;quot;nexcloud@example.com&amp;quot;,&lt;br /&gt;
   &amp;#039;mail_domain&amp;#039; =&amp;gt; &amp;quot;example.com&amp;quot;,&lt;br /&gt;
   &amp;#039;mail_smtpauthtype&amp;#039; =&amp;gt; &amp;#039;PLAIN&amp;#039;,&lt;br /&gt;
   &amp;#039;mail_smtpauth&amp;#039; =&amp;gt; 1,&lt;br /&gt;
   &amp;#039;mail_smtphost&amp;#039; =&amp;gt; &amp;quot;mail.example.com&amp;quot;,&lt;br /&gt;
   &amp;#039;mail_smtpport&amp;#039; =&amp;gt; 587,&lt;br /&gt;
   &amp;#039;mail_smtpname&amp;#039; =&amp;gt; &amp;quot;&amp;lt;emailuser&amp;gt;&amp;quot;,&lt;br /&gt;
   &amp;#039;mail_smtppassword&amp;#039; =&amp;gt; &amp;quot;&amp;lt;emailpassword&amp;gt;&amp;quot;,&lt;br /&gt;
 &lt;br /&gt;
   # ...&lt;br /&gt;
 ]  &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then navigate to the URL in the browser to install (or run the NextCloud {{code | ./occ}} tool from the command line).&lt;br /&gt;
&lt;br /&gt;
;Note: Make sure that the directory used for {{code|cache_path}} exists and is writeable, or you will get weird seemingly unrelated 403 MKCOL errors to do with [https://docs.nextcloud.com/server/26/admin_manual/configuration_files/big_file_upload_configuration.html chunked uploads].&lt;br /&gt;
&lt;br /&gt;
=== Clean URLs ===&lt;br /&gt;
&lt;br /&gt;
For clean URLs, make sure {{code | AllowOverride All}} is set for the parent directory; the {{code | /var/www}} definition is in the main {{code | /etc/apache2/apache.conf}}. Then run the follwing OCC command to enable the rewrite rules:&lt;br /&gt;
&lt;br /&gt;
 sudo -u www-data ./occ maintenance:update:htaccess&lt;br /&gt;
&lt;br /&gt;
=== Previews of other file types ===&lt;br /&gt;
&lt;br /&gt;
Edit {{code|/etc/ImageMagick/policy.xml}} and remove this line to get PDF previews to work:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;policy domain=&amp;quot;coder&amp;quot; rights=&amp;quot;none&amp;quot; pattern=&amp;quot;PDF&amp;quot; /&amp;gt; &amp;lt;!-- remove this line --&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then add the following to {{code|config.php}} to get lots of other useful file previews:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
   &amp;#039;enabledPreviewProviders&amp;#039; =&amp;gt; [&lt;br /&gt;
     # ...&lt;br /&gt;
     8 =&amp;gt; &amp;#039;OC\\Preview\\MarkDown&amp;#039;,&lt;br /&gt;
     9 =&amp;gt; &amp;#039;OC\\Preview\\Movie&amp;#039;,&lt;br /&gt;
     10 =&amp;gt; &amp;#039;OC\\Preview\\PDF&amp;#039;,&lt;br /&gt;
     11 =&amp;gt; &amp;#039;OC\\Preview\\OpenDocument&amp;#039;,&lt;br /&gt;
     12 =&amp;gt; &amp;#039;OC\\Preview\\MSOfficeDoc&amp;#039;,&lt;br /&gt;
     13 =&amp;gt; &amp;#039;OC\\Preview\\MSOffice2003&amp;#039;,&lt;br /&gt;
     14 =&amp;gt; &amp;#039;OC\\Preview\\MSOffice2007&amp;#039;,&lt;br /&gt;
   ],&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Photos ===&lt;br /&gt;
&lt;br /&gt;
Photos replaces the Gallery app, and is installed separately through the NC store or you can use git to manage it as a submodule. If it doesn&amp;#039;t work you might need to build its JavaScript resources by running {{code|make}} in its {{code|apps/photos}} directory. Alternatively you can resuscitate the Gallery app, which stopped working after NextCloud version 17, by updating its JavaScript dompurify library to a [https://raw.githubusercontent.com/nextcloud/gallery/ecb26a812f30a3f516964808ccfa6430be09b45e/js/vendor/dompurify/src/purify.js newer version] and bumping the app max version in {{code|apps/galleryappinfo/info.xml}} as follows (See also [https://github.com/nextcloud/gallery/pull/570/ pull request #570]):&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nextcloud min-version=&amp;quot;17&amp;quot; max-version=&amp;quot;&amp;#039;&amp;#039;&amp;#039;20&amp;#039;&amp;#039;&amp;#039;&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== NextCloud Talk ===&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;Note:&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039; &amp;#039;&amp;#039;A TURN server can also be used for other things, like your own [https://matrix-org.github.io/synapse/v1.41/turn-howto.html Matrix] chat server.&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
To be at all useful, you need a TURN server. This is easiest achieved by installing and correctly configuring coturn, which also acts as a STUN server. STUN is for clients to figure out their external IP address, and TURN is for relaying UDP packets, e.g. for WebRTC.&lt;br /&gt;
&lt;br /&gt;
 sudo apt install coturn&lt;br /&gt;
&lt;br /&gt;
For it to actually do anything (it is disabled by default!) you need to edit {{code|/etc/default/coturn}} and make sure it contains the following, and is not commented out:&lt;br /&gt;
&lt;br /&gt;
 TURNSERVER_ENABLED=1&lt;br /&gt;
&lt;br /&gt;
Then in {{code|/etc/turnserver.conf}} you need to configure its domain name, IP addresses and ports, SSL certificate, and how TURN authenticates. See GitHub for a fully documented example [https://github.com/coturn/coturn/blob/master/examples/etc/turnserver.conf turnserver.conf] file. This example uses the same domain as the NextCloud instance, on the standard STUN and TURN ports, but if you want to host it on port 443 to support people behind restrictive firewalls, you will need a different subdomain and/or IP address:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;ini&amp;quot;&amp;gt;&lt;br /&gt;
 server-name=cloud.example.com&lt;br /&gt;
 realm=cloud.example.com&lt;br /&gt;
 &lt;br /&gt;
 # When hosted on an internal LAN or DMZ, it might look like this: &lt;br /&gt;
 listening-ip=192.168.1.100&lt;br /&gt;
 relay-ip=192.168.1.100&lt;br /&gt;
 external-ip=123.45.67.8&lt;br /&gt;
 &lt;br /&gt;
 # Or use the short-hand:&lt;br /&gt;
 external-ip=123.45.67.8/192.168.1.100&lt;br /&gt;
 &lt;br /&gt;
 # Specify listening ports; originally 3478 was unencrypted, and 5349 was TLS,&lt;br /&gt;
 # but now TLS is supported on both. It is possible to listen on 443, which will&lt;br /&gt;
 # help to provide connectivity for people behind port-limited firewalls; this will&lt;br /&gt;
 # conflict with any HTTPS web hosting on the same server though, unless you set&lt;br /&gt;
 # up a second IP address for it.&lt;br /&gt;
 listening-port=3478&lt;br /&gt;
 tls-listening-port=5349&lt;br /&gt;
 #tls-listening-port=443&lt;br /&gt;
 &lt;br /&gt;
 # Specify a UDP port range and ensure they are exposed through the firewall/router&lt;br /&gt;
 min-port=53490&lt;br /&gt;
 max-port=59999&lt;br /&gt;
 &lt;br /&gt;
 # SSL setup; &lt;br /&gt;
 cert=/path/to/cloud.example.com/fullchain.cert&lt;br /&gt;
 pkey=/path/to/cloud.example.com/privkey.pem&lt;br /&gt;
 no-tlsv1&lt;br /&gt;
 no-tlsv1_1&lt;br /&gt;
 &lt;br /&gt;
 # To use with NextCloud, set a shared secret here.&lt;br /&gt;
 use-auth-secret&lt;br /&gt;
 static-auth-secret=your-shared-secret-string-here&lt;br /&gt;
 stale-nonce=600&lt;br /&gt;
 &lt;br /&gt;
 # Limit STUN amplification/gain attacks (coturn 4.5.2+)&lt;br /&gt;
 no-stun-backward-compatibility&lt;br /&gt;
 response-origin-only-with-rfc5780&lt;br /&gt;
 &lt;br /&gt;
 # RFC-5780 support requires two listening IP addresses and is for serious-cat&lt;br /&gt;
 # usage, so you can safely disable it for a small home NextCloud instance.&lt;br /&gt;
 no-rfc5780&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In your NextCloud Administration section, you can now configure Talk to use the STUN/TURN server, using your server URLs, and provide the same shared secret you configured above. For maximum compatibility, use both UDP and TCP, and both turn and turns (TLS) connections:&lt;br /&gt;
&lt;br /&gt;
 stun: &amp;#039;&amp;#039;&amp;#039;cloud.example.com&amp;#039;&amp;#039;&amp;#039;:5349&lt;br /&gt;
 turn and turns: &amp;#039;&amp;#039;&amp;#039;cloud.example.com&amp;#039;&amp;#039;&amp;#039;:5349&lt;br /&gt;
&lt;br /&gt;
Test your server [https://webrtc.github.io/samples/src/content/peerconnection/trickle-ice/ here]. If STUN is working, you should get {{code|srflx}} candidates, and {{code|relay}} candidates if TURN is working.&lt;br /&gt;
&lt;br /&gt;
Sources and further reading:&lt;br /&gt;
* NextCloud Talk documentation: [https://nextcloud-talk.readthedocs.io/en/latest/TURN/ TURN], [https://nextcloud-talk.readthedocs.io/en/latest/coturn coturn]&lt;br /&gt;
* NextCloud Help, [https://help.nextcloud.com/t/howto-setup-nextcloud-talk-with-turn-server/30794 1] [https://help.nextcloud.com/t/nextcloud-talk-app-could-not-establish-a-connection-a-turn-server/131069/31 2]&lt;br /&gt;
* Stack Overflow [https://stackoverflow.com/questions/42801361/install-rfc5766-turn-server-trying-to-bind-fd-to-ip-address-errno-99 1]&lt;br /&gt;
* [https://ourcodeworld.com/articles/read/1526/how-to-test-online-whether-a-stun-turn-server-is-working-properly-or-not Testing STUN/TURN]&lt;br /&gt;
&lt;br /&gt;
=== NextCloud Office ===&lt;br /&gt;
&lt;br /&gt;
Install Collabora Office Online (COOL) which emerged from the smoking ruins of LibreOffice Online (LOOL):&lt;br /&gt;
&lt;br /&gt;
 apt install coolwsd code-brand&lt;br /&gt;
&lt;br /&gt;
Use an Apache reverse proxy to handle the host and SSL, disable SSL in WOPI setup; restrict NextCloud and coolwsd requests to their respective endpoints, IP addresses; see [https://c-nergy.be/blog/?p=18055 &amp;quot;Install CODE on NextCloud on Ubuntu 22.04&amp;quot;]&lt;br /&gt;
&lt;br /&gt;
== Maintenance ==&lt;br /&gt;
&lt;br /&gt;
Keep the git checkout of NextCloud and its submodules up to date with git, and run the OCC upgrade command:&lt;br /&gt;
&lt;br /&gt;
 cd /var/www/nextcloud&lt;br /&gt;
 git pull&lt;br /&gt;
 git submodule update --init --recursive&lt;br /&gt;
 sudo -u www-data ./occ upgrade&lt;br /&gt;
&lt;br /&gt;
=== Cron job ===&lt;br /&gt;
&lt;br /&gt;
In the administrator settings select cron rather than other methods, and put this in {{code|/etc/cron.d/nextcloud}}&lt;br /&gt;
&lt;br /&gt;
 */5 * * * * www-data /usr/bin/php /var/www/nextcloud/cron.php&lt;/div&gt;</summary>
		<author><name>Johnno</name></author>
	</entry>
	<entry>
		<id>https://wiki.jon.geek.nz/index.php?title=NextCloud&amp;diff=2506</id>
		<title>NextCloud</title>
		<link rel="alternate" type="text/html" href="https://wiki.jon.geek.nz/index.php?title=NextCloud&amp;diff=2506"/>
		<updated>2023-09-18T05:11:58Z</updated>

		<summary type="html">&lt;p&gt;Johnno: /* Office */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Assumes Ubuntu 20.04, stable20 branch, and installing in {{code|/var/www/nextcloud}} for a cloud.&amp;#039;&amp;#039;&amp;#039;example.com&amp;#039;&amp;#039;&amp;#039; URL (c. December 2020).&lt;br /&gt;
&lt;br /&gt;
== Prerequisites ==&lt;br /&gt;
&lt;br /&gt;
Install some stuff first. This NextCloud recipe uses [[PostgreSQL]], Redis, Apache 2.4, FastCGI with PHP FPM, and Dehydrated for [[Letsencrypt]] SSL certificate maangement.&lt;br /&gt;
&lt;br /&gt;
 sudo apt install apache2 libapache2-mod-fcgid \&lt;br /&gt;
    php7.4-{bcmath,bz2,curl,gd,fpm,gmp,intl,json,mbstring,opcache,pgsql,tidy,xmlrpc,xsl,zip}&lt;br /&gt;
    php-{imagick,redis} composer dehydrated postgresql redis-server&lt;br /&gt;
&lt;br /&gt;
;NOTE: NextCloud works fine under nginx, I just can&amp;#039;t be bothered maintaining what goes in {{code|.htaccess}} which NextCloud expects to be writeable to keep itself updated.&lt;br /&gt;
&lt;br /&gt;
== Configuring Apache and PHP ==&lt;br /&gt;
&lt;br /&gt;
: &amp;#039;&amp;#039;See the [[PHP]] page for setting up PHP with Apache, FPM and Event MPM.&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
=== Add a virtual host for NextCloud ===&lt;br /&gt;
&lt;br /&gt;
It should look something like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;apache&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;VirtualHost *:443&amp;gt;&lt;br /&gt;
   ServerName cloud.example.com&lt;br /&gt;
   DocumentRoot /var/www/nextcloud &lt;br /&gt;
 &lt;br /&gt;
   &amp;lt;Directory &amp;quot;/var/www/nexcloud&amp;quot;&amp;gt;&lt;br /&gt;
     Options FollowSymLinks MultiViews&lt;br /&gt;
     AllowOverride All&lt;br /&gt;
     Require all granted&lt;br /&gt;
     Satisfy Any &lt;br /&gt;
     SetEnv HOME /var/www/nextcloud&lt;br /&gt;
     SetEnv HTTP_HOME /var/www/nextcloud&lt;br /&gt;
 &lt;br /&gt;
     &amp;lt;IfModule mod_dav.c&amp;gt;&lt;br /&gt;
       Dav off&lt;br /&gt;
     &amp;lt;/IfModule&amp;gt;&lt;br /&gt;
   &amp;lt;/Directory&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
   SSLEngine On&lt;br /&gt;
   SSLCertificateFile ...&lt;br /&gt;
 &amp;lt;/VirtualHost&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== PHP settings ===&lt;br /&gt;
&lt;br /&gt;
Enable the opcache, increase the memory limit, and increase the maximum POST and file upload size so you can upload large files.&lt;br /&gt;
&lt;br /&gt;
== Create a database ==&lt;br /&gt;
&lt;br /&gt;
Create a database in [[PostgreSQL]]:&lt;br /&gt;
&lt;br /&gt;
 sudo -u postgres createuser -SDRP &amp;#039;&amp;#039;&amp;lt;nextcloud-user&amp;gt;&amp;#039;&amp;#039;&lt;br /&gt;
 sudo -u postgres createdb -E UTF8 -O &amp;#039;&amp;#039;&amp;lt;nextcloud-user&amp;gt;&amp;#039;&amp;#039; &amp;#039;&amp;#039;&amp;lt;nextcloud-dbname&amp;gt;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
== Install NextCloud ==&lt;br /&gt;
&lt;br /&gt;
We can just clone it from git:&lt;br /&gt;
&lt;br /&gt;
 git clone &amp;lt;nowiki&amp;gt;https://&amp;lt;/nowiki&amp;gt;github.com/nextcloud/server.git nextcloud&lt;br /&gt;
 cd nextcloud&lt;br /&gt;
 git checkout stable20  &amp;#039;&amp;#039;# or whatever the latest stable version is&amp;#039;&amp;#039;&lt;br /&gt;
 git submodule update --init --recursive&lt;br /&gt;
 chown www-data:www-data config apps .htaccess&lt;br /&gt;
&lt;br /&gt;
Create a directory for the cache and user data, which should not reside under the web root:&lt;br /&gt;
&lt;br /&gt;
 mkdir -p /var/lib/nextcloud/data /var/cache/nextcloud&lt;br /&gt;
 chown -R www-data:www-data /var/lib/nextcloud /var/cache/nextcloud&lt;br /&gt;
&lt;br /&gt;
== Configure NextCloud ==&lt;br /&gt;
&lt;br /&gt;
Edit the configuration file in {{code|config/config.php}} and check or consider these settings, and add the database and SMTP connection details:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
 $config =&amp;gt; [&lt;br /&gt;
   # ...&lt;br /&gt;
   #&lt;br /&gt;
   &amp;#039;passwordsalt&amp;#039; =&amp;gt; &amp;quot;&amp;lt;very long random string&amp;gt;&amp;quot;,&lt;br /&gt;
   &amp;#039;secret&amp;#039; =&amp;gt; &amp;quot;&amp;lt;a different very long random string&amp;gt;&amp;quot;,&lt;br /&gt;
   &amp;#039;trusted_domains&amp;#039; =&amp;gt; [&lt;br /&gt;
     0 =&amp;gt; &amp;quot;cloud.example.com&amp;quot;,&lt;br /&gt;
   ],&lt;br /&gt;
   &amp;#039;datadirectory&amp;#039; =&amp;gt; &amp;#039;/var/lib/nextcloud/data&amp;#039;,&lt;br /&gt;
   &amp;#039;overwrite.cli.url&amp;#039; =&amp;gt; &amp;#039;&amp;lt;nowiki&amp;gt;https://&amp;lt;/nowiki&amp;gt;cloud.example.com/&amp;#039;,&lt;br /&gt;
   &amp;#039;htaccess.RewriteBase&amp;#039; =&amp;gt; &amp;#039;/&amp;#039;,&lt;br /&gt;
 &lt;br /&gt;
   # Database connection details&lt;br /&gt;
   &amp;#039;dbtype&amp;#039; =&amp;gt; &amp;#039;pgsql&amp;#039;,&lt;br /&gt;
   &amp;#039;dbhost&amp;#039; =&amp;gt; &amp;#039;localhost&amp;#039;,&lt;br /&gt;
   &amp;#039;dbuser&amp;#039; =&amp;gt; &amp;quot;&amp;lt;nextcloud-dbuser&amp;gt;&amp;quot;,&lt;br /&gt;
   &amp;#039;dbpassword&amp;#039; =&amp;gt; &amp;quot;&amp;lt;password&amp;gt;&amp;quot;,&lt;br /&gt;
   &amp;#039;dbname&amp;#039; =&amp;gt; &amp;quot;&amp;lt;nextcloud-dbname&amp;gt;&amp;quot;,&lt;br /&gt;
   &amp;#039;dbtableprefix&amp;#039; =&amp;gt; &amp;#039;oc_&amp;#039;,&lt;br /&gt;
 &lt;br /&gt;
   # Force all URLs to use SSL or it may trip up things like OAuth&lt;br /&gt;
   &amp;#039;overwriteprotocol&amp;#039; =&amp;gt; &amp;#039;https&amp;#039;,&lt;br /&gt;
 &lt;br /&gt;
   # Use Redis and caching to make everything go faster&lt;br /&gt;
   &amp;#039;memcache.local&amp;#039; =&amp;gt; &amp;#039;\\OC\\Memcache\\Redis&amp;#039;,&lt;br /&gt;
   &amp;#039;memcache.locking&amp;#039; =&amp;gt; &amp;#039;\\OC\\Memcache\\Redis&amp;#039;,&lt;br /&gt;
   &amp;#039;redis&amp;#039; =&amp;gt; [&lt;br /&gt;
     &amp;#039;host&amp;#039; =&amp;gt; &amp;#039;localhost&amp;#039;,&lt;br /&gt;
     &amp;#039;port&amp;#039; =&amp;gt; 6379,&lt;br /&gt;
   ],&lt;br /&gt;
   &amp;#039;cache_path&amp;#039; =&amp;gt; &amp;#039;/var/cache/nextcloud&amp;#039;,&lt;br /&gt;
 &lt;br /&gt;
   # Send email details&lt;br /&gt;
   &amp;#039;mail_smtpmode&amp;#039; =&amp;gt; &amp;#039;smtp&amp;#039;,&lt;br /&gt;
   &amp;#039;mail_smtpsecure&amp;#039; =&amp;gt; &amp;#039;tls&amp;#039;,&lt;br /&gt;
   &amp;#039;mail_sendmailmode&amp;#039; =&amp;gt; &amp;#039;smtp&amp;#039;,&lt;br /&gt;
   &amp;#039;mail_from_address&amp;#039; =&amp;gt; &amp;quot;nexcloud@example.com&amp;quot;,&lt;br /&gt;
   &amp;#039;mail_domain&amp;#039; =&amp;gt; &amp;quot;example.com&amp;quot;,&lt;br /&gt;
   &amp;#039;mail_smtpauthtype&amp;#039; =&amp;gt; &amp;#039;PLAIN&amp;#039;,&lt;br /&gt;
   &amp;#039;mail_smtpauth&amp;#039; =&amp;gt; 1,&lt;br /&gt;
   &amp;#039;mail_smtphost&amp;#039; =&amp;gt; &amp;quot;mail.example.com&amp;quot;,&lt;br /&gt;
   &amp;#039;mail_smtpport&amp;#039; =&amp;gt; 587,&lt;br /&gt;
   &amp;#039;mail_smtpname&amp;#039; =&amp;gt; &amp;quot;&amp;lt;emailuser&amp;gt;&amp;quot;,&lt;br /&gt;
   &amp;#039;mail_smtppassword&amp;#039; =&amp;gt; &amp;quot;&amp;lt;emailpassword&amp;gt;&amp;quot;,&lt;br /&gt;
 &lt;br /&gt;
   # ...&lt;br /&gt;
 ]  &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then navigate to the URL in the browser to install (or run the NextCloud {{code | ./occ}} tool from the command line).&lt;br /&gt;
&lt;br /&gt;
=== Clean URLs ===&lt;br /&gt;
&lt;br /&gt;
For clean URLs, make sure {{code | AllowOverride All}} is set for the parent directory; the {{code | /var/www}} definition is in the main {{code | /etc/apache2/apache.conf}}. Then run the follwing OCC command to enable the rewrite rules:&lt;br /&gt;
&lt;br /&gt;
 sudo -u www-data ./occ maintenance:update:htaccess&lt;br /&gt;
&lt;br /&gt;
=== Previews of other file types ===&lt;br /&gt;
&lt;br /&gt;
Edit {{code|/etc/ImageMagick/policy.xml}} and remove this line to get PDF previews to work:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;policy domain=&amp;quot;coder&amp;quot; rights=&amp;quot;none&amp;quot; pattern=&amp;quot;PDF&amp;quot; /&amp;gt; &amp;lt;!-- remove this line --&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then add the following to {{code|config.php}} to get lots of other useful file previews:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
   &amp;#039;enabledPreviewProviders&amp;#039; =&amp;gt; [&lt;br /&gt;
     # ...&lt;br /&gt;
     8 =&amp;gt; &amp;#039;OC\\Preview\\MarkDown&amp;#039;,&lt;br /&gt;
     9 =&amp;gt; &amp;#039;OC\\Preview\\Movie&amp;#039;,&lt;br /&gt;
     10 =&amp;gt; &amp;#039;OC\\Preview\\PDF&amp;#039;,&lt;br /&gt;
     11 =&amp;gt; &amp;#039;OC\\Preview\\OpenDocument&amp;#039;,&lt;br /&gt;
     12 =&amp;gt; &amp;#039;OC\\Preview\\MSOfficeDoc&amp;#039;,&lt;br /&gt;
     13 =&amp;gt; &amp;#039;OC\\Preview\\MSOffice2003&amp;#039;,&lt;br /&gt;
     14 =&amp;gt; &amp;#039;OC\\Preview\\MSOffice2007&amp;#039;,&lt;br /&gt;
   ],&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Photos ===&lt;br /&gt;
&lt;br /&gt;
Photos replaces the Gallery app, and is installed separately through the NC store or you can use git to manage it as a submodule. If it doesn&amp;#039;t work you might need to build its JavaScript resources by running {{code|make}} in its {{code|apps/photos}} directory. Alternatively you can resuscitate the Gallery app, which stopped working after NextCloud version 17, by updating its JavaScript dompurify library to a [https://raw.githubusercontent.com/nextcloud/gallery/ecb26a812f30a3f516964808ccfa6430be09b45e/js/vendor/dompurify/src/purify.js newer version] and bumping the app max version in {{code|apps/galleryappinfo/info.xml}} as follows (See also [https://github.com/nextcloud/gallery/pull/570/ pull request #570]):&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nextcloud min-version=&amp;quot;17&amp;quot; max-version=&amp;quot;&amp;#039;&amp;#039;&amp;#039;20&amp;#039;&amp;#039;&amp;#039;&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== NextCloud Talk ===&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;Note:&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039; &amp;#039;&amp;#039;A TURN server can also be used for other things, like your own [https://matrix-org.github.io/synapse/v1.41/turn-howto.html Matrix] chat server.&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
To be at all useful, you need a TURN server. This is easiest achieved by installing and correctly configuring coturn, which also acts as a STUN server. STUN is for clients to figure out their external IP address, and TURN is for relaying UDP packets, e.g. for WebRTC.&lt;br /&gt;
&lt;br /&gt;
 sudo apt install coturn&lt;br /&gt;
&lt;br /&gt;
For it to actually do anything (it is disabled by default!) you need to edit {{code|/etc/default/coturn}} and make sure it contains the following, and is not commented out:&lt;br /&gt;
&lt;br /&gt;
 TURNSERVER_ENABLED=1&lt;br /&gt;
&lt;br /&gt;
Then in {{code|/etc/turnserver.conf}} you need to configure its domain name, IP addresses and ports, SSL certificate, and how TURN authenticates. See GitHub for a fully documented example [https://github.com/coturn/coturn/blob/master/examples/etc/turnserver.conf turnserver.conf] file. This example uses the same domain as the NextCloud instance, on the standard STUN and TURN ports, but if you want to host it on port 443 to support people behind restrictive firewalls, you will need a different subdomain and/or IP address:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;ini&amp;quot;&amp;gt;&lt;br /&gt;
 server-name=cloud.example.com&lt;br /&gt;
 realm=cloud.example.com&lt;br /&gt;
 &lt;br /&gt;
 # When hosted on an internal LAN or DMZ, it might look like this: &lt;br /&gt;
 listening-ip=192.168.1.100&lt;br /&gt;
 relay-ip=192.168.1.100&lt;br /&gt;
 external-ip=123.45.67.8&lt;br /&gt;
 &lt;br /&gt;
 # Or use the short-hand:&lt;br /&gt;
 external-ip=123.45.67.8/192.168.1.100&lt;br /&gt;
 &lt;br /&gt;
 # Specify listening ports; originally 3478 was unencrypted, and 5349 was TLS,&lt;br /&gt;
 # but now TLS is supported on both. It is possible to listen on 443, which will&lt;br /&gt;
 # help to provide connectivity for people behind port-limited firewalls; this will&lt;br /&gt;
 # conflict with any HTTPS web hosting on the same server though, unless you set&lt;br /&gt;
 # up a second IP address for it.&lt;br /&gt;
 listening-port=3478&lt;br /&gt;
 tls-listening-port=5349&lt;br /&gt;
 #tls-listening-port=443&lt;br /&gt;
 &lt;br /&gt;
 # Specify a UDP port range and ensure they are exposed through the firewall/router&lt;br /&gt;
 min-port=53490&lt;br /&gt;
 max-port=59999&lt;br /&gt;
 &lt;br /&gt;
 # SSL setup; &lt;br /&gt;
 cert=/path/to/cloud.example.com/fullchain.cert&lt;br /&gt;
 pkey=/path/to/cloud.example.com/privkey.pem&lt;br /&gt;
 no-tlsv1&lt;br /&gt;
 no-tlsv1_1&lt;br /&gt;
 &lt;br /&gt;
 # To use with NextCloud, set a shared secret here.&lt;br /&gt;
 use-auth-secret&lt;br /&gt;
 static-auth-secret=your-shared-secret-string-here&lt;br /&gt;
 stale-nonce=600&lt;br /&gt;
 &lt;br /&gt;
 # Limit STUN amplification/gain attacks (coturn 4.5.2+)&lt;br /&gt;
 no-stun-backward-compatibility&lt;br /&gt;
 response-origin-only-with-rfc5780&lt;br /&gt;
 &lt;br /&gt;
 # RFC-5780 support requires two listening IP addresses and is for serious-cat&lt;br /&gt;
 # usage, so you can safely disable it for a small home NextCloud instance.&lt;br /&gt;
 no-rfc5780&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In your NextCloud Administration section, you can now configure Talk to use the STUN/TURN server, using your server URLs, and provide the same shared secret you configured above. For maximum compatibility, use both UDP and TCP, and both turn and turns (TLS) connections:&lt;br /&gt;
&lt;br /&gt;
 stun: &amp;#039;&amp;#039;&amp;#039;cloud.example.com&amp;#039;&amp;#039;&amp;#039;:5349&lt;br /&gt;
 turn and turns: &amp;#039;&amp;#039;&amp;#039;cloud.example.com&amp;#039;&amp;#039;&amp;#039;:5349&lt;br /&gt;
&lt;br /&gt;
Test your server [https://webrtc.github.io/samples/src/content/peerconnection/trickle-ice/ here]. If STUN is working, you should get {{code|srflx}} candidates, and {{code|relay}} candidates if TURN is working.&lt;br /&gt;
&lt;br /&gt;
Sources and further reading:&lt;br /&gt;
* NextCloud Talk documentation: [https://nextcloud-talk.readthedocs.io/en/latest/TURN/ TURN], [https://nextcloud-talk.readthedocs.io/en/latest/coturn coturn]&lt;br /&gt;
* NextCloud Help, [https://help.nextcloud.com/t/howto-setup-nextcloud-talk-with-turn-server/30794 1] [https://help.nextcloud.com/t/nextcloud-talk-app-could-not-establish-a-connection-a-turn-server/131069/31 2]&lt;br /&gt;
* Stack Overflow [https://stackoverflow.com/questions/42801361/install-rfc5766-turn-server-trying-to-bind-fd-to-ip-address-errno-99 1]&lt;br /&gt;
* [https://ourcodeworld.com/articles/read/1526/how-to-test-online-whether-a-stun-turn-server-is-working-properly-or-not Testing STUN/TURN]&lt;br /&gt;
&lt;br /&gt;
=== NextCloud Office ===&lt;br /&gt;
&lt;br /&gt;
Install Collabora Office Online (COOL) which emerged from the smoking ruins of LibreOffice Online (LOOL):&lt;br /&gt;
&lt;br /&gt;
 apt install coolwsd code-brand&lt;br /&gt;
&lt;br /&gt;
Use an Apache reverse proxy to handle the host and SSL, disable SSL in WOPI setup; restrict NextCloud and coolwsd requests to their respective endpoints, IP addresses; see [https://c-nergy.be/blog/?p=18055 &amp;quot;Install CODE on NextCloud on Ubuntu 22.04&amp;quot;]&lt;br /&gt;
&lt;br /&gt;
== Maintenance ==&lt;br /&gt;
&lt;br /&gt;
Keep the git checkout of NextCloud and its submodules up to date with git, and run the OCC upgrade command:&lt;br /&gt;
&lt;br /&gt;
 cd /var/www/nextcloud&lt;br /&gt;
 git pull&lt;br /&gt;
 git submodule update --init --recursive&lt;br /&gt;
 sudo -u www-data ./occ upgrade&lt;br /&gt;
&lt;br /&gt;
=== Cron job ===&lt;br /&gt;
&lt;br /&gt;
In the administrator settings select cron rather than other methods, and put this in {{code|/etc/cron.d/nextcloud}}&lt;br /&gt;
&lt;br /&gt;
 */5 * * * * www-data /usr/bin/php /var/www/nextcloud/cron.php&lt;/div&gt;</summary>
		<author><name>Johnno</name></author>
	</entry>
	<entry>
		<id>https://wiki.jon.geek.nz/index.php?title=NextCloud&amp;diff=2505</id>
		<title>NextCloud</title>
		<link rel="alternate" type="text/html" href="https://wiki.jon.geek.nz/index.php?title=NextCloud&amp;diff=2505"/>
		<updated>2023-09-18T05:06:35Z</updated>

		<summary type="html">&lt;p&gt;Johnno: /* Maintenance */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Assumes Ubuntu 20.04, stable20 branch, and installing in {{code|/var/www/nextcloud}} for a cloud.&amp;#039;&amp;#039;&amp;#039;example.com&amp;#039;&amp;#039;&amp;#039; URL (c. December 2020).&lt;br /&gt;
&lt;br /&gt;
== Prerequisites ==&lt;br /&gt;
&lt;br /&gt;
Install some stuff first. This NextCloud recipe uses [[PostgreSQL]], Redis, Apache 2.4, FastCGI with PHP FPM, and Dehydrated for [[Letsencrypt]] SSL certificate maangement.&lt;br /&gt;
&lt;br /&gt;
 sudo apt install apache2 libapache2-mod-fcgid \&lt;br /&gt;
    php7.4-{bcmath,bz2,curl,gd,fpm,gmp,intl,json,mbstring,opcache,pgsql,tidy,xmlrpc,xsl,zip}&lt;br /&gt;
    php-{imagick,redis} composer dehydrated postgresql redis-server&lt;br /&gt;
&lt;br /&gt;
;NOTE: NextCloud works fine under nginx, I just can&amp;#039;t be bothered maintaining what goes in {{code|.htaccess}} which NextCloud expects to be writeable to keep itself updated.&lt;br /&gt;
&lt;br /&gt;
== Configuring Apache and PHP ==&lt;br /&gt;
&lt;br /&gt;
: &amp;#039;&amp;#039;See the [[PHP]] page for setting up PHP with Apache, FPM and Event MPM.&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
=== Add a virtual host for NextCloud ===&lt;br /&gt;
&lt;br /&gt;
It should look something like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;apache&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;VirtualHost *:443&amp;gt;&lt;br /&gt;
   ServerName cloud.example.com&lt;br /&gt;
   DocumentRoot /var/www/nextcloud &lt;br /&gt;
 &lt;br /&gt;
   &amp;lt;Directory &amp;quot;/var/www/nexcloud&amp;quot;&amp;gt;&lt;br /&gt;
     Options FollowSymLinks MultiViews&lt;br /&gt;
     AllowOverride All&lt;br /&gt;
     Require all granted&lt;br /&gt;
     Satisfy Any &lt;br /&gt;
     SetEnv HOME /var/www/nextcloud&lt;br /&gt;
     SetEnv HTTP_HOME /var/www/nextcloud&lt;br /&gt;
 &lt;br /&gt;
     &amp;lt;IfModule mod_dav.c&amp;gt;&lt;br /&gt;
       Dav off&lt;br /&gt;
     &amp;lt;/IfModule&amp;gt;&lt;br /&gt;
   &amp;lt;/Directory&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
   SSLEngine On&lt;br /&gt;
   SSLCertificateFile ...&lt;br /&gt;
 &amp;lt;/VirtualHost&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== PHP settings ===&lt;br /&gt;
&lt;br /&gt;
Enable the opcache, increase the memory limit, and increase the maximum POST and file upload size so you can upload large files.&lt;br /&gt;
&lt;br /&gt;
== Create a database ==&lt;br /&gt;
&lt;br /&gt;
Create a database in [[PostgreSQL]]:&lt;br /&gt;
&lt;br /&gt;
 sudo -u postgres createuser -SDRP &amp;#039;&amp;#039;&amp;lt;nextcloud-user&amp;gt;&amp;#039;&amp;#039;&lt;br /&gt;
 sudo -u postgres createdb -E UTF8 -O &amp;#039;&amp;#039;&amp;lt;nextcloud-user&amp;gt;&amp;#039;&amp;#039; &amp;#039;&amp;#039;&amp;lt;nextcloud-dbname&amp;gt;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
== Install NextCloud ==&lt;br /&gt;
&lt;br /&gt;
We can just clone it from git:&lt;br /&gt;
&lt;br /&gt;
 git clone &amp;lt;nowiki&amp;gt;https://&amp;lt;/nowiki&amp;gt;github.com/nextcloud/server.git nextcloud&lt;br /&gt;
 cd nextcloud&lt;br /&gt;
 git checkout stable20  &amp;#039;&amp;#039;# or whatever the latest stable version is&amp;#039;&amp;#039;&lt;br /&gt;
 git submodule update --init --recursive&lt;br /&gt;
 chown www-data:www-data config apps .htaccess&lt;br /&gt;
&lt;br /&gt;
Create a directory for the cache and user data, which should not reside under the web root:&lt;br /&gt;
&lt;br /&gt;
 mkdir -p /var/lib/nextcloud/data /var/cache/nextcloud&lt;br /&gt;
 chown -R www-data:www-data /var/lib/nextcloud /var/cache/nextcloud&lt;br /&gt;
&lt;br /&gt;
== Configure NextCloud ==&lt;br /&gt;
&lt;br /&gt;
Edit the configuration file in {{code|config/config.php}} and check or consider these settings, and add the database and SMTP connection details:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
 $config =&amp;gt; [&lt;br /&gt;
   # ...&lt;br /&gt;
   #&lt;br /&gt;
   &amp;#039;passwordsalt&amp;#039; =&amp;gt; &amp;quot;&amp;lt;very long random string&amp;gt;&amp;quot;,&lt;br /&gt;
   &amp;#039;secret&amp;#039; =&amp;gt; &amp;quot;&amp;lt;a different very long random string&amp;gt;&amp;quot;,&lt;br /&gt;
   &amp;#039;trusted_domains&amp;#039; =&amp;gt; [&lt;br /&gt;
     0 =&amp;gt; &amp;quot;cloud.example.com&amp;quot;,&lt;br /&gt;
   ],&lt;br /&gt;
   &amp;#039;datadirectory&amp;#039; =&amp;gt; &amp;#039;/var/lib/nextcloud/data&amp;#039;,&lt;br /&gt;
   &amp;#039;overwrite.cli.url&amp;#039; =&amp;gt; &amp;#039;&amp;lt;nowiki&amp;gt;https://&amp;lt;/nowiki&amp;gt;cloud.example.com/&amp;#039;,&lt;br /&gt;
   &amp;#039;htaccess.RewriteBase&amp;#039; =&amp;gt; &amp;#039;/&amp;#039;,&lt;br /&gt;
 &lt;br /&gt;
   # Database connection details&lt;br /&gt;
   &amp;#039;dbtype&amp;#039; =&amp;gt; &amp;#039;pgsql&amp;#039;,&lt;br /&gt;
   &amp;#039;dbhost&amp;#039; =&amp;gt; &amp;#039;localhost&amp;#039;,&lt;br /&gt;
   &amp;#039;dbuser&amp;#039; =&amp;gt; &amp;quot;&amp;lt;nextcloud-dbuser&amp;gt;&amp;quot;,&lt;br /&gt;
   &amp;#039;dbpassword&amp;#039; =&amp;gt; &amp;quot;&amp;lt;password&amp;gt;&amp;quot;,&lt;br /&gt;
   &amp;#039;dbname&amp;#039; =&amp;gt; &amp;quot;&amp;lt;nextcloud-dbname&amp;gt;&amp;quot;,&lt;br /&gt;
   &amp;#039;dbtableprefix&amp;#039; =&amp;gt; &amp;#039;oc_&amp;#039;,&lt;br /&gt;
 &lt;br /&gt;
   # Force all URLs to use SSL or it may trip up things like OAuth&lt;br /&gt;
   &amp;#039;overwriteprotocol&amp;#039; =&amp;gt; &amp;#039;https&amp;#039;,&lt;br /&gt;
 &lt;br /&gt;
   # Use Redis and caching to make everything go faster&lt;br /&gt;
   &amp;#039;memcache.local&amp;#039; =&amp;gt; &amp;#039;\\OC\\Memcache\\Redis&amp;#039;,&lt;br /&gt;
   &amp;#039;memcache.locking&amp;#039; =&amp;gt; &amp;#039;\\OC\\Memcache\\Redis&amp;#039;,&lt;br /&gt;
   &amp;#039;redis&amp;#039; =&amp;gt; [&lt;br /&gt;
     &amp;#039;host&amp;#039; =&amp;gt; &amp;#039;localhost&amp;#039;,&lt;br /&gt;
     &amp;#039;port&amp;#039; =&amp;gt; 6379,&lt;br /&gt;
   ],&lt;br /&gt;
   &amp;#039;cache_path&amp;#039; =&amp;gt; &amp;#039;/var/cache/nextcloud&amp;#039;,&lt;br /&gt;
 &lt;br /&gt;
   # Send email details&lt;br /&gt;
   &amp;#039;mail_smtpmode&amp;#039; =&amp;gt; &amp;#039;smtp&amp;#039;,&lt;br /&gt;
   &amp;#039;mail_smtpsecure&amp;#039; =&amp;gt; &amp;#039;tls&amp;#039;,&lt;br /&gt;
   &amp;#039;mail_sendmailmode&amp;#039; =&amp;gt; &amp;#039;smtp&amp;#039;,&lt;br /&gt;
   &amp;#039;mail_from_address&amp;#039; =&amp;gt; &amp;quot;nexcloud@example.com&amp;quot;,&lt;br /&gt;
   &amp;#039;mail_domain&amp;#039; =&amp;gt; &amp;quot;example.com&amp;quot;,&lt;br /&gt;
   &amp;#039;mail_smtpauthtype&amp;#039; =&amp;gt; &amp;#039;PLAIN&amp;#039;,&lt;br /&gt;
   &amp;#039;mail_smtpauth&amp;#039; =&amp;gt; 1,&lt;br /&gt;
   &amp;#039;mail_smtphost&amp;#039; =&amp;gt; &amp;quot;mail.example.com&amp;quot;,&lt;br /&gt;
   &amp;#039;mail_smtpport&amp;#039; =&amp;gt; 587,&lt;br /&gt;
   &amp;#039;mail_smtpname&amp;#039; =&amp;gt; &amp;quot;&amp;lt;emailuser&amp;gt;&amp;quot;,&lt;br /&gt;
   &amp;#039;mail_smtppassword&amp;#039; =&amp;gt; &amp;quot;&amp;lt;emailpassword&amp;gt;&amp;quot;,&lt;br /&gt;
 &lt;br /&gt;
   # ...&lt;br /&gt;
 ]  &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then navigate to the URL in the browser to install (or run the NextCloud {{code | ./occ}} tool from the command line).&lt;br /&gt;
&lt;br /&gt;
=== Clean URLs ===&lt;br /&gt;
&lt;br /&gt;
For clean URLs, make sure {{code | AllowOverride All}} is set for the parent directory; the {{code | /var/www}} definition is in the main {{code | /etc/apache2/apache.conf}}. Then run the follwing OCC command to enable the rewrite rules:&lt;br /&gt;
&lt;br /&gt;
 sudo -u www-data ./occ maintenance:update:htaccess&lt;br /&gt;
&lt;br /&gt;
=== Previews of other file types ===&lt;br /&gt;
&lt;br /&gt;
Edit {{code|/etc/ImageMagick/policy.xml}} and remove this line to get PDF previews to work:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;policy domain=&amp;quot;coder&amp;quot; rights=&amp;quot;none&amp;quot; pattern=&amp;quot;PDF&amp;quot; /&amp;gt; &amp;lt;!-- remove this line --&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then add the following to {{code|config.php}} to get lots of other useful file previews:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
   &amp;#039;enabledPreviewProviders&amp;#039; =&amp;gt; [&lt;br /&gt;
     # ...&lt;br /&gt;
     8 =&amp;gt; &amp;#039;OC\\Preview\\MarkDown&amp;#039;,&lt;br /&gt;
     9 =&amp;gt; &amp;#039;OC\\Preview\\Movie&amp;#039;,&lt;br /&gt;
     10 =&amp;gt; &amp;#039;OC\\Preview\\PDF&amp;#039;,&lt;br /&gt;
     11 =&amp;gt; &amp;#039;OC\\Preview\\OpenDocument&amp;#039;,&lt;br /&gt;
     12 =&amp;gt; &amp;#039;OC\\Preview\\MSOfficeDoc&amp;#039;,&lt;br /&gt;
     13 =&amp;gt; &amp;#039;OC\\Preview\\MSOffice2003&amp;#039;,&lt;br /&gt;
     14 =&amp;gt; &amp;#039;OC\\Preview\\MSOffice2007&amp;#039;,&lt;br /&gt;
   ],&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Photos ===&lt;br /&gt;
&lt;br /&gt;
Photos replaces the Gallery app, and is installed separately through the NC store or you can use git to manage it as a submodule. If it doesn&amp;#039;t work you might need to build its JavaScript resources by running {{code|make}} in its {{code|apps/photos}} directory. Alternatively you can resuscitate the Gallery app, which stopped working after NextCloud version 17, by updating its JavaScript dompurify library to a [https://raw.githubusercontent.com/nextcloud/gallery/ecb26a812f30a3f516964808ccfa6430be09b45e/js/vendor/dompurify/src/purify.js newer version] and bumping the app max version in {{code|apps/galleryappinfo/info.xml}} as follows (See also [https://github.com/nextcloud/gallery/pull/570/ pull request #570]):&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nextcloud min-version=&amp;quot;17&amp;quot; max-version=&amp;quot;&amp;#039;&amp;#039;&amp;#039;20&amp;#039;&amp;#039;&amp;#039;&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== NextCloud Talk ===&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;Note:&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039; &amp;#039;&amp;#039;A TURN server can also be used for other things, like your own [https://matrix-org.github.io/synapse/v1.41/turn-howto.html Matrix] chat server.&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
To be at all useful, you need a TURN server. This is easiest achieved by installing and correctly configuring coturn, which also acts as a STUN server. STUN is for clients to figure out their external IP address, and TURN is for relaying UDP packets, e.g. for WebRTC.&lt;br /&gt;
&lt;br /&gt;
 sudo apt install coturn&lt;br /&gt;
&lt;br /&gt;
For it to actually do anything (it is disabled by default!) you need to edit {{code|/etc/default/coturn}} and make sure it contains the following, and is not commented out:&lt;br /&gt;
&lt;br /&gt;
 TURNSERVER_ENABLED=1&lt;br /&gt;
&lt;br /&gt;
Then in {{code|/etc/turnserver.conf}} you need to configure its domain name, IP addresses and ports, SSL certificate, and how TURN authenticates. See GitHub for a fully documented example [https://github.com/coturn/coturn/blob/master/examples/etc/turnserver.conf turnserver.conf] file. This example uses the same domain as the NextCloud instance, on the standard STUN and TURN ports, but if you want to host it on port 443 to support people behind restrictive firewalls, you will need a different subdomain and/or IP address:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;ini&amp;quot;&amp;gt;&lt;br /&gt;
 server-name=cloud.example.com&lt;br /&gt;
 realm=cloud.example.com&lt;br /&gt;
 &lt;br /&gt;
 # When hosted on an internal LAN or DMZ, it might look like this: &lt;br /&gt;
 listening-ip=192.168.1.100&lt;br /&gt;
 relay-ip=192.168.1.100&lt;br /&gt;
 external-ip=123.45.67.8&lt;br /&gt;
 &lt;br /&gt;
 # Or use the short-hand:&lt;br /&gt;
 external-ip=123.45.67.8/192.168.1.100&lt;br /&gt;
 &lt;br /&gt;
 # Specify listening ports; originally 3478 was unencrypted, and 5349 was TLS,&lt;br /&gt;
 # but now TLS is supported on both. It is possible to listen on 443, which will&lt;br /&gt;
 # help to provide connectivity for people behind port-limited firewalls; this will&lt;br /&gt;
 # conflict with any HTTPS web hosting on the same server though, unless you set&lt;br /&gt;
 # up a second IP address for it.&lt;br /&gt;
 listening-port=3478&lt;br /&gt;
 tls-listening-port=5349&lt;br /&gt;
 #tls-listening-port=443&lt;br /&gt;
 &lt;br /&gt;
 # Specify a UDP port range and ensure they are exposed through the firewall/router&lt;br /&gt;
 min-port=53490&lt;br /&gt;
 max-port=59999&lt;br /&gt;
 &lt;br /&gt;
 # SSL setup; &lt;br /&gt;
 cert=/path/to/cloud.example.com/fullchain.cert&lt;br /&gt;
 pkey=/path/to/cloud.example.com/privkey.pem&lt;br /&gt;
 no-tlsv1&lt;br /&gt;
 no-tlsv1_1&lt;br /&gt;
 &lt;br /&gt;
 # To use with NextCloud, set a shared secret here.&lt;br /&gt;
 use-auth-secret&lt;br /&gt;
 static-auth-secret=your-shared-secret-string-here&lt;br /&gt;
 stale-nonce=600&lt;br /&gt;
 &lt;br /&gt;
 # Limit STUN amplification/gain attacks (coturn 4.5.2+)&lt;br /&gt;
 no-stun-backward-compatibility&lt;br /&gt;
 response-origin-only-with-rfc5780&lt;br /&gt;
 &lt;br /&gt;
 # RFC-5780 support requires two listening IP addresses and is for serious-cat&lt;br /&gt;
 # usage, so you can safely disable it for a small home NextCloud instance.&lt;br /&gt;
 no-rfc5780&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In your NextCloud Administration section, you can now configure Talk to use the STUN/TURN server, using your server URLs, and provide the same shared secret you configured above. For maximum compatibility, use both UDP and TCP, and both turn and turns (TLS) connections:&lt;br /&gt;
&lt;br /&gt;
 stun: &amp;#039;&amp;#039;&amp;#039;cloud.example.com&amp;#039;&amp;#039;&amp;#039;:5349&lt;br /&gt;
 turn and turns: &amp;#039;&amp;#039;&amp;#039;cloud.example.com&amp;#039;&amp;#039;&amp;#039;:5349&lt;br /&gt;
&lt;br /&gt;
Test your server [https://webrtc.github.io/samples/src/content/peerconnection/trickle-ice/ here]. If STUN is working, you should get {{code|srflx}} candidates, and {{code|relay}} candidates if TURN is working.&lt;br /&gt;
&lt;br /&gt;
Sources and further reading:&lt;br /&gt;
* NextCloud Talk documentation: [https://nextcloud-talk.readthedocs.io/en/latest/TURN/ TURN], [https://nextcloud-talk.readthedocs.io/en/latest/coturn coturn]&lt;br /&gt;
* NextCloud Help, [https://help.nextcloud.com/t/howto-setup-nextcloud-talk-with-turn-server/30794 1] [https://help.nextcloud.com/t/nextcloud-talk-app-could-not-establish-a-connection-a-turn-server/131069/31 2]&lt;br /&gt;
* Stack Overflow [https://stackoverflow.com/questions/42801361/install-rfc5766-turn-server-trying-to-bind-fd-to-ip-address-errno-99 1]&lt;br /&gt;
* [https://ourcodeworld.com/articles/read/1526/how-to-test-online-whether-a-stun-turn-server-is-working-properly-or-not Testing STUN/TURN]&lt;br /&gt;
&lt;br /&gt;
== Office ==&lt;br /&gt;
&lt;br /&gt;
Install Collabora Office Online (COOL) which emerged from the smoking ruins of LibreOffice Online (LOOL):&lt;br /&gt;
&lt;br /&gt;
 apt install coolwsd code-brand&lt;br /&gt;
&lt;br /&gt;
Use an Apache reverse proxy to handle the host and SSL, disable SSL in WOPI setup; restrict NextCloud and coolwsd requests to their respective endpoints, IP addresses; see [https://c-nergy.be/blog/?p=18055 &amp;quot;Install CODE on NextCloud on Ubuntu 22.04&amp;quot;]&lt;br /&gt;
&lt;br /&gt;
== Maintenance ==&lt;br /&gt;
&lt;br /&gt;
Keep the git checkout of NextCloud and its submodules up to date with git, and run the OCC upgrade command:&lt;br /&gt;
&lt;br /&gt;
 cd /var/www/nextcloud&lt;br /&gt;
 git pull&lt;br /&gt;
 git submodule update --init --recursive&lt;br /&gt;
 sudo -u www-data ./occ upgrade&lt;br /&gt;
&lt;br /&gt;
=== Cron job ===&lt;br /&gt;
&lt;br /&gt;
In the administrator settings select cron rather than other methods, and put this in {{code|/etc/cron.d/nextcloud}}&lt;br /&gt;
&lt;br /&gt;
 */5 * * * * www-data /usr/bin/php /var/www/nextcloud/cron.php&lt;/div&gt;</summary>
		<author><name>Johnno</name></author>
	</entry>
	<entry>
		<id>https://wiki.jon.geek.nz/index.php?title=NextCloud&amp;diff=2504</id>
		<title>NextCloud</title>
		<link rel="alternate" type="text/html" href="https://wiki.jon.geek.nz/index.php?title=NextCloud&amp;diff=2504"/>
		<updated>2023-09-07T22:07:56Z</updated>

		<summary type="html">&lt;p&gt;Johnno: /* NextCloud Talk */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Assumes Ubuntu 20.04, stable20 branch, and installing in {{code|/var/www/nextcloud}} for a cloud.&amp;#039;&amp;#039;&amp;#039;example.com&amp;#039;&amp;#039;&amp;#039; URL (c. December 2020).&lt;br /&gt;
&lt;br /&gt;
== Prerequisites ==&lt;br /&gt;
&lt;br /&gt;
Install some stuff first. This NextCloud recipe uses [[PostgreSQL]], Redis, Apache 2.4, FastCGI with PHP FPM, and Dehydrated for [[Letsencrypt]] SSL certificate maangement.&lt;br /&gt;
&lt;br /&gt;
 sudo apt install apache2 libapache2-mod-fcgid \&lt;br /&gt;
    php7.4-{bcmath,bz2,curl,gd,fpm,gmp,intl,json,mbstring,opcache,pgsql,tidy,xmlrpc,xsl,zip}&lt;br /&gt;
    php-{imagick,redis} composer dehydrated postgresql redis-server&lt;br /&gt;
&lt;br /&gt;
;NOTE: NextCloud works fine under nginx, I just can&amp;#039;t be bothered maintaining what goes in {{code|.htaccess}} which NextCloud expects to be writeable to keep itself updated.&lt;br /&gt;
&lt;br /&gt;
== Configuring Apache and PHP ==&lt;br /&gt;
&lt;br /&gt;
: &amp;#039;&amp;#039;See the [[PHP]] page for setting up PHP with Apache, FPM and Event MPM.&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
=== Add a virtual host for NextCloud ===&lt;br /&gt;
&lt;br /&gt;
It should look something like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;apache&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;VirtualHost *:443&amp;gt;&lt;br /&gt;
   ServerName cloud.example.com&lt;br /&gt;
   DocumentRoot /var/www/nextcloud &lt;br /&gt;
 &lt;br /&gt;
   &amp;lt;Directory &amp;quot;/var/www/nexcloud&amp;quot;&amp;gt;&lt;br /&gt;
     Options FollowSymLinks MultiViews&lt;br /&gt;
     AllowOverride All&lt;br /&gt;
     Require all granted&lt;br /&gt;
     Satisfy Any &lt;br /&gt;
     SetEnv HOME /var/www/nextcloud&lt;br /&gt;
     SetEnv HTTP_HOME /var/www/nextcloud&lt;br /&gt;
 &lt;br /&gt;
     &amp;lt;IfModule mod_dav.c&amp;gt;&lt;br /&gt;
       Dav off&lt;br /&gt;
     &amp;lt;/IfModule&amp;gt;&lt;br /&gt;
   &amp;lt;/Directory&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
   SSLEngine On&lt;br /&gt;
   SSLCertificateFile ...&lt;br /&gt;
 &amp;lt;/VirtualHost&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== PHP settings ===&lt;br /&gt;
&lt;br /&gt;
Enable the opcache, increase the memory limit, and increase the maximum POST and file upload size so you can upload large files.&lt;br /&gt;
&lt;br /&gt;
== Create a database ==&lt;br /&gt;
&lt;br /&gt;
Create a database in [[PostgreSQL]]:&lt;br /&gt;
&lt;br /&gt;
 sudo -u postgres createuser -SDRP &amp;#039;&amp;#039;&amp;lt;nextcloud-user&amp;gt;&amp;#039;&amp;#039;&lt;br /&gt;
 sudo -u postgres createdb -E UTF8 -O &amp;#039;&amp;#039;&amp;lt;nextcloud-user&amp;gt;&amp;#039;&amp;#039; &amp;#039;&amp;#039;&amp;lt;nextcloud-dbname&amp;gt;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
== Install NextCloud ==&lt;br /&gt;
&lt;br /&gt;
We can just clone it from git:&lt;br /&gt;
&lt;br /&gt;
 git clone &amp;lt;nowiki&amp;gt;https://&amp;lt;/nowiki&amp;gt;github.com/nextcloud/server.git nextcloud&lt;br /&gt;
 cd nextcloud&lt;br /&gt;
 git checkout stable20  &amp;#039;&amp;#039;# or whatever the latest stable version is&amp;#039;&amp;#039;&lt;br /&gt;
 git submodule update --init --recursive&lt;br /&gt;
 chown www-data:www-data config apps .htaccess&lt;br /&gt;
&lt;br /&gt;
Create a directory for the cache and user data, which should not reside under the web root:&lt;br /&gt;
&lt;br /&gt;
 mkdir -p /var/lib/nextcloud/data /var/cache/nextcloud&lt;br /&gt;
 chown -R www-data:www-data /var/lib/nextcloud /var/cache/nextcloud&lt;br /&gt;
&lt;br /&gt;
== Configure NextCloud ==&lt;br /&gt;
&lt;br /&gt;
Edit the configuration file in {{code|config/config.php}} and check or consider these settings, and add the database and SMTP connection details:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
 $config =&amp;gt; [&lt;br /&gt;
   # ...&lt;br /&gt;
   #&lt;br /&gt;
   &amp;#039;passwordsalt&amp;#039; =&amp;gt; &amp;quot;&amp;lt;very long random string&amp;gt;&amp;quot;,&lt;br /&gt;
   &amp;#039;secret&amp;#039; =&amp;gt; &amp;quot;&amp;lt;a different very long random string&amp;gt;&amp;quot;,&lt;br /&gt;
   &amp;#039;trusted_domains&amp;#039; =&amp;gt; [&lt;br /&gt;
     0 =&amp;gt; &amp;quot;cloud.example.com&amp;quot;,&lt;br /&gt;
   ],&lt;br /&gt;
   &amp;#039;datadirectory&amp;#039; =&amp;gt; &amp;#039;/var/lib/nextcloud/data&amp;#039;,&lt;br /&gt;
   &amp;#039;overwrite.cli.url&amp;#039; =&amp;gt; &amp;#039;&amp;lt;nowiki&amp;gt;https://&amp;lt;/nowiki&amp;gt;cloud.example.com/&amp;#039;,&lt;br /&gt;
   &amp;#039;htaccess.RewriteBase&amp;#039; =&amp;gt; &amp;#039;/&amp;#039;,&lt;br /&gt;
 &lt;br /&gt;
   # Database connection details&lt;br /&gt;
   &amp;#039;dbtype&amp;#039; =&amp;gt; &amp;#039;pgsql&amp;#039;,&lt;br /&gt;
   &amp;#039;dbhost&amp;#039; =&amp;gt; &amp;#039;localhost&amp;#039;,&lt;br /&gt;
   &amp;#039;dbuser&amp;#039; =&amp;gt; &amp;quot;&amp;lt;nextcloud-dbuser&amp;gt;&amp;quot;,&lt;br /&gt;
   &amp;#039;dbpassword&amp;#039; =&amp;gt; &amp;quot;&amp;lt;password&amp;gt;&amp;quot;,&lt;br /&gt;
   &amp;#039;dbname&amp;#039; =&amp;gt; &amp;quot;&amp;lt;nextcloud-dbname&amp;gt;&amp;quot;,&lt;br /&gt;
   &amp;#039;dbtableprefix&amp;#039; =&amp;gt; &amp;#039;oc_&amp;#039;,&lt;br /&gt;
 &lt;br /&gt;
   # Force all URLs to use SSL or it may trip up things like OAuth&lt;br /&gt;
   &amp;#039;overwriteprotocol&amp;#039; =&amp;gt; &amp;#039;https&amp;#039;,&lt;br /&gt;
 &lt;br /&gt;
   # Use Redis and caching to make everything go faster&lt;br /&gt;
   &amp;#039;memcache.local&amp;#039; =&amp;gt; &amp;#039;\\OC\\Memcache\\Redis&amp;#039;,&lt;br /&gt;
   &amp;#039;memcache.locking&amp;#039; =&amp;gt; &amp;#039;\\OC\\Memcache\\Redis&amp;#039;,&lt;br /&gt;
   &amp;#039;redis&amp;#039; =&amp;gt; [&lt;br /&gt;
     &amp;#039;host&amp;#039; =&amp;gt; &amp;#039;localhost&amp;#039;,&lt;br /&gt;
     &amp;#039;port&amp;#039; =&amp;gt; 6379,&lt;br /&gt;
   ],&lt;br /&gt;
   &amp;#039;cache_path&amp;#039; =&amp;gt; &amp;#039;/var/cache/nextcloud&amp;#039;,&lt;br /&gt;
 &lt;br /&gt;
   # Send email details&lt;br /&gt;
   &amp;#039;mail_smtpmode&amp;#039; =&amp;gt; &amp;#039;smtp&amp;#039;,&lt;br /&gt;
   &amp;#039;mail_smtpsecure&amp;#039; =&amp;gt; &amp;#039;tls&amp;#039;,&lt;br /&gt;
   &amp;#039;mail_sendmailmode&amp;#039; =&amp;gt; &amp;#039;smtp&amp;#039;,&lt;br /&gt;
   &amp;#039;mail_from_address&amp;#039; =&amp;gt; &amp;quot;nexcloud@example.com&amp;quot;,&lt;br /&gt;
   &amp;#039;mail_domain&amp;#039; =&amp;gt; &amp;quot;example.com&amp;quot;,&lt;br /&gt;
   &amp;#039;mail_smtpauthtype&amp;#039; =&amp;gt; &amp;#039;PLAIN&amp;#039;,&lt;br /&gt;
   &amp;#039;mail_smtpauth&amp;#039; =&amp;gt; 1,&lt;br /&gt;
   &amp;#039;mail_smtphost&amp;#039; =&amp;gt; &amp;quot;mail.example.com&amp;quot;,&lt;br /&gt;
   &amp;#039;mail_smtpport&amp;#039; =&amp;gt; 587,&lt;br /&gt;
   &amp;#039;mail_smtpname&amp;#039; =&amp;gt; &amp;quot;&amp;lt;emailuser&amp;gt;&amp;quot;,&lt;br /&gt;
   &amp;#039;mail_smtppassword&amp;#039; =&amp;gt; &amp;quot;&amp;lt;emailpassword&amp;gt;&amp;quot;,&lt;br /&gt;
 &lt;br /&gt;
   # ...&lt;br /&gt;
 ]  &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then navigate to the URL in the browser to install (or run the NextCloud {{code | ./occ}} tool from the command line).&lt;br /&gt;
&lt;br /&gt;
=== Clean URLs ===&lt;br /&gt;
&lt;br /&gt;
For clean URLs, make sure {{code | AllowOverride All}} is set for the parent directory; the {{code | /var/www}} definition is in the main {{code | /etc/apache2/apache.conf}}. Then run the follwing OCC command to enable the rewrite rules:&lt;br /&gt;
&lt;br /&gt;
 sudo -u www-data ./occ maintenance:update:htaccess&lt;br /&gt;
&lt;br /&gt;
=== Previews of other file types ===&lt;br /&gt;
&lt;br /&gt;
Edit {{code|/etc/ImageMagick/policy.xml}} and remove this line to get PDF previews to work:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;policy domain=&amp;quot;coder&amp;quot; rights=&amp;quot;none&amp;quot; pattern=&amp;quot;PDF&amp;quot; /&amp;gt; &amp;lt;!-- remove this line --&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then add the following to {{code|config.php}} to get lots of other useful file previews:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
   &amp;#039;enabledPreviewProviders&amp;#039; =&amp;gt; [&lt;br /&gt;
     # ...&lt;br /&gt;
     8 =&amp;gt; &amp;#039;OC\\Preview\\MarkDown&amp;#039;,&lt;br /&gt;
     9 =&amp;gt; &amp;#039;OC\\Preview\\Movie&amp;#039;,&lt;br /&gt;
     10 =&amp;gt; &amp;#039;OC\\Preview\\PDF&amp;#039;,&lt;br /&gt;
     11 =&amp;gt; &amp;#039;OC\\Preview\\OpenDocument&amp;#039;,&lt;br /&gt;
     12 =&amp;gt; &amp;#039;OC\\Preview\\MSOfficeDoc&amp;#039;,&lt;br /&gt;
     13 =&amp;gt; &amp;#039;OC\\Preview\\MSOffice2003&amp;#039;,&lt;br /&gt;
     14 =&amp;gt; &amp;#039;OC\\Preview\\MSOffice2007&amp;#039;,&lt;br /&gt;
   ],&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Photos ===&lt;br /&gt;
&lt;br /&gt;
Photos replaces the Gallery app, and is installed separately through the NC store or you can use git to manage it as a submodule. If it doesn&amp;#039;t work you might need to build its JavaScript resources by running {{code|make}} in its {{code|apps/photos}} directory. Alternatively you can resuscitate the Gallery app, which stopped working after NextCloud version 17, by updating its JavaScript dompurify library to a [https://raw.githubusercontent.com/nextcloud/gallery/ecb26a812f30a3f516964808ccfa6430be09b45e/js/vendor/dompurify/src/purify.js newer version] and bumping the app max version in {{code|apps/galleryappinfo/info.xml}} as follows (See also [https://github.com/nextcloud/gallery/pull/570/ pull request #570]):&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nextcloud min-version=&amp;quot;17&amp;quot; max-version=&amp;quot;&amp;#039;&amp;#039;&amp;#039;20&amp;#039;&amp;#039;&amp;#039;&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== NextCloud Talk ===&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;Note:&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039; &amp;#039;&amp;#039;A TURN server can also be used for other things, like your own [https://matrix-org.github.io/synapse/v1.41/turn-howto.html Matrix] chat server.&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
To be at all useful, you need a TURN server. This is easiest achieved by installing and correctly configuring coturn, which also acts as a STUN server. STUN is for clients to figure out their external IP address, and TURN is for relaying UDP packets, e.g. for WebRTC.&lt;br /&gt;
&lt;br /&gt;
 sudo apt install coturn&lt;br /&gt;
&lt;br /&gt;
For it to actually do anything (it is disabled by default!) you need to edit {{code|/etc/default/coturn}} and make sure it contains the following, and is not commented out:&lt;br /&gt;
&lt;br /&gt;
 TURNSERVER_ENABLED=1&lt;br /&gt;
&lt;br /&gt;
Then in {{code|/etc/turnserver.conf}} you need to configure its domain name, IP addresses and ports, SSL certificate, and how TURN authenticates. See GitHub for a fully documented example [https://github.com/coturn/coturn/blob/master/examples/etc/turnserver.conf turnserver.conf] file. This example uses the same domain as the NextCloud instance, on the standard STUN and TURN ports, but if you want to host it on port 443 to support people behind restrictive firewalls, you will need a different subdomain and/or IP address:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;ini&amp;quot;&amp;gt;&lt;br /&gt;
 server-name=cloud.example.com&lt;br /&gt;
 realm=cloud.example.com&lt;br /&gt;
 &lt;br /&gt;
 # When hosted on an internal LAN or DMZ, it might look like this: &lt;br /&gt;
 listening-ip=192.168.1.100&lt;br /&gt;
 relay-ip=192.168.1.100&lt;br /&gt;
 external-ip=123.45.67.8&lt;br /&gt;
 &lt;br /&gt;
 # Or use the short-hand:&lt;br /&gt;
 external-ip=123.45.67.8/192.168.1.100&lt;br /&gt;
 &lt;br /&gt;
 # Specify listening ports; originally 3478 was unencrypted, and 5349 was TLS,&lt;br /&gt;
 # but now TLS is supported on both. It is possible to listen on 443, which will&lt;br /&gt;
 # help to provide connectivity for people behind port-limited firewalls; this will&lt;br /&gt;
 # conflict with any HTTPS web hosting on the same server though, unless you set&lt;br /&gt;
 # up a second IP address for it.&lt;br /&gt;
 listening-port=3478&lt;br /&gt;
 tls-listening-port=5349&lt;br /&gt;
 #tls-listening-port=443&lt;br /&gt;
 &lt;br /&gt;
 # Specify a UDP port range and ensure they are exposed through the firewall/router&lt;br /&gt;
 min-port=53490&lt;br /&gt;
 max-port=59999&lt;br /&gt;
 &lt;br /&gt;
 # SSL setup; &lt;br /&gt;
 cert=/path/to/cloud.example.com/fullchain.cert&lt;br /&gt;
 pkey=/path/to/cloud.example.com/privkey.pem&lt;br /&gt;
 no-tlsv1&lt;br /&gt;
 no-tlsv1_1&lt;br /&gt;
 &lt;br /&gt;
 # To use with NextCloud, set a shared secret here.&lt;br /&gt;
 use-auth-secret&lt;br /&gt;
 static-auth-secret=your-shared-secret-string-here&lt;br /&gt;
 stale-nonce=600&lt;br /&gt;
 &lt;br /&gt;
 # Limit STUN amplification/gain attacks (coturn 4.5.2+)&lt;br /&gt;
 no-stun-backward-compatibility&lt;br /&gt;
 response-origin-only-with-rfc5780&lt;br /&gt;
 &lt;br /&gt;
 # RFC-5780 support requires two listening IP addresses and is for serious-cat&lt;br /&gt;
 # usage, so you can safely disable it for a small home NextCloud instance.&lt;br /&gt;
 no-rfc5780&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In your NextCloud Administration section, you can now configure Talk to use the STUN/TURN server, using your server URLs, and provide the same shared secret you configured above. For maximum compatibility, use both UDP and TCP, and both turn and turns (TLS) connections:&lt;br /&gt;
&lt;br /&gt;
 stun: &amp;#039;&amp;#039;&amp;#039;cloud.example.com&amp;#039;&amp;#039;&amp;#039;:5349&lt;br /&gt;
 turn and turns: &amp;#039;&amp;#039;&amp;#039;cloud.example.com&amp;#039;&amp;#039;&amp;#039;:5349&lt;br /&gt;
&lt;br /&gt;
Test your server [https://webrtc.github.io/samples/src/content/peerconnection/trickle-ice/ here]. If STUN is working, you should get {{code|srflx}} candidates, and {{code|relay}} candidates if TURN is working.&lt;br /&gt;
&lt;br /&gt;
Sources and further reading:&lt;br /&gt;
* NextCloud Talk documentation: [https://nextcloud-talk.readthedocs.io/en/latest/TURN/ TURN], [https://nextcloud-talk.readthedocs.io/en/latest/coturn coturn]&lt;br /&gt;
* NextCloud Help, [https://help.nextcloud.com/t/howto-setup-nextcloud-talk-with-turn-server/30794 1] [https://help.nextcloud.com/t/nextcloud-talk-app-could-not-establish-a-connection-a-turn-server/131069/31 2]&lt;br /&gt;
* Stack Overflow [https://stackoverflow.com/questions/42801361/install-rfc5766-turn-server-trying-to-bind-fd-to-ip-address-errno-99 1]&lt;br /&gt;
* [https://ourcodeworld.com/articles/read/1526/how-to-test-online-whether-a-stun-turn-server-is-working-properly-or-not Testing STUN/TURN]&lt;br /&gt;
&lt;br /&gt;
== Maintenance ==&lt;br /&gt;
&lt;br /&gt;
Keep the git checkout of NextCloud and its submodules up to date with git, and run the OCC upgrade command:&lt;br /&gt;
&lt;br /&gt;
 cd /var/www/nextcloud&lt;br /&gt;
 git pull&lt;br /&gt;
 git submodule update --init --recursive&lt;br /&gt;
 sudo -u www-data ./occ upgrade&lt;br /&gt;
&lt;br /&gt;
=== Cron job ===&lt;br /&gt;
&lt;br /&gt;
In the administrator settings select cron rather than other methods, and put this in {{code|/etc/cron.d/nextcloud}}&lt;br /&gt;
&lt;br /&gt;
 */5 * * * * www-data /usr/bin/php /var/www/nextcloud/cron.php&lt;/div&gt;</summary>
		<author><name>Johnno</name></author>
	</entry>
	<entry>
		<id>https://wiki.jon.geek.nz/index.php?title=PostgreSQL&amp;diff=2503</id>
		<title>PostgreSQL</title>
		<link rel="alternate" type="text/html" href="https://wiki.jon.geek.nz/index.php?title=PostgreSQL&amp;diff=2503"/>
		<updated>2023-09-07T20:11:51Z</updated>

		<summary type="html">&lt;p&gt;Johnno: /* Documentation */ use current docs&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Documentation ==&lt;br /&gt;
&lt;br /&gt;
The online [http://www.postgresql.org/docs/current/ PostgreSQL Manual] is actually quite awesome and worth bookmarking.&lt;br /&gt;
&lt;br /&gt;
== Install and Configure ==&lt;br /&gt;
&lt;br /&gt;
Assuming Debian or Ubuntu, installation is:&lt;br /&gt;
 sudo apt-get install postgresql postgresql-client&lt;br /&gt;
&lt;br /&gt;
=== Check The Configuration ===&lt;br /&gt;
&lt;br /&gt;
You may end up with (and may require) several different versions of PostgreSQL on one box. If this is so, check that they are running on separate ports. The port is specified in &amp;lt;tt&amp;gt;/etc/postgresql/9.1/main/postgresql.conf&amp;lt;/tt&amp;gt;. For a development (&amp;#039;&amp;#039;&amp;#039;NOT&amp;#039;&amp;#039;&amp;#039; production!) environment, we can make life simple by making a change to &amp;lt;tt&amp;gt;/etc/postgresql/9.1/main/pg_hba.conf&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 local  all     all                            trust &lt;br /&gt;
 host   all     all         127.0.0.1/32       trust&lt;br /&gt;
&lt;br /&gt;
That is, changing the authentication from &amp;#039;&amp;#039;md5&amp;#039;&amp;#039; to &amp;#039;&amp;#039;trust&amp;#039;&amp;#039; for local socket-based connections and TCP connections from localhost. On production servers, &amp;lt;tt&amp;gt;pg_hba.conf&amp;lt;/tt&amp;gt; provides the means for a powerful and atomic user- and host-based authentication system to really lock the whole thing down nicely.&lt;br /&gt;
&lt;br /&gt;
;NOTE: If you have changed the port or anything else in &amp;lt;tt&amp;gt;postgresql.conf&amp;lt;/tt&amp;gt;, you will need to stop then start the service, as reload and restart are &amp;#039;&amp;#039;&amp;#039;not&amp;#039;&amp;#039;&amp;#039; sufficient! This is a nasty trap for young players.&lt;br /&gt;
&lt;br /&gt;
== Creating Users and Databases ==&lt;br /&gt;
&lt;br /&gt;
PostgreSQL system administration is somewhat different in approach to MySQL, but actually much less retarded once you get the hang of it.&lt;br /&gt;
&lt;br /&gt;
With PostgreSQL creating users and databases is done with shell level commands &amp;lt;tt&amp;gt;createuser&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;createdb&amp;lt;/tt&amp;gt;, rather than lame non-standard SQL commands (although you can also use SQL-ish statements like MySQL if you insist, but they are not covered here).&lt;br /&gt;
&lt;br /&gt;
=== Make Yourself A Superuser ===&lt;br /&gt;
&lt;br /&gt;
Out of the box, the PostgreSQL server runs as the postgres user, so to create yourself an administrator account, you need to run the createuser script as the postgres user:&lt;br /&gt;
&lt;br /&gt;
 sudo -u postgres createuser &amp;lt;yourusername&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Use your shell account name and answer &amp;#039;&amp;#039;Y&amp;#039;&amp;#039; to all questions to give yourself a superuser account. Unless told otherwise, PostgreSQL will try to use the shell account to save time. If you don&amp;#039;t want question prompts, you can go&lt;br /&gt;
&lt;br /&gt;
 sudo -u postgres createuser -srdP &amp;lt;username&amp;gt;&lt;br /&gt;
&lt;br /&gt;
;NOTE: Reload the PostgreSQL server to pick up the new privileges.&lt;br /&gt;
&lt;br /&gt;
==== Switches for createuser ====&lt;br /&gt;
&lt;br /&gt;
{| border=1&lt;br /&gt;
|-&lt;br /&gt;
|  &amp;#039;&amp;#039;&amp;#039;Switch&amp;#039;&amp;#039;&amp;#039;  ||  &amp;#039;&amp;#039;&amp;#039;Behaviour&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;-s&amp;#039;&amp;#039;  ||  User will be a superuser&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;-S&amp;#039;&amp;#039;  ||  User will not be a superuser&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;-r&amp;#039;&amp;#039;  ||  User can create other roles (users)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;-R&amp;#039;&amp;#039;  ||  User cannot create other roles (users)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;-d&amp;#039;&amp;#039;  ||  User can create databases&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;-D&amp;#039;&amp;#039;  ||  User cannot create databases&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;-P&amp;#039;&amp;#039;  ||  Prompt to create a password for the user&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Common Switches For All Commands ====&lt;br /&gt;
{| border=1&lt;br /&gt;
|-&lt;br /&gt;
|  &amp;#039;&amp;#039;&amp;#039;Switch&amp;#039;&amp;#039;&amp;#039;  ||  &amp;#039;&amp;#039;&amp;#039;Behaviour&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;-h&amp;#039;&amp;#039;  ||  Host - hostname of the PostgreSQL server &amp;#039;&amp;#039;(defaults to localhost)&amp;#039;&amp;#039;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;-p&amp;#039;&amp;#039;  ||  Port - PostgreSQL server port &amp;#039;&amp;#039;(defaults to 5432)&amp;#039;&amp;#039;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;-U&amp;#039;&amp;#039;  ||  User - specify the user to connect as &amp;#039;&amp;#039;(defaults to the shell user)&amp;#039;&amp;#039;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;-W&amp;#039;&amp;#039;  ||  Force PostgreSQL to ask you for a password before connecting&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Create Non-Privileged Users ===&lt;br /&gt;
&lt;br /&gt;
Usually, you give yourself admin rights, and then get your applications to use non-privileged accounts. For production boxes, that&amp;#039;s usually one account per different application and/or database, but for a development box we can often just use a single dev account:&lt;br /&gt;
&lt;br /&gt;
 createuser -SDRP devuser&lt;br /&gt;
&lt;br /&gt;
=== Drop Users ===&lt;br /&gt;
&lt;br /&gt;
You can also drop a user with the &amp;lt;tt&amp;gt;dropuser&amp;lt;/tt&amp;gt; shell command:&lt;br /&gt;
&lt;br /&gt;
 dropuser &amp;lt;username&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Create A Database ===&lt;br /&gt;
&lt;br /&gt;
Now we can create a database. Being 2008, we like to use UTF8 so we need to specify that, since the default is still ASCII.&lt;br /&gt;
&lt;br /&gt;
 createdb -O devuser -E UTF8 &amp;lt;databasename&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Switches for createdb ====&lt;br /&gt;
{| border=1&lt;br /&gt;
|-&lt;br /&gt;
|  &amp;#039;&amp;#039;&amp;#039;Switch&amp;#039;&amp;#039;&amp;#039;  ||  &amp;#039;&amp;#039;&amp;#039;Behaviour&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;-O&amp;#039;&amp;#039;  ||  Owner - the user that owns the database&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;-E&amp;#039;&amp;#039;  ||  Encoding - almost always UTF8&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Drop A Database ===&lt;br /&gt;
&lt;br /&gt;
You can also drop a database with the &amp;lt;tt&amp;gt;dropdb&amp;lt;/tt&amp;gt; shell command:&lt;br /&gt;
&lt;br /&gt;
 dropdb &amp;lt;databasename&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Using The Client ==&lt;br /&gt;
&lt;br /&gt;
The cli client is &amp;lt;tt&amp;gt;psql&amp;lt;/tt&amp;gt;. To get a list of databases on the system, you can use the &amp;#039;&amp;#039;-l&amp;#039;&amp;#039; switch:&lt;br /&gt;
&lt;br /&gt;
 psql -l&lt;br /&gt;
&lt;br /&gt;
=== Connect To A Database ===&lt;br /&gt;
&lt;br /&gt;
If your database has been created, you should be able to use the PostgreSQL client:&lt;br /&gt;
&lt;br /&gt;
 psql &amp;lt;databasename&amp;gt; [&amp;lt;username&amp;gt;]&lt;br /&gt;
&lt;br /&gt;
Since you are a superuser, you should be able to get amongst it without having to specify the username.&lt;br /&gt;
&lt;br /&gt;
=== Backslash Commands ===&lt;br /&gt;
&lt;br /&gt;
;TODO: once at the psql prompt, type \? for help with the various backslash commands, and \h for help with SQL syntax.&lt;br /&gt;
&lt;br /&gt;
{| border=1&lt;br /&gt;
|-&lt;br /&gt;
|  &amp;#039;&amp;#039;&amp;#039;Command&amp;#039;&amp;#039;&amp;#039;     || &amp;#039;&amp;#039;&amp;#039;Behaviour&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;\dt&amp;#039;&amp;#039;            || List the tables&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;\d &amp;lt;tablename&amp;gt;&amp;#039;&amp;#039; || Show table schema&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;\x&amp;#039;&amp;#039;             || Toggle to horizontal format when displaying rows&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;\i &amp;lt;filename&amp;gt;&amp;#039;&amp;#039;  || Execute a bunch of SQL in the file&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;\cd &amp;lt;path&amp;gt;&amp;#039;&amp;#039;     || Change directory (useful for \i)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;\l&amp;#039;&amp;#039;             || List all databases&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;\c &amp;lt;database&amp;gt;&amp;#039;&amp;#039;  || Connect to another database&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;\q&amp;#039;&amp;#039;             || Quit&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Backing Up And Restoring Databases ==&lt;br /&gt;
&lt;br /&gt;
We use the &amp;lt;tt&amp;gt;pg_dump&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;pg_restore&amp;lt;/tt&amp;gt; shell commands. Ownership of the database objects is probably the most common source of confusion here. Since most of the time ownership will not be more atomic than database-level, it is usually easiest to avoid the whole issue by not including ownership data in the dumps. It can then be safely determined by specifying the owner during the restore. This also means you can change the ownership if necessary, without unnecessary bloodshed.&lt;br /&gt;
&lt;br /&gt;
=== Backup ===&lt;br /&gt;
&lt;br /&gt;
To create a compressed format (-Fc) dump file (-f), that does not specify object ownerships (-O), execute the following:&lt;br /&gt;
&lt;br /&gt;
 pg_dump -Fc -O -f &amp;lt;dumpfile&amp;gt; &amp;lt;databasename&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Restore ===&lt;br /&gt;
&lt;br /&gt;
During a restore, the ownership is set to whichever user the restore command connects to the database as. So to restore a dump file into an existing database (-d), without using ownerships from the file (-O), but specifying the connecting user (-U) as the owner:&lt;br /&gt;
&lt;br /&gt;
 pg_restore -O -U &amp;lt;username&amp;gt; -d &amp;lt;databasename&amp;gt; &amp;lt;dumpfile&amp;gt;&lt;br /&gt;
&lt;br /&gt;
;NOTE: You usually want the database to be empty, having (re)created a new one for the restore.&lt;br /&gt;
&lt;br /&gt;
== Troubleshooting ==&lt;br /&gt;
&lt;br /&gt;
;I can&amp;#039;t drop the database!&lt;br /&gt;
:You may need to stop Apache before you can drop a database, otherwise PostgreSQL will complain that it is in use.&lt;br /&gt;
:Or, you can create a &amp;#039;&amp;#039;/usr/local/bin/pg_kill_connections&amp;#039;&amp;#039; script:&lt;br /&gt;
 #!/bin/sh&lt;br /&gt;
 DATABASE=&amp;quot;$1&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 if [ -z &amp;quot;${DATABASE}&amp;quot; ];then&lt;br /&gt;
     echo &amp;quot;Usage: pg_kill_connections dbname&amp;quot;&lt;br /&gt;
     exit 1;&lt;br /&gt;
 fi&lt;br /&gt;
 &lt;br /&gt;
 for i in $(su postgres -c \&lt;br /&gt;
        &amp;quot;psql -tc \&amp;quot;SELECT procpid FROM pg_stat_activity WHERE datname=&amp;#039;${DATABASE}&amp;#039;\&amp;quot; \&lt;br /&gt;
         template1 | xargs -r kill&amp;quot;); do&lt;br /&gt;
     kill $i&lt;br /&gt;
 done&lt;br /&gt;
&lt;br /&gt;
;How do I rename a database?&lt;br /&gt;
:ALTER DATABASE &amp;quot;foo&amp;quot; RENAME TO &amp;quot;bar&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
;How do I concatenate strings?&lt;br /&gt;
:SELECT &amp;#039;Hello&amp;#039; || &amp;#039; &amp;#039; || &amp;#039;World&amp;#039;;&lt;br /&gt;
&lt;br /&gt;
== See Also ==&lt;br /&gt;
* [[PostgreSQL/From_MySQL]]&lt;br /&gt;
* [[PostgreSQL full text searching]]&lt;/div&gt;</summary>
		<author><name>Johnno</name></author>
	</entry>
	<entry>
		<id>https://wiki.jon.geek.nz/index.php?title=NextCloud&amp;diff=2502</id>
		<title>NextCloud</title>
		<link rel="alternate" type="text/html" href="https://wiki.jon.geek.nz/index.php?title=NextCloud&amp;diff=2502"/>
		<updated>2023-09-07T20:10:13Z</updated>

		<summary type="html">&lt;p&gt;Johnno: /* Previews of other file types */ highlighting&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Assumes Ubuntu 20.04, stable20 branch, and installing in {{code|/var/www/nextcloud}} for a cloud.&amp;#039;&amp;#039;&amp;#039;example.com&amp;#039;&amp;#039;&amp;#039; URL (c. December 2020).&lt;br /&gt;
&lt;br /&gt;
== Prerequisites ==&lt;br /&gt;
&lt;br /&gt;
Install some stuff first. This NextCloud recipe uses [[PostgreSQL]], Redis, Apache 2.4, FastCGI with PHP FPM, and Dehydrated for [[Letsencrypt]] SSL certificate maangement.&lt;br /&gt;
&lt;br /&gt;
 sudo apt install apache2 libapache2-mod-fcgid \&lt;br /&gt;
    php7.4-{bcmath,bz2,curl,gd,fpm,gmp,intl,json,mbstring,opcache,pgsql,tidy,xmlrpc,xsl,zip}&lt;br /&gt;
    php-{imagick,redis} composer dehydrated postgresql redis-server&lt;br /&gt;
&lt;br /&gt;
;NOTE: NextCloud works fine under nginx, I just can&amp;#039;t be bothered maintaining what goes in {{code|.htaccess}} which NextCloud expects to be writeable to keep itself updated.&lt;br /&gt;
&lt;br /&gt;
== Configuring Apache and PHP ==&lt;br /&gt;
&lt;br /&gt;
: &amp;#039;&amp;#039;See the [[PHP]] page for setting up PHP with Apache, FPM and Event MPM.&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
=== Add a virtual host for NextCloud ===&lt;br /&gt;
&lt;br /&gt;
It should look something like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;apache&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;VirtualHost *:443&amp;gt;&lt;br /&gt;
   ServerName cloud.example.com&lt;br /&gt;
   DocumentRoot /var/www/nextcloud &lt;br /&gt;
 &lt;br /&gt;
   &amp;lt;Directory &amp;quot;/var/www/nexcloud&amp;quot;&amp;gt;&lt;br /&gt;
     Options FollowSymLinks MultiViews&lt;br /&gt;
     AllowOverride All&lt;br /&gt;
     Require all granted&lt;br /&gt;
     Satisfy Any &lt;br /&gt;
     SetEnv HOME /var/www/nextcloud&lt;br /&gt;
     SetEnv HTTP_HOME /var/www/nextcloud&lt;br /&gt;
 &lt;br /&gt;
     &amp;lt;IfModule mod_dav.c&amp;gt;&lt;br /&gt;
       Dav off&lt;br /&gt;
     &amp;lt;/IfModule&amp;gt;&lt;br /&gt;
   &amp;lt;/Directory&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
   SSLEngine On&lt;br /&gt;
   SSLCertificateFile ...&lt;br /&gt;
 &amp;lt;/VirtualHost&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== PHP settings ===&lt;br /&gt;
&lt;br /&gt;
Enable the opcache, increase the memory limit, and increase the maximum POST and file upload size so you can upload large files.&lt;br /&gt;
&lt;br /&gt;
== Create a database ==&lt;br /&gt;
&lt;br /&gt;
Create a database in [[PostgreSQL]]:&lt;br /&gt;
&lt;br /&gt;
 sudo -u postgres createuser -SDRP &amp;#039;&amp;#039;&amp;lt;nextcloud-user&amp;gt;&amp;#039;&amp;#039;&lt;br /&gt;
 sudo -u postgres createdb -E UTF8 -O &amp;#039;&amp;#039;&amp;lt;nextcloud-user&amp;gt;&amp;#039;&amp;#039; &amp;#039;&amp;#039;&amp;lt;nextcloud-dbname&amp;gt;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
== Install NextCloud ==&lt;br /&gt;
&lt;br /&gt;
We can just clone it from git:&lt;br /&gt;
&lt;br /&gt;
 git clone &amp;lt;nowiki&amp;gt;https://&amp;lt;/nowiki&amp;gt;github.com/nextcloud/server.git nextcloud&lt;br /&gt;
 cd nextcloud&lt;br /&gt;
 git checkout stable20  &amp;#039;&amp;#039;# or whatever the latest stable version is&amp;#039;&amp;#039;&lt;br /&gt;
 git submodule update --init --recursive&lt;br /&gt;
 chown www-data:www-data config apps .htaccess&lt;br /&gt;
&lt;br /&gt;
Create a directory for the cache and user data, which should not reside under the web root:&lt;br /&gt;
&lt;br /&gt;
 mkdir -p /var/lib/nextcloud/data /var/cache/nextcloud&lt;br /&gt;
 chown -R www-data:www-data /var/lib/nextcloud /var/cache/nextcloud&lt;br /&gt;
&lt;br /&gt;
== Configure NextCloud ==&lt;br /&gt;
&lt;br /&gt;
Edit the configuration file in {{code|config/config.php}} and check or consider these settings, and add the database and SMTP connection details:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
 $config =&amp;gt; [&lt;br /&gt;
   # ...&lt;br /&gt;
   #&lt;br /&gt;
   &amp;#039;passwordsalt&amp;#039; =&amp;gt; &amp;quot;&amp;lt;very long random string&amp;gt;&amp;quot;,&lt;br /&gt;
   &amp;#039;secret&amp;#039; =&amp;gt; &amp;quot;&amp;lt;a different very long random string&amp;gt;&amp;quot;,&lt;br /&gt;
   &amp;#039;trusted_domains&amp;#039; =&amp;gt; [&lt;br /&gt;
     0 =&amp;gt; &amp;quot;cloud.example.com&amp;quot;,&lt;br /&gt;
   ],&lt;br /&gt;
   &amp;#039;datadirectory&amp;#039; =&amp;gt; &amp;#039;/var/lib/nextcloud/data&amp;#039;,&lt;br /&gt;
   &amp;#039;overwrite.cli.url&amp;#039; =&amp;gt; &amp;#039;&amp;lt;nowiki&amp;gt;https://&amp;lt;/nowiki&amp;gt;cloud.example.com/&amp;#039;,&lt;br /&gt;
   &amp;#039;htaccess.RewriteBase&amp;#039; =&amp;gt; &amp;#039;/&amp;#039;,&lt;br /&gt;
 &lt;br /&gt;
   # Database connection details&lt;br /&gt;
   &amp;#039;dbtype&amp;#039; =&amp;gt; &amp;#039;pgsql&amp;#039;,&lt;br /&gt;
   &amp;#039;dbhost&amp;#039; =&amp;gt; &amp;#039;localhost&amp;#039;,&lt;br /&gt;
   &amp;#039;dbuser&amp;#039; =&amp;gt; &amp;quot;&amp;lt;nextcloud-dbuser&amp;gt;&amp;quot;,&lt;br /&gt;
   &amp;#039;dbpassword&amp;#039; =&amp;gt; &amp;quot;&amp;lt;password&amp;gt;&amp;quot;,&lt;br /&gt;
   &amp;#039;dbname&amp;#039; =&amp;gt; &amp;quot;&amp;lt;nextcloud-dbname&amp;gt;&amp;quot;,&lt;br /&gt;
   &amp;#039;dbtableprefix&amp;#039; =&amp;gt; &amp;#039;oc_&amp;#039;,&lt;br /&gt;
 &lt;br /&gt;
   # Force all URLs to use SSL or it may trip up things like OAuth&lt;br /&gt;
   &amp;#039;overwriteprotocol&amp;#039; =&amp;gt; &amp;#039;https&amp;#039;,&lt;br /&gt;
 &lt;br /&gt;
   # Use Redis and caching to make everything go faster&lt;br /&gt;
   &amp;#039;memcache.local&amp;#039; =&amp;gt; &amp;#039;\\OC\\Memcache\\Redis&amp;#039;,&lt;br /&gt;
   &amp;#039;memcache.locking&amp;#039; =&amp;gt; &amp;#039;\\OC\\Memcache\\Redis&amp;#039;,&lt;br /&gt;
   &amp;#039;redis&amp;#039; =&amp;gt; [&lt;br /&gt;
     &amp;#039;host&amp;#039; =&amp;gt; &amp;#039;localhost&amp;#039;,&lt;br /&gt;
     &amp;#039;port&amp;#039; =&amp;gt; 6379,&lt;br /&gt;
   ],&lt;br /&gt;
   &amp;#039;cache_path&amp;#039; =&amp;gt; &amp;#039;/var/cache/nextcloud&amp;#039;,&lt;br /&gt;
 &lt;br /&gt;
   # Send email details&lt;br /&gt;
   &amp;#039;mail_smtpmode&amp;#039; =&amp;gt; &amp;#039;smtp&amp;#039;,&lt;br /&gt;
   &amp;#039;mail_smtpsecure&amp;#039; =&amp;gt; &amp;#039;tls&amp;#039;,&lt;br /&gt;
   &amp;#039;mail_sendmailmode&amp;#039; =&amp;gt; &amp;#039;smtp&amp;#039;,&lt;br /&gt;
   &amp;#039;mail_from_address&amp;#039; =&amp;gt; &amp;quot;nexcloud@example.com&amp;quot;,&lt;br /&gt;
   &amp;#039;mail_domain&amp;#039; =&amp;gt; &amp;quot;example.com&amp;quot;,&lt;br /&gt;
   &amp;#039;mail_smtpauthtype&amp;#039; =&amp;gt; &amp;#039;PLAIN&amp;#039;,&lt;br /&gt;
   &amp;#039;mail_smtpauth&amp;#039; =&amp;gt; 1,&lt;br /&gt;
   &amp;#039;mail_smtphost&amp;#039; =&amp;gt; &amp;quot;mail.example.com&amp;quot;,&lt;br /&gt;
   &amp;#039;mail_smtpport&amp;#039; =&amp;gt; 587,&lt;br /&gt;
   &amp;#039;mail_smtpname&amp;#039; =&amp;gt; &amp;quot;&amp;lt;emailuser&amp;gt;&amp;quot;,&lt;br /&gt;
   &amp;#039;mail_smtppassword&amp;#039; =&amp;gt; &amp;quot;&amp;lt;emailpassword&amp;gt;&amp;quot;,&lt;br /&gt;
 &lt;br /&gt;
   # ...&lt;br /&gt;
 ]  &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then navigate to the URL in the browser to install (or run the NextCloud {{code | ./occ}} tool from the command line).&lt;br /&gt;
&lt;br /&gt;
=== Clean URLs ===&lt;br /&gt;
&lt;br /&gt;
For clean URLs, make sure {{code | AllowOverride All}} is set for the parent directory; the {{code | /var/www}} definition is in the main {{code | /etc/apache2/apache.conf}}. Then run the follwing OCC command to enable the rewrite rules:&lt;br /&gt;
&lt;br /&gt;
 sudo -u www-data ./occ maintenance:update:htaccess&lt;br /&gt;
&lt;br /&gt;
=== Previews of other file types ===&lt;br /&gt;
&lt;br /&gt;
Edit {{code|/etc/ImageMagick/policy.xml}} and remove this line to get PDF previews to work:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;policy domain=&amp;quot;coder&amp;quot; rights=&amp;quot;none&amp;quot; pattern=&amp;quot;PDF&amp;quot; /&amp;gt; &amp;lt;!-- remove this line --&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then add the following to {{code|config.php}} to get lots of other useful file previews:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
   &amp;#039;enabledPreviewProviders&amp;#039; =&amp;gt; [&lt;br /&gt;
     # ...&lt;br /&gt;
     8 =&amp;gt; &amp;#039;OC\\Preview\\MarkDown&amp;#039;,&lt;br /&gt;
     9 =&amp;gt; &amp;#039;OC\\Preview\\Movie&amp;#039;,&lt;br /&gt;
     10 =&amp;gt; &amp;#039;OC\\Preview\\PDF&amp;#039;,&lt;br /&gt;
     11 =&amp;gt; &amp;#039;OC\\Preview\\OpenDocument&amp;#039;,&lt;br /&gt;
     12 =&amp;gt; &amp;#039;OC\\Preview\\MSOfficeDoc&amp;#039;,&lt;br /&gt;
     13 =&amp;gt; &amp;#039;OC\\Preview\\MSOffice2003&amp;#039;,&lt;br /&gt;
     14 =&amp;gt; &amp;#039;OC\\Preview\\MSOffice2007&amp;#039;,&lt;br /&gt;
   ],&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Photos ===&lt;br /&gt;
&lt;br /&gt;
Photos replaces the Gallery app, and is installed separately through the NC store or you can use git to manage it as a submodule. If it doesn&amp;#039;t work you might need to build its JavaScript resources by running {{code|make}} in its {{code|apps/photos}} directory. Alternatively you can resuscitate the Gallery app, which stopped working after NextCloud version 17, by updating its JavaScript dompurify library to a [https://raw.githubusercontent.com/nextcloud/gallery/ecb26a812f30a3f516964808ccfa6430be09b45e/js/vendor/dompurify/src/purify.js newer version] and bumping the app max version in {{code|apps/galleryappinfo/info.xml}} as follows (See also [https://github.com/nextcloud/gallery/pull/570/ pull request #570]):&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nextcloud min-version=&amp;quot;17&amp;quot; max-version=&amp;quot;&amp;#039;&amp;#039;&amp;#039;20&amp;#039;&amp;#039;&amp;#039;&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== NextCloud Talk ===&lt;br /&gt;
&lt;br /&gt;
To be at all useful, you need a TURN server. This is easiest achieved by installing and correctly configuring coturn, which also acts as a STUN server. STUN is for clients to figure out their external IP address, and TURN is for relaying UDP packets, e.g. for WebRTC.&lt;br /&gt;
&lt;br /&gt;
 sudo apt install coturn&lt;br /&gt;
&lt;br /&gt;
For it to actually do anything (it is disabled by default!) you need to edit {{code|/etc/default/coturn}} and make sure it contains the following, and is not commented out:&lt;br /&gt;
&lt;br /&gt;
 TURNSERVER_ENABLED=1&lt;br /&gt;
&lt;br /&gt;
Then in {{code|/etc/turnserver.conf}} you need to configure its domain name, IP addresses and ports, SSL certificate, and how TURN authenticates. See GitHub for a fully documented example [https://github.com/coturn/coturn/blob/master/examples/etc/turnserver.conf turnserver.conf] file. This example uses the same domain as the NextCloud instance, on the standard STUN and TURN ports, but if you want to host it on port 443 to support people behind restrictive firewalls, you will need a different subdomain and/or IP address:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;ini&amp;quot;&amp;gt;&lt;br /&gt;
 server-name=cloud.example.com&lt;br /&gt;
 realm=cloud.example.com&lt;br /&gt;
 &lt;br /&gt;
 # When hosted on an internal LAN or DMZ, it might look like this: &lt;br /&gt;
 listening-ip=192.168.1.100&lt;br /&gt;
 relay-ip=192.168.1.100&lt;br /&gt;
 external-ip=123.45.67.8&lt;br /&gt;
 &lt;br /&gt;
 # Or use the short-hand:&lt;br /&gt;
 external-ip=123.45.67.8/192.168.1.100&lt;br /&gt;
 &lt;br /&gt;
 # Specify listening ports; originally 3478 was unencrypted, and 5349 was TLS,&lt;br /&gt;
 # but now TLS is supported on both. It is possible to listen on 443, which will&lt;br /&gt;
 # help to provide connectivity for people behind port-limited firewalls; this will&lt;br /&gt;
 # conflict with any HTTPS web hosting on the same server though, unless you set&lt;br /&gt;
 # up a second IP address for it.&lt;br /&gt;
 listening-port=3478&lt;br /&gt;
 tls-listening-port=5349&lt;br /&gt;
 #tls-listening-port=443&lt;br /&gt;
 &lt;br /&gt;
 # Specify a UDP port range and ensure they are exposed through the firewall/router&lt;br /&gt;
 min-port=53490&lt;br /&gt;
 max-port=59999&lt;br /&gt;
 &lt;br /&gt;
 # SSL setup; &lt;br /&gt;
 cert=/path/to/cloud.example.com/fullchain.cert&lt;br /&gt;
 pkey=/path/to/cloud.example.com/privkey.pem&lt;br /&gt;
 no-tlsv1&lt;br /&gt;
 no-tlsv1_1&lt;br /&gt;
 &lt;br /&gt;
 # To use with NextCloud, set a shared secret here.&lt;br /&gt;
 use-auth-secret&lt;br /&gt;
 static-auth-secret=your-shared-secret-string-here&lt;br /&gt;
 stale-nonce=600&lt;br /&gt;
 &lt;br /&gt;
 # Limit STUN amplification/gain attacks (coturn 4.5.2+)&lt;br /&gt;
 no-stun-backward-compatibility&lt;br /&gt;
 response-origin-only-with-rfc5780&lt;br /&gt;
 &lt;br /&gt;
 # RFC-5780 support requires two listening IP addresses and is for serious-cat&lt;br /&gt;
 # usage, so you can safely disable it for a small home NextCloud instance.&lt;br /&gt;
 no-rfc5780&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In your NextCloud Administration section, you can now configure Talk to use the STUN/TURN server, using your server URLs, and provide the same shared secret you configured above. For maximum compatibility, use both UDP and TCP, and both turn and turns (TLS) connections:&lt;br /&gt;
&lt;br /&gt;
 stun: &amp;#039;&amp;#039;&amp;#039;cloud.example.com&amp;#039;&amp;#039;&amp;#039;:5349&lt;br /&gt;
 turn and turns: &amp;#039;&amp;#039;&amp;#039;cloud.example.com&amp;#039;&amp;#039;&amp;#039;:5349&lt;br /&gt;
&lt;br /&gt;
Test your server [https://webrtc.github.io/samples/src/content/peerconnection/trickle-ice/ here]. If STUN is working, you should get {{code|srflx}} candidates, and {{code|relay}} candidates if TURN is working.&lt;br /&gt;
&lt;br /&gt;
Sources and further reading:&lt;br /&gt;
* NextCloud Talk documentation: [https://nextcloud-talk.readthedocs.io/en/latest/TURN/ TURN], [https://nextcloud-talk.readthedocs.io/en/latest/coturn coturn]&lt;br /&gt;
* NextCloud Help, [https://help.nextcloud.com/t/howto-setup-nextcloud-talk-with-turn-server/30794 1] [https://help.nextcloud.com/t/nextcloud-talk-app-could-not-establish-a-connection-a-turn-server/131069/31 2]&lt;br /&gt;
* Stack Overflow [https://stackoverflow.com/questions/42801361/install-rfc5766-turn-server-trying-to-bind-fd-to-ip-address-errno-99 1]&lt;br /&gt;
* [https://ourcodeworld.com/articles/read/1526/how-to-test-online-whether-a-stun-turn-server-is-working-properly-or-not Testing STUN/TURN]&lt;br /&gt;
&lt;br /&gt;
== Maintenance ==&lt;br /&gt;
&lt;br /&gt;
Keep the git checkout of NextCloud and its submodules up to date with git, and run the OCC upgrade command:&lt;br /&gt;
&lt;br /&gt;
 cd /var/www/nextcloud&lt;br /&gt;
 git pull&lt;br /&gt;
 git submodule update --init --recursive&lt;br /&gt;
 sudo -u www-data ./occ upgrade&lt;br /&gt;
&lt;br /&gt;
=== Cron job ===&lt;br /&gt;
&lt;br /&gt;
In the administrator settings select cron rather than other methods, and put this in {{code|/etc/cron.d/nextcloud}}&lt;br /&gt;
&lt;br /&gt;
 */5 * * * * www-data /usr/bin/php /var/www/nextcloud/cron.php&lt;/div&gt;</summary>
		<author><name>Johnno</name></author>
	</entry>
	<entry>
		<id>https://wiki.jon.geek.nz/index.php?title=NextCloud&amp;diff=2501</id>
		<title>NextCloud</title>
		<link rel="alternate" type="text/html" href="https://wiki.jon.geek.nz/index.php?title=NextCloud&amp;diff=2501"/>
		<updated>2023-09-07T20:07:57Z</updated>

		<summary type="html">&lt;p&gt;Johnno: remove bold/italic in syntax highlights&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Assumes Ubuntu 20.04, stable20 branch, and installing in {{code|/var/www/nextcloud}} for a cloud.&amp;#039;&amp;#039;&amp;#039;example.com&amp;#039;&amp;#039;&amp;#039; URL (c. December 2020).&lt;br /&gt;
&lt;br /&gt;
== Prerequisites ==&lt;br /&gt;
&lt;br /&gt;
Install some stuff first. This NextCloud recipe uses [[PostgreSQL]], Redis, Apache 2.4, FastCGI with PHP FPM, and Dehydrated for [[Letsencrypt]] SSL certificate maangement.&lt;br /&gt;
&lt;br /&gt;
 sudo apt install apache2 libapache2-mod-fcgid \&lt;br /&gt;
    php7.4-{bcmath,bz2,curl,gd,fpm,gmp,intl,json,mbstring,opcache,pgsql,tidy,xmlrpc,xsl,zip}&lt;br /&gt;
    php-{imagick,redis} composer dehydrated postgresql redis-server&lt;br /&gt;
&lt;br /&gt;
;NOTE: NextCloud works fine under nginx, I just can&amp;#039;t be bothered maintaining what goes in {{code|.htaccess}} which NextCloud expects to be writeable to keep itself updated.&lt;br /&gt;
&lt;br /&gt;
== Configuring Apache and PHP ==&lt;br /&gt;
&lt;br /&gt;
: &amp;#039;&amp;#039;See the [[PHP]] page for setting up PHP with Apache, FPM and Event MPM.&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
=== Add a virtual host for NextCloud ===&lt;br /&gt;
&lt;br /&gt;
It should look something like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;apache&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;VirtualHost *:443&amp;gt;&lt;br /&gt;
   ServerName cloud.example.com&lt;br /&gt;
   DocumentRoot /var/www/nextcloud &lt;br /&gt;
 &lt;br /&gt;
   &amp;lt;Directory &amp;quot;/var/www/nexcloud&amp;quot;&amp;gt;&lt;br /&gt;
     Options FollowSymLinks MultiViews&lt;br /&gt;
     AllowOverride All&lt;br /&gt;
     Require all granted&lt;br /&gt;
     Satisfy Any &lt;br /&gt;
     SetEnv HOME /var/www/nextcloud&lt;br /&gt;
     SetEnv HTTP_HOME /var/www/nextcloud&lt;br /&gt;
 &lt;br /&gt;
     &amp;lt;IfModule mod_dav.c&amp;gt;&lt;br /&gt;
       Dav off&lt;br /&gt;
     &amp;lt;/IfModule&amp;gt;&lt;br /&gt;
   &amp;lt;/Directory&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
   SSLEngine On&lt;br /&gt;
   SSLCertificateFile ...&lt;br /&gt;
 &amp;lt;/VirtualHost&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== PHP settings ===&lt;br /&gt;
&lt;br /&gt;
Enable the opcache, increase the memory limit, and increase the maximum POST and file upload size so you can upload large files.&lt;br /&gt;
&lt;br /&gt;
== Create a database ==&lt;br /&gt;
&lt;br /&gt;
Create a database in [[PostgreSQL]]:&lt;br /&gt;
&lt;br /&gt;
 sudo -u postgres createuser -SDRP &amp;#039;&amp;#039;&amp;lt;nextcloud-user&amp;gt;&amp;#039;&amp;#039;&lt;br /&gt;
 sudo -u postgres createdb -E UTF8 -O &amp;#039;&amp;#039;&amp;lt;nextcloud-user&amp;gt;&amp;#039;&amp;#039; &amp;#039;&amp;#039;&amp;lt;nextcloud-dbname&amp;gt;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
== Install NextCloud ==&lt;br /&gt;
&lt;br /&gt;
We can just clone it from git:&lt;br /&gt;
&lt;br /&gt;
 git clone &amp;lt;nowiki&amp;gt;https://&amp;lt;/nowiki&amp;gt;github.com/nextcloud/server.git nextcloud&lt;br /&gt;
 cd nextcloud&lt;br /&gt;
 git checkout stable20  &amp;#039;&amp;#039;# or whatever the latest stable version is&amp;#039;&amp;#039;&lt;br /&gt;
 git submodule update --init --recursive&lt;br /&gt;
 chown www-data:www-data config apps .htaccess&lt;br /&gt;
&lt;br /&gt;
Create a directory for the cache and user data, which should not reside under the web root:&lt;br /&gt;
&lt;br /&gt;
 mkdir -p /var/lib/nextcloud/data /var/cache/nextcloud&lt;br /&gt;
 chown -R www-data:www-data /var/lib/nextcloud /var/cache/nextcloud&lt;br /&gt;
&lt;br /&gt;
== Configure NextCloud ==&lt;br /&gt;
&lt;br /&gt;
Edit the configuration file in {{code|config/config.php}} and check or consider these settings, and add the database and SMTP connection details:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
 $config =&amp;gt; [&lt;br /&gt;
   # ...&lt;br /&gt;
   #&lt;br /&gt;
   &amp;#039;passwordsalt&amp;#039; =&amp;gt; &amp;quot;&amp;lt;very long random string&amp;gt;&amp;quot;,&lt;br /&gt;
   &amp;#039;secret&amp;#039; =&amp;gt; &amp;quot;&amp;lt;a different very long random string&amp;gt;&amp;quot;,&lt;br /&gt;
   &amp;#039;trusted_domains&amp;#039; =&amp;gt; [&lt;br /&gt;
     0 =&amp;gt; &amp;quot;cloud.example.com&amp;quot;,&lt;br /&gt;
   ],&lt;br /&gt;
   &amp;#039;datadirectory&amp;#039; =&amp;gt; &amp;#039;/var/lib/nextcloud/data&amp;#039;,&lt;br /&gt;
   &amp;#039;overwrite.cli.url&amp;#039; =&amp;gt; &amp;#039;&amp;lt;nowiki&amp;gt;https://&amp;lt;/nowiki&amp;gt;cloud.example.com/&amp;#039;,&lt;br /&gt;
   &amp;#039;htaccess.RewriteBase&amp;#039; =&amp;gt; &amp;#039;/&amp;#039;,&lt;br /&gt;
 &lt;br /&gt;
   # Database connection details&lt;br /&gt;
   &amp;#039;dbtype&amp;#039; =&amp;gt; &amp;#039;pgsql&amp;#039;,&lt;br /&gt;
   &amp;#039;dbhost&amp;#039; =&amp;gt; &amp;#039;localhost&amp;#039;,&lt;br /&gt;
   &amp;#039;dbuser&amp;#039; =&amp;gt; &amp;quot;&amp;lt;nextcloud-dbuser&amp;gt;&amp;quot;,&lt;br /&gt;
   &amp;#039;dbpassword&amp;#039; =&amp;gt; &amp;quot;&amp;lt;password&amp;gt;&amp;quot;,&lt;br /&gt;
   &amp;#039;dbname&amp;#039; =&amp;gt; &amp;quot;&amp;lt;nextcloud-dbname&amp;gt;&amp;quot;,&lt;br /&gt;
   &amp;#039;dbtableprefix&amp;#039; =&amp;gt; &amp;#039;oc_&amp;#039;,&lt;br /&gt;
 &lt;br /&gt;
   # Force all URLs to use SSL or it may trip up things like OAuth&lt;br /&gt;
   &amp;#039;overwriteprotocol&amp;#039; =&amp;gt; &amp;#039;https&amp;#039;,&lt;br /&gt;
 &lt;br /&gt;
   # Use Redis and caching to make everything go faster&lt;br /&gt;
   &amp;#039;memcache.local&amp;#039; =&amp;gt; &amp;#039;\\OC\\Memcache\\Redis&amp;#039;,&lt;br /&gt;
   &amp;#039;memcache.locking&amp;#039; =&amp;gt; &amp;#039;\\OC\\Memcache\\Redis&amp;#039;,&lt;br /&gt;
   &amp;#039;redis&amp;#039; =&amp;gt; [&lt;br /&gt;
     &amp;#039;host&amp;#039; =&amp;gt; &amp;#039;localhost&amp;#039;,&lt;br /&gt;
     &amp;#039;port&amp;#039; =&amp;gt; 6379,&lt;br /&gt;
   ],&lt;br /&gt;
   &amp;#039;cache_path&amp;#039; =&amp;gt; &amp;#039;/var/cache/nextcloud&amp;#039;,&lt;br /&gt;
 &lt;br /&gt;
   # Send email details&lt;br /&gt;
   &amp;#039;mail_smtpmode&amp;#039; =&amp;gt; &amp;#039;smtp&amp;#039;,&lt;br /&gt;
   &amp;#039;mail_smtpsecure&amp;#039; =&amp;gt; &amp;#039;tls&amp;#039;,&lt;br /&gt;
   &amp;#039;mail_sendmailmode&amp;#039; =&amp;gt; &amp;#039;smtp&amp;#039;,&lt;br /&gt;
   &amp;#039;mail_from_address&amp;#039; =&amp;gt; &amp;quot;nexcloud@example.com&amp;quot;,&lt;br /&gt;
   &amp;#039;mail_domain&amp;#039; =&amp;gt; &amp;quot;example.com&amp;quot;,&lt;br /&gt;
   &amp;#039;mail_smtpauthtype&amp;#039; =&amp;gt; &amp;#039;PLAIN&amp;#039;,&lt;br /&gt;
   &amp;#039;mail_smtpauth&amp;#039; =&amp;gt; 1,&lt;br /&gt;
   &amp;#039;mail_smtphost&amp;#039; =&amp;gt; &amp;quot;mail.example.com&amp;quot;,&lt;br /&gt;
   &amp;#039;mail_smtpport&amp;#039; =&amp;gt; 587,&lt;br /&gt;
   &amp;#039;mail_smtpname&amp;#039; =&amp;gt; &amp;quot;&amp;lt;emailuser&amp;gt;&amp;quot;,&lt;br /&gt;
   &amp;#039;mail_smtppassword&amp;#039; =&amp;gt; &amp;quot;&amp;lt;emailpassword&amp;gt;&amp;quot;,&lt;br /&gt;
 &lt;br /&gt;
   # ...&lt;br /&gt;
 ]  &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then navigate to the URL in the browser to install (or run the NextCloud {{code | ./occ}} tool from the command line).&lt;br /&gt;
&lt;br /&gt;
=== Clean URLs ===&lt;br /&gt;
&lt;br /&gt;
For clean URLs, make sure {{code | AllowOverride All}} is set for the parent directory; the {{code | /var/www}} definition is in the main {{code | /etc/apache2/apache.conf}}. Then run the follwing OCC command to enable the rewrite rules:&lt;br /&gt;
&lt;br /&gt;
 sudo -u www-data ./occ maintenance:update:htaccess&lt;br /&gt;
&lt;br /&gt;
=== Previews of other file types ===&lt;br /&gt;
&lt;br /&gt;
Edit {{code|/etc/ImageMagick/policy.xml}} and remove this line to get PDF previews to work:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;policy domain=&amp;quot;coder&amp;quot; rights=&amp;quot;none&amp;quot; pattern=&amp;quot;PDF&amp;quot; /&amp;gt; &amp;lt;!-- remove this line --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then add the following to {{code|config.php}} to get lots of other useful file previews:&lt;br /&gt;
   &amp;#039;enabledPreviewProviders&amp;#039; =&amp;gt; [&lt;br /&gt;
     # ...&lt;br /&gt;
     8 =&amp;gt; &amp;#039;OC\\Preview\\MarkDown&amp;#039;,&lt;br /&gt;
     9 =&amp;gt; &amp;#039;OC\\Preview\\Movie&amp;#039;,&lt;br /&gt;
     10 =&amp;gt; &amp;#039;OC\\Preview\\PDF&amp;#039;,&lt;br /&gt;
     11 =&amp;gt; &amp;#039;OC\\Preview\\OpenDocument&amp;#039;,&lt;br /&gt;
     12 =&amp;gt; &amp;#039;OC\\Preview\\MSOfficeDoc&amp;#039;,&lt;br /&gt;
     13 =&amp;gt; &amp;#039;OC\\Preview\\MSOffice2003&amp;#039;,&lt;br /&gt;
     14 =&amp;gt; &amp;#039;OC\\Preview\\MSOffice2007&amp;#039;,&lt;br /&gt;
   ],&lt;br /&gt;
&lt;br /&gt;
=== Photos ===&lt;br /&gt;
&lt;br /&gt;
Photos replaces the Gallery app, and is installed separately through the NC store or you can use git to manage it as a submodule. If it doesn&amp;#039;t work you might need to build its JavaScript resources by running {{code|make}} in its {{code|apps/photos}} directory. Alternatively you can resuscitate the Gallery app, which stopped working after NextCloud version 17, by updating its JavaScript dompurify library to a [https://raw.githubusercontent.com/nextcloud/gallery/ecb26a812f30a3f516964808ccfa6430be09b45e/js/vendor/dompurify/src/purify.js newer version] and bumping the app max version in {{code|apps/galleryappinfo/info.xml}} as follows (See also [https://github.com/nextcloud/gallery/pull/570/ pull request #570]):&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nextcloud min-version=&amp;quot;17&amp;quot; max-version=&amp;quot;&amp;#039;&amp;#039;&amp;#039;20&amp;#039;&amp;#039;&amp;#039;&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== NextCloud Talk ===&lt;br /&gt;
&lt;br /&gt;
To be at all useful, you need a TURN server. This is easiest achieved by installing and correctly configuring coturn, which also acts as a STUN server. STUN is for clients to figure out their external IP address, and TURN is for relaying UDP packets, e.g. for WebRTC.&lt;br /&gt;
&lt;br /&gt;
 sudo apt install coturn&lt;br /&gt;
&lt;br /&gt;
For it to actually do anything (it is disabled by default!) you need to edit {{code|/etc/default/coturn}} and make sure it contains the following, and is not commented out:&lt;br /&gt;
&lt;br /&gt;
 TURNSERVER_ENABLED=1&lt;br /&gt;
&lt;br /&gt;
Then in {{code|/etc/turnserver.conf}} you need to configure its domain name, IP addresses and ports, SSL certificate, and how TURN authenticates. See GitHub for a fully documented example [https://github.com/coturn/coturn/blob/master/examples/etc/turnserver.conf turnserver.conf] file. This example uses the same domain as the NextCloud instance, on the standard STUN and TURN ports, but if you want to host it on port 443 to support people behind restrictive firewalls, you will need a different subdomain and/or IP address:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;ini&amp;quot;&amp;gt;&lt;br /&gt;
 server-name=cloud.example.com&lt;br /&gt;
 realm=cloud.example.com&lt;br /&gt;
 &lt;br /&gt;
 # When hosted on an internal LAN or DMZ, it might look like this: &lt;br /&gt;
 listening-ip=192.168.1.100&lt;br /&gt;
 relay-ip=192.168.1.100&lt;br /&gt;
 external-ip=123.45.67.8&lt;br /&gt;
 &lt;br /&gt;
 # Or use the short-hand:&lt;br /&gt;
 external-ip=123.45.67.8/192.168.1.100&lt;br /&gt;
 &lt;br /&gt;
 # Specify listening ports; originally 3478 was unencrypted, and 5349 was TLS,&lt;br /&gt;
 # but now TLS is supported on both. It is possible to listen on 443, which will&lt;br /&gt;
 # help to provide connectivity for people behind port-limited firewalls; this will&lt;br /&gt;
 # conflict with any HTTPS web hosting on the same server though, unless you set&lt;br /&gt;
 # up a second IP address for it.&lt;br /&gt;
 listening-port=3478&lt;br /&gt;
 tls-listening-port=5349&lt;br /&gt;
 #tls-listening-port=443&lt;br /&gt;
 &lt;br /&gt;
 # Specify a UDP port range and ensure they are exposed through the firewall/router&lt;br /&gt;
 min-port=53490&lt;br /&gt;
 max-port=59999&lt;br /&gt;
 &lt;br /&gt;
 # SSL setup; &lt;br /&gt;
 cert=/path/to/cloud.example.com/fullchain.cert&lt;br /&gt;
 pkey=/path/to/cloud.example.com/privkey.pem&lt;br /&gt;
 no-tlsv1&lt;br /&gt;
 no-tlsv1_1&lt;br /&gt;
 &lt;br /&gt;
 # To use with NextCloud, set a shared secret here.&lt;br /&gt;
 use-auth-secret&lt;br /&gt;
 static-auth-secret=your-shared-secret-string-here&lt;br /&gt;
 stale-nonce=600&lt;br /&gt;
 &lt;br /&gt;
 # Limit STUN amplification/gain attacks (coturn 4.5.2+)&lt;br /&gt;
 no-stun-backward-compatibility&lt;br /&gt;
 response-origin-only-with-rfc5780&lt;br /&gt;
 &lt;br /&gt;
 # RFC-5780 support requires two listening IP addresses and is for serious-cat&lt;br /&gt;
 # usage, so you can safely disable it for a small home NextCloud instance.&lt;br /&gt;
 no-rfc5780&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In your NextCloud Administration section, you can now configure Talk to use the STUN/TURN server, using your server URLs, and provide the same shared secret you configured above. For maximum compatibility, use both UDP and TCP, and both turn and turns (TLS) connections:&lt;br /&gt;
&lt;br /&gt;
 stun: &amp;#039;&amp;#039;&amp;#039;cloud.example.com&amp;#039;&amp;#039;&amp;#039;:5349&lt;br /&gt;
 turn and turns: &amp;#039;&amp;#039;&amp;#039;cloud.example.com&amp;#039;&amp;#039;&amp;#039;:5349&lt;br /&gt;
&lt;br /&gt;
Test your server [https://webrtc.github.io/samples/src/content/peerconnection/trickle-ice/ here]. If STUN is working, you should get {{code|srflx}} candidates, and {{code|relay}} candidates if TURN is working.&lt;br /&gt;
&lt;br /&gt;
Sources and further reading:&lt;br /&gt;
* NextCloud Talk documentation: [https://nextcloud-talk.readthedocs.io/en/latest/TURN/ TURN], [https://nextcloud-talk.readthedocs.io/en/latest/coturn coturn]&lt;br /&gt;
* NextCloud Help, [https://help.nextcloud.com/t/howto-setup-nextcloud-talk-with-turn-server/30794 1] [https://help.nextcloud.com/t/nextcloud-talk-app-could-not-establish-a-connection-a-turn-server/131069/31 2]&lt;br /&gt;
* Stack Overflow [https://stackoverflow.com/questions/42801361/install-rfc5766-turn-server-trying-to-bind-fd-to-ip-address-errno-99 1]&lt;br /&gt;
* [https://ourcodeworld.com/articles/read/1526/how-to-test-online-whether-a-stun-turn-server-is-working-properly-or-not Testing STUN/TURN]&lt;br /&gt;
&lt;br /&gt;
== Maintenance ==&lt;br /&gt;
&lt;br /&gt;
Keep the git checkout of NextCloud and its submodules up to date with git, and run the OCC upgrade command:&lt;br /&gt;
&lt;br /&gt;
 cd /var/www/nextcloud&lt;br /&gt;
 git pull&lt;br /&gt;
 git submodule update --init --recursive&lt;br /&gt;
 sudo -u www-data ./occ upgrade&lt;br /&gt;
&lt;br /&gt;
=== Cron job ===&lt;br /&gt;
&lt;br /&gt;
In the administrator settings select cron rather than other methods, and put this in {{code|/etc/cron.d/nextcloud}}&lt;br /&gt;
&lt;br /&gt;
 */5 * * * * www-data /usr/bin/php /var/www/nextcloud/cron.php&lt;/div&gt;</summary>
		<author><name>Johnno</name></author>
	</entry>
	<entry>
		<id>https://wiki.jon.geek.nz/index.php?title=NextCloud&amp;diff=2500</id>
		<title>NextCloud</title>
		<link rel="alternate" type="text/html" href="https://wiki.jon.geek.nz/index.php?title=NextCloud&amp;diff=2500"/>
		<updated>2023-09-07T20:05:06Z</updated>

		<summary type="html">&lt;p&gt;Johnno: syntax highlighting&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Assumes Ubuntu 20.04, stable20 branch, and installing in {{code|/var/www/nextcloud}} for a cloud.&amp;#039;&amp;#039;&amp;#039;example.com&amp;#039;&amp;#039;&amp;#039; URL (c. December 2020).&lt;br /&gt;
&lt;br /&gt;
== Prerequisites ==&lt;br /&gt;
&lt;br /&gt;
Install some stuff first. This NextCloud recipe uses [[PostgreSQL]], Redis, Apache 2.4, FastCGI with PHP FPM, and Dehydrated for [[Letsencrypt]] SSL certificate maangement.&lt;br /&gt;
&lt;br /&gt;
 sudo apt install apache2 libapache2-mod-fcgid \&lt;br /&gt;
    php7.4-{bcmath,bz2,curl,gd,fpm,gmp,intl,json,mbstring,opcache,pgsql,tidy,xmlrpc,xsl,zip}&lt;br /&gt;
    php-{imagick,redis} composer dehydrated postgresql redis-server&lt;br /&gt;
&lt;br /&gt;
;NOTE: NextCloud works fine under nginx, I just can&amp;#039;t be bothered maintaining what goes in {{code|.htaccess}} which NextCloud expects to be writeable to keep itself updated.&lt;br /&gt;
&lt;br /&gt;
== Configuring Apache and PHP ==&lt;br /&gt;
&lt;br /&gt;
: &amp;#039;&amp;#039;See the [[PHP]] page for setting up PHP with Apache, FPM and Event MPM.&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
=== Add a virtual host for NextCloud ===&lt;br /&gt;
&lt;br /&gt;
It should look something like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;apache&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;VirtualHost *:443&amp;gt;&lt;br /&gt;
   ServerName cloud.&amp;#039;&amp;#039;&amp;#039;example.com&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   DocumentRoot /var/www/nextcloud &lt;br /&gt;
 &lt;br /&gt;
   &amp;lt;Directory &amp;quot;/var/www/nexcloud&amp;quot;&amp;gt;&lt;br /&gt;
     Options FollowSymLinks MultiViews&lt;br /&gt;
     AllowOverride All&lt;br /&gt;
     Require all granted&lt;br /&gt;
     Satisfy Any &lt;br /&gt;
     SetEnv HOME /var/www/nextcloud&lt;br /&gt;
     SetEnv HTTP_HOME /var/www/nextcloud&lt;br /&gt;
 &lt;br /&gt;
     &amp;lt;IfModule mod_dav.c&amp;gt;&lt;br /&gt;
       Dav off&lt;br /&gt;
     &amp;lt;/IfModule&amp;gt;&lt;br /&gt;
   &amp;lt;/Directory&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
   SSLEngine On&lt;br /&gt;
   SSLCertificateFile ...&lt;br /&gt;
 &amp;lt;/VirtualHost&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== PHP settings ===&lt;br /&gt;
&lt;br /&gt;
Enable the opcache, increase the memory limit, and increase the maximum POST and file upload size so you can upload large files.&lt;br /&gt;
&lt;br /&gt;
== Create a database ==&lt;br /&gt;
&lt;br /&gt;
Create a database in [[PostgreSQL]]:&lt;br /&gt;
&lt;br /&gt;
 sudo -u postgres createuser -SDRP &amp;#039;&amp;#039;&amp;lt;nextcloud-user&amp;gt;&amp;#039;&amp;#039;&lt;br /&gt;
 sudo -u postgres createdb -E UTF8 -O &amp;#039;&amp;#039;&amp;lt;nextcloud-user&amp;gt;&amp;#039;&amp;#039; &amp;#039;&amp;#039;&amp;lt;nextcloud-dbname&amp;gt;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
== Install NextCloud ==&lt;br /&gt;
&lt;br /&gt;
We can just clone it from git:&lt;br /&gt;
&lt;br /&gt;
 git clone &amp;lt;nowiki&amp;gt;https://&amp;lt;/nowiki&amp;gt;github.com/nextcloud/server.git nextcloud&lt;br /&gt;
 cd nextcloud&lt;br /&gt;
 git checkout stable20  &amp;#039;&amp;#039;# or whatever the latest stable version is&amp;#039;&amp;#039;&lt;br /&gt;
 git submodule update --init --recursive&lt;br /&gt;
 chown www-data:www-data config apps .htaccess&lt;br /&gt;
&lt;br /&gt;
Create a directory for the cache and user data, which should not reside under the web root:&lt;br /&gt;
&lt;br /&gt;
 mkdir -p /var/lib/nextcloud/data /var/cache/nextcloud&lt;br /&gt;
 chown -R www-data:www-data /var/lib/nextcloud /var/cache/nextcloud&lt;br /&gt;
&lt;br /&gt;
== Configure NextCloud ==&lt;br /&gt;
&lt;br /&gt;
Edit the configuration file in {{code|config/config.php}} and check or consider these settings, and add the database and SMTP connection details:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
 $config =&amp;gt; [&lt;br /&gt;
   # ...&lt;br /&gt;
   #&lt;br /&gt;
   &amp;#039;passwordsalt&amp;#039; =&amp;gt; &amp;quot;&amp;#039;&amp;#039;&amp;lt;very long random string&amp;gt;&amp;#039;&amp;#039;&amp;quot;,&lt;br /&gt;
   &amp;#039;secret&amp;#039; =&amp;gt; &amp;quot;&amp;#039;&amp;#039;&amp;lt;a different very long random string&amp;gt;&amp;#039;&amp;#039;&amp;quot;,&lt;br /&gt;
   &amp;#039;trusted_domains&amp;#039; =&amp;gt; [&lt;br /&gt;
     0 =&amp;gt; &amp;quot;cloud.&amp;#039;&amp;#039;&amp;#039;example.com&amp;#039;&amp;#039;&amp;#039;&amp;quot;,&lt;br /&gt;
   ],&lt;br /&gt;
   &amp;#039;datadirectory&amp;#039; =&amp;gt; &amp;#039;/var/lib/nextcloud/data&amp;#039;,&lt;br /&gt;
   &amp;#039;overwrite.cli.url&amp;#039; =&amp;gt; &amp;#039;&amp;lt;nowiki&amp;gt;https://&amp;lt;/nowiki&amp;gt;cloud.&amp;#039;&amp;#039;&amp;#039;example.com&amp;#039;&amp;#039;&amp;#039;/&amp;#039;,&lt;br /&gt;
   &amp;#039;htaccess.RewriteBase&amp;#039; =&amp;gt; &amp;#039;/&amp;#039;,&lt;br /&gt;
 &lt;br /&gt;
   # Database connection details&lt;br /&gt;
   &amp;#039;dbtype&amp;#039; =&amp;gt; &amp;#039;pgsql&amp;#039;,&lt;br /&gt;
   &amp;#039;dbhost&amp;#039; =&amp;gt; &amp;#039;localhost&amp;#039;,&lt;br /&gt;
   &amp;#039;dbuser&amp;#039; =&amp;gt; &amp;quot;&amp;#039;&amp;#039;&amp;lt;nextcloud-dbuser&amp;gt;&amp;#039;&amp;#039;&amp;quot;,&lt;br /&gt;
   &amp;#039;dbpassword&amp;#039; =&amp;gt; &amp;quot;&amp;#039;&amp;#039;&amp;lt;password&amp;gt;&amp;#039;&amp;#039;&amp;quot;,&lt;br /&gt;
   &amp;#039;dbname&amp;#039; =&amp;gt; &amp;quot;&amp;#039;&amp;#039;&amp;lt;nextcloud-dbname&amp;gt;&amp;#039;&amp;#039;&amp;quot;,&lt;br /&gt;
   &amp;#039;dbtableprefix&amp;#039; =&amp;gt; &amp;#039;oc_&amp;#039;,&lt;br /&gt;
 &lt;br /&gt;
   # Force all URLs to use SSL or it may trip up things like OAuth&lt;br /&gt;
   &amp;#039;overwriteprotocol&amp;#039; =&amp;gt; &amp;#039;https&amp;#039;,&lt;br /&gt;
 &lt;br /&gt;
   # Use Redis and caching to make everything go faster&lt;br /&gt;
   &amp;#039;memcache.local&amp;#039; =&amp;gt; &amp;#039;\\OC\\Memcache\\Redis&amp;#039;,&lt;br /&gt;
   &amp;#039;memcache.locking&amp;#039; =&amp;gt; &amp;#039;\\OC\\Memcache\\Redis&amp;#039;,&lt;br /&gt;
   &amp;#039;redis&amp;#039; =&amp;gt; [&lt;br /&gt;
     &amp;#039;host&amp;#039; =&amp;gt; &amp;#039;localhost&amp;#039;,&lt;br /&gt;
     &amp;#039;port&amp;#039; =&amp;gt; 6379,&lt;br /&gt;
   ],&lt;br /&gt;
   &amp;#039;cache_path&amp;#039; =&amp;gt; &amp;#039;/var/cache/nextcloud&amp;#039;,&lt;br /&gt;
 &lt;br /&gt;
   # Send email details&lt;br /&gt;
   &amp;#039;mail_smtpmode&amp;#039; =&amp;gt; &amp;#039;smtp&amp;#039;,&lt;br /&gt;
   &amp;#039;mail_smtpsecure&amp;#039; =&amp;gt; &amp;#039;tls&amp;#039;,&lt;br /&gt;
   &amp;#039;mail_sendmailmode&amp;#039; =&amp;gt; &amp;#039;smtp&amp;#039;,&lt;br /&gt;
   &amp;#039;mail_from_address&amp;#039; =&amp;gt; &amp;quot;nexcloud@&amp;#039;&amp;#039;&amp;#039;example.com&amp;#039;&amp;#039;&amp;#039;&amp;quot;,&lt;br /&gt;
   &amp;#039;mail_domain&amp;#039; =&amp;gt; &amp;quot;&amp;#039;&amp;#039;&amp;#039;example.com&amp;#039;&amp;#039;&amp;#039;&amp;quot;,&lt;br /&gt;
   &amp;#039;mail_smtpauthtype&amp;#039; =&amp;gt; &amp;#039;PLAIN&amp;#039;,&lt;br /&gt;
   &amp;#039;mail_smtpauth&amp;#039; =&amp;gt; 1,&lt;br /&gt;
   &amp;#039;mail_smtphost&amp;#039; =&amp;gt; &amp;quot;mail.&amp;#039;&amp;#039;&amp;#039;example.com&amp;#039;&amp;#039;&amp;#039;&amp;quot;,&lt;br /&gt;
   &amp;#039;mail_smtpport&amp;#039; =&amp;gt; 587,&lt;br /&gt;
   &amp;#039;mail_smtpname&amp;#039; =&amp;gt; &amp;quot;&amp;#039;&amp;#039;&amp;lt;emailuser&amp;gt;&amp;#039;&amp;#039;&amp;quot;,&lt;br /&gt;
   &amp;#039;mail_smtppassword&amp;#039; =&amp;gt; &amp;quot;&amp;#039;&amp;#039;&amp;lt;emailpassword&amp;gt;&amp;#039;&amp;#039;&amp;quot;,&lt;br /&gt;
 &lt;br /&gt;
   # ...&lt;br /&gt;
 ]  &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then navigate to the URL in the browser to install (or run the NextCloud {{code | ./occ}} tool from the command line).&lt;br /&gt;
&lt;br /&gt;
=== Clean URLs ===&lt;br /&gt;
&lt;br /&gt;
For clean URLs, make sure {{code | AllowOverride All}} is set for the parent directory; the {{code | /var/www}} definition is in the main {{code | /etc/apache2/apache.conf}}. Then run the follwing OCC command to enable the rewrite rules:&lt;br /&gt;
&lt;br /&gt;
 sudo -u www-data ./occ maintenance:update:htaccess&lt;br /&gt;
&lt;br /&gt;
=== Previews of other file types ===&lt;br /&gt;
&lt;br /&gt;
Edit {{code|/etc/ImageMagick/policy.xml}} and remove this line to get PDF previews to work:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;policy domain=&amp;quot;coder&amp;quot; rights=&amp;quot;none&amp;quot; pattern=&amp;quot;PDF&amp;quot; /&amp;gt; &amp;lt;!-- remove this line --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then add the following to {{code|config.php}} to get lots of other useful file previews:&lt;br /&gt;
   &amp;#039;enabledPreviewProviders&amp;#039; =&amp;gt; [&lt;br /&gt;
     # ...&lt;br /&gt;
     8 =&amp;gt; &amp;#039;OC\\Preview\\MarkDown&amp;#039;,&lt;br /&gt;
     9 =&amp;gt; &amp;#039;OC\\Preview\\Movie&amp;#039;,&lt;br /&gt;
     10 =&amp;gt; &amp;#039;OC\\Preview\\PDF&amp;#039;,&lt;br /&gt;
     11 =&amp;gt; &amp;#039;OC\\Preview\\OpenDocument&amp;#039;,&lt;br /&gt;
     12 =&amp;gt; &amp;#039;OC\\Preview\\MSOfficeDoc&amp;#039;,&lt;br /&gt;
     13 =&amp;gt; &amp;#039;OC\\Preview\\MSOffice2003&amp;#039;,&lt;br /&gt;
     14 =&amp;gt; &amp;#039;OC\\Preview\\MSOffice2007&amp;#039;,&lt;br /&gt;
   ],&lt;br /&gt;
&lt;br /&gt;
=== Photos ===&lt;br /&gt;
&lt;br /&gt;
Photos replaces the Gallery app, and is installed separately through the NC store or you can use git to manage it as a submodule. If it doesn&amp;#039;t work you might need to build its JavaScript resources by running {{code|make}} in its {{code|apps/photos}} directory. Alternatively you can resuscitate the Gallery app, which stopped working after NextCloud version 17, by updating its JavaScript dompurify library to a [https://raw.githubusercontent.com/nextcloud/gallery/ecb26a812f30a3f516964808ccfa6430be09b45e/js/vendor/dompurify/src/purify.js newer version] and bumping the app max version in {{code|apps/galleryappinfo/info.xml}} as follows (See also [https://github.com/nextcloud/gallery/pull/570/ pull request #570]):&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nextcloud min-version=&amp;quot;17&amp;quot; max-version=&amp;quot;&amp;#039;&amp;#039;&amp;#039;20&amp;#039;&amp;#039;&amp;#039;&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== NextCloud Talk ===&lt;br /&gt;
&lt;br /&gt;
To be at all useful, you need a TURN server. This is easiest achieved by installing and correctly configuring coturn, which also acts as a STUN server. STUN is for clients to figure out their external IP address, and TURN is for relaying UDP packets, e.g. for WebRTC.&lt;br /&gt;
&lt;br /&gt;
 sudo apt install coturn&lt;br /&gt;
&lt;br /&gt;
For it to actually do anything (it is disabled by default!) you need to edit {{code|/etc/default/coturn}} and make sure it contains the following, and is not commented out:&lt;br /&gt;
&lt;br /&gt;
 TURNSERVER_ENABLED=1&lt;br /&gt;
&lt;br /&gt;
Then in {{code|/etc/turnserver.conf}} you need to configure its domain name, IP addresses and ports, SSL certificate, and how TURN authenticates. See GitHub for a fully documented example [https://github.com/coturn/coturn/blob/master/examples/etc/turnserver.conf turnserver.conf] file. This example uses the same domain as the NextCloud instance, on the standard STUN and TURN ports, but if you want to host it on port 443 to support people behind restrictive firewalls, you will need a different subdomain and/or IP address:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;ini&amp;quot;&amp;gt;&lt;br /&gt;
 server-name=cloud.example.com&lt;br /&gt;
 realm=cloud.example.com&lt;br /&gt;
 &lt;br /&gt;
 # When hosted on an internal LAN or DMZ, it might look like this: &lt;br /&gt;
 listening-ip=192.168.1.100&lt;br /&gt;
 relay-ip=192.168.1.100&lt;br /&gt;
 external-ip=123.45.67.8&lt;br /&gt;
 &lt;br /&gt;
 # Or use the short-hand:&lt;br /&gt;
 external-ip=123.45.67.8/192.168.1.100&lt;br /&gt;
 &lt;br /&gt;
 # Specify listening ports; originally 3478 was unencrypted, and 5349 was TLS,&lt;br /&gt;
 # but now TLS is supported on both. It is possible to listen on 443, which will&lt;br /&gt;
 # help to provide connectivity for people behind port-limited firewalls; this will&lt;br /&gt;
 # conflict with any HTTPS web hosting on the same server though, unless you set&lt;br /&gt;
 # up a second IP address for it.&lt;br /&gt;
 listening-port=3478&lt;br /&gt;
 tls-listening-port=5349&lt;br /&gt;
 #tls-listening-port=443&lt;br /&gt;
 &lt;br /&gt;
 # Specify a UDP port range and ensure they are exposed through the firewall/router&lt;br /&gt;
 min-port=53490&lt;br /&gt;
 max-port=59999&lt;br /&gt;
 &lt;br /&gt;
 # SSL setup; &lt;br /&gt;
 cert=/path/to/cloud.example.com/fullchain.cert&lt;br /&gt;
 pkey=/path/to/cloud.example.com/privkey.pem&lt;br /&gt;
 no-tlsv1&lt;br /&gt;
 no-tlsv1_1&lt;br /&gt;
 &lt;br /&gt;
 # To use with NextCloud, set a shared secret here.&lt;br /&gt;
 use-auth-secret&lt;br /&gt;
 static-auth-secret=your-shared-secret-string-here&lt;br /&gt;
 stale-nonce=600&lt;br /&gt;
 &lt;br /&gt;
 # Limit STUN amplification/gain attacks (coturn 4.5.2+)&lt;br /&gt;
 no-stun-backward-compatibility&lt;br /&gt;
 response-origin-only-with-rfc5780&lt;br /&gt;
 &lt;br /&gt;
 # RFC-5780 support requires two listening IP addresses and is for serious-cat&lt;br /&gt;
 # usage, so you can safely disable it for a small home NextCloud instance.&lt;br /&gt;
 no-rfc5780&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In your NextCloud Administration section, you can now configure Talk to use the STUN/TURN server, using your server URLs, and provide the same shared secret you configured above. For maximum compatibility, use both UDP and TCP, and both turn and turns (TLS) connections:&lt;br /&gt;
&lt;br /&gt;
 stun: &amp;#039;&amp;#039;&amp;#039;cloud.example.com&amp;#039;&amp;#039;&amp;#039;:5349&lt;br /&gt;
 turn and turns: &amp;#039;&amp;#039;&amp;#039;cloud.example.com&amp;#039;&amp;#039;&amp;#039;:5349&lt;br /&gt;
&lt;br /&gt;
Test your server [https://webrtc.github.io/samples/src/content/peerconnection/trickle-ice/ here]. If STUN is working, you should get {{code|srflx}} candidates, and {{code|relay}} candidates if TURN is working.&lt;br /&gt;
&lt;br /&gt;
Sources and further reading:&lt;br /&gt;
* NextCloud Talk documentation: [https://nextcloud-talk.readthedocs.io/en/latest/TURN/ TURN], [https://nextcloud-talk.readthedocs.io/en/latest/coturn coturn]&lt;br /&gt;
* NextCloud Help, [https://help.nextcloud.com/t/howto-setup-nextcloud-talk-with-turn-server/30794 1] [https://help.nextcloud.com/t/nextcloud-talk-app-could-not-establish-a-connection-a-turn-server/131069/31 2]&lt;br /&gt;
* Stack Overflow [https://stackoverflow.com/questions/42801361/install-rfc5766-turn-server-trying-to-bind-fd-to-ip-address-errno-99 1]&lt;br /&gt;
* [https://ourcodeworld.com/articles/read/1526/how-to-test-online-whether-a-stun-turn-server-is-working-properly-or-not Testing STUN/TURN]&lt;br /&gt;
&lt;br /&gt;
== Maintenance ==&lt;br /&gt;
&lt;br /&gt;
Keep the git checkout of NextCloud and its submodules up to date with git, and run the OCC upgrade command:&lt;br /&gt;
&lt;br /&gt;
 cd /var/www/nextcloud&lt;br /&gt;
 git pull&lt;br /&gt;
 git submodule update --init --recursive&lt;br /&gt;
 sudo -u www-data ./occ upgrade&lt;br /&gt;
&lt;br /&gt;
=== Cron job ===&lt;br /&gt;
&lt;br /&gt;
In the administrator settings select cron rather than other methods, and put this in {{code|/etc/cron.d/nextcloud}}&lt;br /&gt;
&lt;br /&gt;
 */5 * * * * www-data /usr/bin/php /var/www/nextcloud/cron.php&lt;/div&gt;</summary>
		<author><name>Johnno</name></author>
	</entry>
	<entry>
		<id>https://wiki.jon.geek.nz/index.php?title=NextCloud&amp;diff=2499</id>
		<title>NextCloud</title>
		<link rel="alternate" type="text/html" href="https://wiki.jon.geek.nz/index.php?title=NextCloud&amp;diff=2499"/>
		<updated>2023-09-07T20:02:37Z</updated>

		<summary type="html">&lt;p&gt;Johnno: /* NextCloud Talk */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Assumes Ubuntu 20.04, stable20 branch, and installing in {{code|/var/www/nextcloud}} for a cloud.&amp;#039;&amp;#039;&amp;#039;example.com&amp;#039;&amp;#039;&amp;#039; URL (c. December 2020).&lt;br /&gt;
&lt;br /&gt;
== Prerequisites ==&lt;br /&gt;
&lt;br /&gt;
Install some stuff first. This NextCloud recipe uses [[PostgreSQL]], Redis, Apache 2.4, FastCGI with PHP FPM, and Dehydrated for [[Letsencrypt]] SSL certificate maangement.&lt;br /&gt;
&lt;br /&gt;
 sudo apt install apache2 libapache2-mod-fcgid \&lt;br /&gt;
    php7.4-{bcmath,bz2,curl,gd,fpm,gmp,intl,json,mbstring,opcache,pgsql,tidy,xmlrpc,xsl,zip}&lt;br /&gt;
    php-{imagick,redis} composer dehydrated postgresql redis-server&lt;br /&gt;
&lt;br /&gt;
;NOTE: NextCloud works fine under nginx, I just can&amp;#039;t be bothered maintaining what goes in {{code|.htaccess}} which NextCloud expects to be writeable to keep itself updated.&lt;br /&gt;
&lt;br /&gt;
== Configuring Apache and PHP ==&lt;br /&gt;
&lt;br /&gt;
: &amp;#039;&amp;#039;See the [[PHP]] page for setting up PHP with Apache, FPM and Event MPM.&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
=== Add a virtual host for NextCloud ===&lt;br /&gt;
&lt;br /&gt;
It should look something like this:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;VirtualHost *:443&amp;gt;&lt;br /&gt;
   ServerName cloud.&amp;#039;&amp;#039;&amp;#039;example.com&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   DocumentRoot /var/www/nextcloud &lt;br /&gt;
 &lt;br /&gt;
   &amp;lt;Directory &amp;quot;/var/www/nexcloud&amp;quot;&amp;gt;&lt;br /&gt;
     Options FollowSymLinks MultiViews&lt;br /&gt;
     AllowOverride All&lt;br /&gt;
     Require all granted&lt;br /&gt;
     Satisfy Any &lt;br /&gt;
     SetEnv HOME /var/www/nextcloud&lt;br /&gt;
     SetEnv HTTP_HOME /var/www/nextcloud&lt;br /&gt;
 &lt;br /&gt;
     &amp;lt;IfModule mod_dav.c&amp;gt;&lt;br /&gt;
       Dav off&lt;br /&gt;
     &amp;lt;/IfModule&amp;gt;&lt;br /&gt;
   &amp;lt;/Directory&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
   SSLEngine On&lt;br /&gt;
   SSLCertificateFile ...&lt;br /&gt;
 &amp;lt;/VirtualHost&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== PHP settings ===&lt;br /&gt;
&lt;br /&gt;
Enable the opcache, increase the memory limit, and increase the maximum POST and file upload size so you can upload large files.&lt;br /&gt;
&lt;br /&gt;
== Create a database ==&lt;br /&gt;
&lt;br /&gt;
Create a database in [[PostgreSQL]]:&lt;br /&gt;
&lt;br /&gt;
 sudo -u postgres createuser -SDRP &amp;#039;&amp;#039;&amp;lt;nextcloud-user&amp;gt;&amp;#039;&amp;#039;&lt;br /&gt;
 sudo -u postgres createdb -E UTF8 -O &amp;#039;&amp;#039;&amp;lt;nextcloud-user&amp;gt;&amp;#039;&amp;#039; &amp;#039;&amp;#039;&amp;lt;nextcloud-dbname&amp;gt;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
== Install NextCloud ==&lt;br /&gt;
&lt;br /&gt;
We can just clone it from git:&lt;br /&gt;
&lt;br /&gt;
 git clone &amp;lt;nowiki&amp;gt;https://&amp;lt;/nowiki&amp;gt;github.com/nextcloud/server.git nextcloud&lt;br /&gt;
 cd nextcloud&lt;br /&gt;
 git checkout stable20  &amp;#039;&amp;#039;# or whatever the latest stable version is&amp;#039;&amp;#039;&lt;br /&gt;
 git submodule update --init --recursive&lt;br /&gt;
 chown www-data:www-data config apps .htaccess&lt;br /&gt;
&lt;br /&gt;
Create a directory for the cache and user data, which should not reside under the web root:&lt;br /&gt;
&lt;br /&gt;
 mkdir -p /var/lib/nextcloud/data /var/cache/nextcloud&lt;br /&gt;
 chown -R www-data:www-data /var/lib/nextcloud /var/cache/nextcloud&lt;br /&gt;
&lt;br /&gt;
== Configure NextCloud ==&lt;br /&gt;
&lt;br /&gt;
Edit the configuration file in {{code|config/config.php}} and check or consider these settings, and add the database and SMTP connection details:&lt;br /&gt;
&lt;br /&gt;
 $config =&amp;gt; [&lt;br /&gt;
   # ...&lt;br /&gt;
   #&lt;br /&gt;
   &amp;#039;passwordsalt&amp;#039; =&amp;gt; &amp;quot;&amp;#039;&amp;#039;&amp;lt;very long random string&amp;gt;&amp;#039;&amp;#039;&amp;quot;,&lt;br /&gt;
   &amp;#039;secret&amp;#039; =&amp;gt; &amp;quot;&amp;#039;&amp;#039;&amp;lt;a different very long random string&amp;gt;&amp;#039;&amp;#039;&amp;quot;,&lt;br /&gt;
   &amp;#039;trusted_domains&amp;#039; =&amp;gt; [&lt;br /&gt;
     0 =&amp;gt; &amp;quot;cloud.&amp;#039;&amp;#039;&amp;#039;example.com&amp;#039;&amp;#039;&amp;#039;&amp;quot;,&lt;br /&gt;
   ],&lt;br /&gt;
   &amp;#039;datadirectory&amp;#039; =&amp;gt; &amp;#039;/var/lib/nextcloud/data&amp;#039;,&lt;br /&gt;
   &amp;#039;overwrite.cli.url&amp;#039; =&amp;gt; &amp;#039;&amp;lt;nowiki&amp;gt;https://&amp;lt;/nowiki&amp;gt;cloud.&amp;#039;&amp;#039;&amp;#039;example.com&amp;#039;&amp;#039;&amp;#039;/&amp;#039;,&lt;br /&gt;
   &amp;#039;htaccess.RewriteBase&amp;#039; =&amp;gt; &amp;#039;/&amp;#039;,&lt;br /&gt;
 &lt;br /&gt;
   # Database connection details&lt;br /&gt;
   &amp;#039;dbtype&amp;#039; =&amp;gt; &amp;#039;pgsql&amp;#039;,&lt;br /&gt;
   &amp;#039;dbhost&amp;#039; =&amp;gt; &amp;#039;localhost&amp;#039;,&lt;br /&gt;
   &amp;#039;dbuser&amp;#039; =&amp;gt; &amp;quot;&amp;#039;&amp;#039;&amp;lt;nextcloud-dbuser&amp;gt;&amp;#039;&amp;#039;&amp;quot;,&lt;br /&gt;
   &amp;#039;dbpassword&amp;#039; =&amp;gt; &amp;quot;&amp;#039;&amp;#039;&amp;lt;password&amp;gt;&amp;#039;&amp;#039;&amp;quot;,&lt;br /&gt;
   &amp;#039;dbname&amp;#039; =&amp;gt; &amp;quot;&amp;#039;&amp;#039;&amp;lt;nextcloud-dbname&amp;gt;&amp;#039;&amp;#039;&amp;quot;,&lt;br /&gt;
   &amp;#039;dbtableprefix&amp;#039; =&amp;gt; &amp;#039;oc_&amp;#039;,&lt;br /&gt;
 &lt;br /&gt;
   # Force all URLs to use SSL or it may trip up things like OAuth&lt;br /&gt;
   &amp;#039;overwriteprotocol&amp;#039; =&amp;gt; &amp;#039;https&amp;#039;,&lt;br /&gt;
 &lt;br /&gt;
   # Use Redis and caching to make everything go faster&lt;br /&gt;
   &amp;#039;memcache.local&amp;#039; =&amp;gt; &amp;#039;\\OC\\Memcache\\Redis&amp;#039;,&lt;br /&gt;
   &amp;#039;memcache.locking&amp;#039; =&amp;gt; &amp;#039;\\OC\\Memcache\\Redis&amp;#039;,&lt;br /&gt;
   &amp;#039;redis&amp;#039; =&amp;gt; [&lt;br /&gt;
     &amp;#039;host&amp;#039; =&amp;gt; &amp;#039;localhost&amp;#039;,&lt;br /&gt;
     &amp;#039;port&amp;#039; =&amp;gt; 6379,&lt;br /&gt;
   ],&lt;br /&gt;
   &amp;#039;cache_path&amp;#039; =&amp;gt; &amp;#039;/var/cache/nextcloud&amp;#039;,&lt;br /&gt;
 &lt;br /&gt;
   # Send email details&lt;br /&gt;
   &amp;#039;mail_smtpmode&amp;#039; =&amp;gt; &amp;#039;smtp&amp;#039;,&lt;br /&gt;
   &amp;#039;mail_smtpsecure&amp;#039; =&amp;gt; &amp;#039;tls&amp;#039;,&lt;br /&gt;
   &amp;#039;mail_sendmailmode&amp;#039; =&amp;gt; &amp;#039;smtp&amp;#039;,&lt;br /&gt;
   &amp;#039;mail_from_address&amp;#039; =&amp;gt; &amp;quot;nexcloud@&amp;#039;&amp;#039;&amp;#039;example.com&amp;#039;&amp;#039;&amp;#039;&amp;quot;,&lt;br /&gt;
   &amp;#039;mail_domain&amp;#039; =&amp;gt; &amp;quot;&amp;#039;&amp;#039;&amp;#039;example.com&amp;#039;&amp;#039;&amp;#039;&amp;quot;,&lt;br /&gt;
   &amp;#039;mail_smtpauthtype&amp;#039; =&amp;gt; &amp;#039;PLAIN&amp;#039;,&lt;br /&gt;
   &amp;#039;mail_smtpauth&amp;#039; =&amp;gt; 1,&lt;br /&gt;
   &amp;#039;mail_smtphost&amp;#039; =&amp;gt; &amp;quot;mail.&amp;#039;&amp;#039;&amp;#039;example.com&amp;#039;&amp;#039;&amp;#039;&amp;quot;,&lt;br /&gt;
   &amp;#039;mail_smtpport&amp;#039; =&amp;gt; 587,&lt;br /&gt;
   &amp;#039;mail_smtpname&amp;#039; =&amp;gt; &amp;quot;&amp;#039;&amp;#039;&amp;lt;emailuser&amp;gt;&amp;#039;&amp;#039;&amp;quot;,&lt;br /&gt;
   &amp;#039;mail_smtppassword&amp;#039; =&amp;gt; &amp;quot;&amp;#039;&amp;#039;&amp;lt;emailpassword&amp;gt;&amp;#039;&amp;#039;&amp;quot;,&lt;br /&gt;
&lt;br /&gt;
Then navigate to the URL in the browser to install (or run the NextCloud {{code | ./occ}} tool from the command line).&lt;br /&gt;
&lt;br /&gt;
=== Clean URLs ===&lt;br /&gt;
&lt;br /&gt;
For clean URLs, make sure {{code | AllowOverride All}} is set for the parent directory; the {{code | /var/www}} definition is in the main {{code | /etc/apache2/apache.conf}}. Then run the follwing OCC command to enable the rewrite rules:&lt;br /&gt;
&lt;br /&gt;
 sudo -u www-data ./occ maintenance:update:htaccess&lt;br /&gt;
&lt;br /&gt;
=== Previews of other file types ===&lt;br /&gt;
&lt;br /&gt;
Edit {{code|/etc/ImageMagick/policy.xml}} and remove this line to get PDF previews to work:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;policy domain=&amp;quot;coder&amp;quot; rights=&amp;quot;none&amp;quot; pattern=&amp;quot;PDF&amp;quot; /&amp;gt; &amp;lt;!-- remove this line --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then add the following to {{code|config.php}} to get lots of other useful file previews:&lt;br /&gt;
   &amp;#039;enabledPreviewProviders&amp;#039; =&amp;gt; [&lt;br /&gt;
     # ...&lt;br /&gt;
     8 =&amp;gt; &amp;#039;OC\\Preview\\MarkDown&amp;#039;,&lt;br /&gt;
     9 =&amp;gt; &amp;#039;OC\\Preview\\Movie&amp;#039;,&lt;br /&gt;
     10 =&amp;gt; &amp;#039;OC\\Preview\\PDF&amp;#039;,&lt;br /&gt;
     11 =&amp;gt; &amp;#039;OC\\Preview\\OpenDocument&amp;#039;,&lt;br /&gt;
     12 =&amp;gt; &amp;#039;OC\\Preview\\MSOfficeDoc&amp;#039;,&lt;br /&gt;
     13 =&amp;gt; &amp;#039;OC\\Preview\\MSOffice2003&amp;#039;,&lt;br /&gt;
     14 =&amp;gt; &amp;#039;OC\\Preview\\MSOffice2007&amp;#039;,&lt;br /&gt;
   ],&lt;br /&gt;
&lt;br /&gt;
=== Photos ===&lt;br /&gt;
&lt;br /&gt;
Photos replaces the Gallery app, and is installed separately through the NC store or you can use git to manage it as a submodule. If it doesn&amp;#039;t work you might need to build its JavaScript resources by running {{code|make}} in its {{code|apps/photos}} directory. Alternatively you can resuscitate the Gallery app, which stopped working after NextCloud version 17, by updating its JavaScript dompurify library to a [https://raw.githubusercontent.com/nextcloud/gallery/ecb26a812f30a3f516964808ccfa6430be09b45e/js/vendor/dompurify/src/purify.js newer version] and bumping the app max version in {{code|apps/galleryappinfo/info.xml}} as follows (See also [https://github.com/nextcloud/gallery/pull/570/ pull request #570]):&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nextcloud min-version=&amp;quot;17&amp;quot; max-version=&amp;quot;&amp;#039;&amp;#039;&amp;#039;20&amp;#039;&amp;#039;&amp;#039;&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== NextCloud Talk ===&lt;br /&gt;
&lt;br /&gt;
To be at all useful, you need a TURN server. This is easiest achieved by installing and correctly configuring coturn, which also acts as a STUN server. STUN is for clients to figure out their external IP address, and TURN is for relaying UDP packets, e.g. for WebRTC.&lt;br /&gt;
&lt;br /&gt;
 sudo apt install coturn&lt;br /&gt;
&lt;br /&gt;
For it to actually do anything (it is disabled by default!) you need to edit {{code|/etc/default/coturn}} and make sure it contains the following, and is not commented out:&lt;br /&gt;
&lt;br /&gt;
 TURNSERVER_ENABLED=1&lt;br /&gt;
&lt;br /&gt;
Then in {{code|/etc/turnserver.conf}} you need to configure its domain name, IP addresses and ports, SSL certificate, and how TURN authenticates. See GitHub for a fully documented example [https://github.com/coturn/coturn/blob/master/examples/etc/turnserver.conf turnserver.conf] file. This example uses the same domain as the NextCloud instance, on the standard STUN and TURN ports, but if you want to host it on port 443 to support people behind restrictive firewalls, you will need a different subdomain and/or IP address:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;ini&amp;quot;&amp;gt;&lt;br /&gt;
 server-name=cloud.example.com&lt;br /&gt;
 realm=cloud.example.com&lt;br /&gt;
 &lt;br /&gt;
 # When hosted on an internal LAN or DMZ, it might look like this: &lt;br /&gt;
 listening-ip=192.168.1.100&lt;br /&gt;
 relay-ip=192.168.1.100&lt;br /&gt;
 external-ip=123.45.67.8&lt;br /&gt;
 &lt;br /&gt;
 # Or use the short-hand:&lt;br /&gt;
 external-ip=123.45.67.8/192.168.1.100&lt;br /&gt;
 &lt;br /&gt;
 # Specify listening ports; originally 3478 was unencrypted, and 5349 was TLS,&lt;br /&gt;
 # but now TLS is supported on both. It is possible to listen on 443, which will&lt;br /&gt;
 # help to provide connectivity for people behind port-limited firewalls; this will&lt;br /&gt;
 # conflict with any HTTPS web hosting on the same server though, unless you set&lt;br /&gt;
 # up a second IP address for it.&lt;br /&gt;
 listening-port=3478&lt;br /&gt;
 tls-listening-port=5349&lt;br /&gt;
 #tls-listening-port=443&lt;br /&gt;
 &lt;br /&gt;
 # Specify a UDP port range and ensure they are exposed through the firewall/router&lt;br /&gt;
 min-port=53490&lt;br /&gt;
 max-port=59999&lt;br /&gt;
 &lt;br /&gt;
 # SSL setup; &lt;br /&gt;
 cert=/path/to/cloud.example.com/fullchain.cert&lt;br /&gt;
 pkey=/path/to/cloud.example.com/privkey.pem&lt;br /&gt;
 no-tlsv1&lt;br /&gt;
 no-tlsv1_1&lt;br /&gt;
 &lt;br /&gt;
 # To use with NextCloud, set a shared secret here.&lt;br /&gt;
 use-auth-secret&lt;br /&gt;
 static-auth-secret=your-shared-secret-string-here&lt;br /&gt;
 stale-nonce=600&lt;br /&gt;
 &lt;br /&gt;
 # Limit STUN amplification/gain attacks (coturn 4.5.2+)&lt;br /&gt;
 no-stun-backward-compatibility&lt;br /&gt;
 response-origin-only-with-rfc5780&lt;br /&gt;
 &lt;br /&gt;
 # RFC-5780 support requires two listening IP addresses and is for serious-cat&lt;br /&gt;
 # usage, so you can safely disable it for a small home NextCloud instance.&lt;br /&gt;
 no-rfc5780&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In your NextCloud Administration section, you can now configure Talk to use the STUN/TURN server, using your server URLs, and provide the same shared secret you configured above. For maximum compatibility, use both UDP and TCP, and both turn and turns (TLS) connections:&lt;br /&gt;
&lt;br /&gt;
 stun: &amp;#039;&amp;#039;&amp;#039;cloud.example.com&amp;#039;&amp;#039;&amp;#039;:5349&lt;br /&gt;
 turn and turns: &amp;#039;&amp;#039;&amp;#039;cloud.example.com&amp;#039;&amp;#039;&amp;#039;:5349&lt;br /&gt;
&lt;br /&gt;
Test your server [https://webrtc.github.io/samples/src/content/peerconnection/trickle-ice/ here]. If STUN is working, you should get {{code|srflx}} candidates, and {{code|relay}} candidates if TURN is working.&lt;br /&gt;
&lt;br /&gt;
Sources and further reading:&lt;br /&gt;
* NextCloud Talk documentation: [https://nextcloud-talk.readthedocs.io/en/latest/TURN/ TURN], [https://nextcloud-talk.readthedocs.io/en/latest/coturn coturn]&lt;br /&gt;
* NextCloud Help, [https://help.nextcloud.com/t/howto-setup-nextcloud-talk-with-turn-server/30794 1] [https://help.nextcloud.com/t/nextcloud-talk-app-could-not-establish-a-connection-a-turn-server/131069/31 2]&lt;br /&gt;
* Stack Overflow [https://stackoverflow.com/questions/42801361/install-rfc5766-turn-server-trying-to-bind-fd-to-ip-address-errno-99 1]&lt;br /&gt;
* [https://ourcodeworld.com/articles/read/1526/how-to-test-online-whether-a-stun-turn-server-is-working-properly-or-not Testing STUN/TURN]&lt;br /&gt;
&lt;br /&gt;
== Maintenance ==&lt;br /&gt;
&lt;br /&gt;
Keep the git checkout of NextCloud and its submodules up to date with git, and run the OCC upgrade command:&lt;br /&gt;
&lt;br /&gt;
 cd /var/www/nextcloud&lt;br /&gt;
 git pull&lt;br /&gt;
 git submodule update --init --recursive&lt;br /&gt;
 sudo -u www-data ./occ upgrade&lt;br /&gt;
&lt;br /&gt;
=== Cron job ===&lt;br /&gt;
&lt;br /&gt;
In the administrator settings select cron rather than other methods, and put this in {{code|/etc/cron.d/nextcloud}}&lt;br /&gt;
&lt;br /&gt;
 */5 * * * * www-data /usr/bin/php /var/www/nextcloud/cron.php&lt;/div&gt;</summary>
		<author><name>Johnno</name></author>
	</entry>
	<entry>
		<id>https://wiki.jon.geek.nz/index.php?title=NextCloud&amp;diff=2498</id>
		<title>NextCloud</title>
		<link rel="alternate" type="text/html" href="https://wiki.jon.geek.nz/index.php?title=NextCloud&amp;diff=2498"/>
		<updated>2023-09-07T08:43:42Z</updated>

		<summary type="html">&lt;p&gt;Johnno: /* NextCloud Talk */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Assumes Ubuntu 20.04, stable20 branch, and installing in {{code|/var/www/nextcloud}} for a cloud.&amp;#039;&amp;#039;&amp;#039;example.com&amp;#039;&amp;#039;&amp;#039; URL (c. December 2020).&lt;br /&gt;
&lt;br /&gt;
== Prerequisites ==&lt;br /&gt;
&lt;br /&gt;
Install some stuff first. This NextCloud recipe uses [[PostgreSQL]], Redis, Apache 2.4, FastCGI with PHP FPM, and Dehydrated for [[Letsencrypt]] SSL certificate maangement.&lt;br /&gt;
&lt;br /&gt;
 sudo apt install apache2 libapache2-mod-fcgid \&lt;br /&gt;
    php7.4-{bcmath,bz2,curl,gd,fpm,gmp,intl,json,mbstring,opcache,pgsql,tidy,xmlrpc,xsl,zip}&lt;br /&gt;
    php-{imagick,redis} composer dehydrated postgresql redis-server&lt;br /&gt;
&lt;br /&gt;
;NOTE: NextCloud works fine under nginx, I just can&amp;#039;t be bothered maintaining what goes in {{code|.htaccess}} which NextCloud expects to be writeable to keep itself updated.&lt;br /&gt;
&lt;br /&gt;
== Configuring Apache and PHP ==&lt;br /&gt;
&lt;br /&gt;
: &amp;#039;&amp;#039;See the [[PHP]] page for setting up PHP with Apache, FPM and Event MPM.&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
=== Add a virtual host for NextCloud ===&lt;br /&gt;
&lt;br /&gt;
It should look something like this:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;VirtualHost *:443&amp;gt;&lt;br /&gt;
   ServerName cloud.&amp;#039;&amp;#039;&amp;#039;example.com&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   DocumentRoot /var/www/nextcloud &lt;br /&gt;
 &lt;br /&gt;
   &amp;lt;Directory &amp;quot;/var/www/nexcloud&amp;quot;&amp;gt;&lt;br /&gt;
     Options FollowSymLinks MultiViews&lt;br /&gt;
     AllowOverride All&lt;br /&gt;
     Require all granted&lt;br /&gt;
     Satisfy Any &lt;br /&gt;
     SetEnv HOME /var/www/nextcloud&lt;br /&gt;
     SetEnv HTTP_HOME /var/www/nextcloud&lt;br /&gt;
 &lt;br /&gt;
     &amp;lt;IfModule mod_dav.c&amp;gt;&lt;br /&gt;
       Dav off&lt;br /&gt;
     &amp;lt;/IfModule&amp;gt;&lt;br /&gt;
   &amp;lt;/Directory&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
   SSLEngine On&lt;br /&gt;
   SSLCertificateFile ...&lt;br /&gt;
 &amp;lt;/VirtualHost&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== PHP settings ===&lt;br /&gt;
&lt;br /&gt;
Enable the opcache, increase the memory limit, and increase the maximum POST and file upload size so you can upload large files.&lt;br /&gt;
&lt;br /&gt;
== Create a database ==&lt;br /&gt;
&lt;br /&gt;
Create a database in [[PostgreSQL]]:&lt;br /&gt;
&lt;br /&gt;
 sudo -u postgres createuser -SDRP &amp;#039;&amp;#039;&amp;lt;nextcloud-user&amp;gt;&amp;#039;&amp;#039;&lt;br /&gt;
 sudo -u postgres createdb -E UTF8 -O &amp;#039;&amp;#039;&amp;lt;nextcloud-user&amp;gt;&amp;#039;&amp;#039; &amp;#039;&amp;#039;&amp;lt;nextcloud-dbname&amp;gt;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
== Install NextCloud ==&lt;br /&gt;
&lt;br /&gt;
We can just clone it from git:&lt;br /&gt;
&lt;br /&gt;
 git clone &amp;lt;nowiki&amp;gt;https://&amp;lt;/nowiki&amp;gt;github.com/nextcloud/server.git nextcloud&lt;br /&gt;
 cd nextcloud&lt;br /&gt;
 git checkout stable20  &amp;#039;&amp;#039;# or whatever the latest stable version is&amp;#039;&amp;#039;&lt;br /&gt;
 git submodule update --init --recursive&lt;br /&gt;
 chown www-data:www-data config apps .htaccess&lt;br /&gt;
&lt;br /&gt;
Create a directory for the cache and user data, which should not reside under the web root:&lt;br /&gt;
&lt;br /&gt;
 mkdir -p /var/lib/nextcloud/data /var/cache/nextcloud&lt;br /&gt;
 chown -R www-data:www-data /var/lib/nextcloud /var/cache/nextcloud&lt;br /&gt;
&lt;br /&gt;
== Configure NextCloud ==&lt;br /&gt;
&lt;br /&gt;
Edit the configuration file in {{code|config/config.php}} and check or consider these settings, and add the database and SMTP connection details:&lt;br /&gt;
&lt;br /&gt;
 $config =&amp;gt; [&lt;br /&gt;
   # ...&lt;br /&gt;
   #&lt;br /&gt;
   &amp;#039;passwordsalt&amp;#039; =&amp;gt; &amp;quot;&amp;#039;&amp;#039;&amp;lt;very long random string&amp;gt;&amp;#039;&amp;#039;&amp;quot;,&lt;br /&gt;
   &amp;#039;secret&amp;#039; =&amp;gt; &amp;quot;&amp;#039;&amp;#039;&amp;lt;a different very long random string&amp;gt;&amp;#039;&amp;#039;&amp;quot;,&lt;br /&gt;
   &amp;#039;trusted_domains&amp;#039; =&amp;gt; [&lt;br /&gt;
     0 =&amp;gt; &amp;quot;cloud.&amp;#039;&amp;#039;&amp;#039;example.com&amp;#039;&amp;#039;&amp;#039;&amp;quot;,&lt;br /&gt;
   ],&lt;br /&gt;
   &amp;#039;datadirectory&amp;#039; =&amp;gt; &amp;#039;/var/lib/nextcloud/data&amp;#039;,&lt;br /&gt;
   &amp;#039;overwrite.cli.url&amp;#039; =&amp;gt; &amp;#039;&amp;lt;nowiki&amp;gt;https://&amp;lt;/nowiki&amp;gt;cloud.&amp;#039;&amp;#039;&amp;#039;example.com&amp;#039;&amp;#039;&amp;#039;/&amp;#039;,&lt;br /&gt;
   &amp;#039;htaccess.RewriteBase&amp;#039; =&amp;gt; &amp;#039;/&amp;#039;,&lt;br /&gt;
 &lt;br /&gt;
   # Database connection details&lt;br /&gt;
   &amp;#039;dbtype&amp;#039; =&amp;gt; &amp;#039;pgsql&amp;#039;,&lt;br /&gt;
   &amp;#039;dbhost&amp;#039; =&amp;gt; &amp;#039;localhost&amp;#039;,&lt;br /&gt;
   &amp;#039;dbuser&amp;#039; =&amp;gt; &amp;quot;&amp;#039;&amp;#039;&amp;lt;nextcloud-dbuser&amp;gt;&amp;#039;&amp;#039;&amp;quot;,&lt;br /&gt;
   &amp;#039;dbpassword&amp;#039; =&amp;gt; &amp;quot;&amp;#039;&amp;#039;&amp;lt;password&amp;gt;&amp;#039;&amp;#039;&amp;quot;,&lt;br /&gt;
   &amp;#039;dbname&amp;#039; =&amp;gt; &amp;quot;&amp;#039;&amp;#039;&amp;lt;nextcloud-dbname&amp;gt;&amp;#039;&amp;#039;&amp;quot;,&lt;br /&gt;
   &amp;#039;dbtableprefix&amp;#039; =&amp;gt; &amp;#039;oc_&amp;#039;,&lt;br /&gt;
 &lt;br /&gt;
   # Force all URLs to use SSL or it may trip up things like OAuth&lt;br /&gt;
   &amp;#039;overwriteprotocol&amp;#039; =&amp;gt; &amp;#039;https&amp;#039;,&lt;br /&gt;
 &lt;br /&gt;
   # Use Redis and caching to make everything go faster&lt;br /&gt;
   &amp;#039;memcache.local&amp;#039; =&amp;gt; &amp;#039;\\OC\\Memcache\\Redis&amp;#039;,&lt;br /&gt;
   &amp;#039;memcache.locking&amp;#039; =&amp;gt; &amp;#039;\\OC\\Memcache\\Redis&amp;#039;,&lt;br /&gt;
   &amp;#039;redis&amp;#039; =&amp;gt; [&lt;br /&gt;
     &amp;#039;host&amp;#039; =&amp;gt; &amp;#039;localhost&amp;#039;,&lt;br /&gt;
     &amp;#039;port&amp;#039; =&amp;gt; 6379,&lt;br /&gt;
   ],&lt;br /&gt;
   &amp;#039;cache_path&amp;#039; =&amp;gt; &amp;#039;/var/cache/nextcloud&amp;#039;,&lt;br /&gt;
 &lt;br /&gt;
   # Send email details&lt;br /&gt;
   &amp;#039;mail_smtpmode&amp;#039; =&amp;gt; &amp;#039;smtp&amp;#039;,&lt;br /&gt;
   &amp;#039;mail_smtpsecure&amp;#039; =&amp;gt; &amp;#039;tls&amp;#039;,&lt;br /&gt;
   &amp;#039;mail_sendmailmode&amp;#039; =&amp;gt; &amp;#039;smtp&amp;#039;,&lt;br /&gt;
   &amp;#039;mail_from_address&amp;#039; =&amp;gt; &amp;quot;nexcloud@&amp;#039;&amp;#039;&amp;#039;example.com&amp;#039;&amp;#039;&amp;#039;&amp;quot;,&lt;br /&gt;
   &amp;#039;mail_domain&amp;#039; =&amp;gt; &amp;quot;&amp;#039;&amp;#039;&amp;#039;example.com&amp;#039;&amp;#039;&amp;#039;&amp;quot;,&lt;br /&gt;
   &amp;#039;mail_smtpauthtype&amp;#039; =&amp;gt; &amp;#039;PLAIN&amp;#039;,&lt;br /&gt;
   &amp;#039;mail_smtpauth&amp;#039; =&amp;gt; 1,&lt;br /&gt;
   &amp;#039;mail_smtphost&amp;#039; =&amp;gt; &amp;quot;mail.&amp;#039;&amp;#039;&amp;#039;example.com&amp;#039;&amp;#039;&amp;#039;&amp;quot;,&lt;br /&gt;
   &amp;#039;mail_smtpport&amp;#039; =&amp;gt; 587,&lt;br /&gt;
   &amp;#039;mail_smtpname&amp;#039; =&amp;gt; &amp;quot;&amp;#039;&amp;#039;&amp;lt;emailuser&amp;gt;&amp;#039;&amp;#039;&amp;quot;,&lt;br /&gt;
   &amp;#039;mail_smtppassword&amp;#039; =&amp;gt; &amp;quot;&amp;#039;&amp;#039;&amp;lt;emailpassword&amp;gt;&amp;#039;&amp;#039;&amp;quot;,&lt;br /&gt;
&lt;br /&gt;
Then navigate to the URL in the browser to install (or run the NextCloud {{code | ./occ}} tool from the command line).&lt;br /&gt;
&lt;br /&gt;
=== Clean URLs ===&lt;br /&gt;
&lt;br /&gt;
For clean URLs, make sure {{code | AllowOverride All}} is set for the parent directory; the {{code | /var/www}} definition is in the main {{code | /etc/apache2/apache.conf}}. Then run the follwing OCC command to enable the rewrite rules:&lt;br /&gt;
&lt;br /&gt;
 sudo -u www-data ./occ maintenance:update:htaccess&lt;br /&gt;
&lt;br /&gt;
=== Previews of other file types ===&lt;br /&gt;
&lt;br /&gt;
Edit {{code|/etc/ImageMagick/policy.xml}} and remove this line to get PDF previews to work:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;policy domain=&amp;quot;coder&amp;quot; rights=&amp;quot;none&amp;quot; pattern=&amp;quot;PDF&amp;quot; /&amp;gt; &amp;lt;!-- remove this line --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then add the following to {{code|config.php}} to get lots of other useful file previews:&lt;br /&gt;
   &amp;#039;enabledPreviewProviders&amp;#039; =&amp;gt; [&lt;br /&gt;
     # ...&lt;br /&gt;
     8 =&amp;gt; &amp;#039;OC\\Preview\\MarkDown&amp;#039;,&lt;br /&gt;
     9 =&amp;gt; &amp;#039;OC\\Preview\\Movie&amp;#039;,&lt;br /&gt;
     10 =&amp;gt; &amp;#039;OC\\Preview\\PDF&amp;#039;,&lt;br /&gt;
     11 =&amp;gt; &amp;#039;OC\\Preview\\OpenDocument&amp;#039;,&lt;br /&gt;
     12 =&amp;gt; &amp;#039;OC\\Preview\\MSOfficeDoc&amp;#039;,&lt;br /&gt;
     13 =&amp;gt; &amp;#039;OC\\Preview\\MSOffice2003&amp;#039;,&lt;br /&gt;
     14 =&amp;gt; &amp;#039;OC\\Preview\\MSOffice2007&amp;#039;,&lt;br /&gt;
   ],&lt;br /&gt;
&lt;br /&gt;
=== Photos ===&lt;br /&gt;
&lt;br /&gt;
Photos replaces the Gallery app, and is installed separately through the NC store or you can use git to manage it as a submodule. If it doesn&amp;#039;t work you might need to build its JavaScript resources by running {{code|make}} in its {{code|apps/photos}} directory. Alternatively you can resuscitate the Gallery app, which stopped working after NextCloud version 17, by updating its JavaScript dompurify library to a [https://raw.githubusercontent.com/nextcloud/gallery/ecb26a812f30a3f516964808ccfa6430be09b45e/js/vendor/dompurify/src/purify.js newer version] and bumping the app max version in {{code|apps/galleryappinfo/info.xml}} as follows (See also [https://github.com/nextcloud/gallery/pull/570/ pull request #570]):&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nextcloud min-version=&amp;quot;17&amp;quot; max-version=&amp;quot;&amp;#039;&amp;#039;&amp;#039;20&amp;#039;&amp;#039;&amp;#039;&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== NextCloud Talk ===&lt;br /&gt;
&lt;br /&gt;
To be at all useful, you need a TURN server. This is easiest achieved by installing and correctly configuring coturn, which also acts as a STUN server. STUN is for clients to figure out their external IP address, and TURN is for relaying UDP packets, e.g. for WebRTC.&lt;br /&gt;
&lt;br /&gt;
 sudo apt install coturn&lt;br /&gt;
&lt;br /&gt;
For it to actually do anything (it is disabled by default!) you need to edit {{code|/etc/default/coturn}} and make sure it contains the following, and is not commented out:&lt;br /&gt;
&lt;br /&gt;
 TURNSERVER_ENABLED=1&lt;br /&gt;
&lt;br /&gt;
Then in {{code|/etc/turnserver.conf}} you need to configure its IP addresses and ports, SSL certificate, and how it authenticates. See GitHub for a fully documented example [https://github.com/coturn/coturn/blob/master/examples/etc/turnserver.conf turnserver.conf] file:&lt;br /&gt;
&lt;br /&gt;
 server-name=&amp;#039;&amp;#039;&amp;#039;turn.example.com&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
 realm=&amp;#039;&amp;#039;&amp;#039;turn.example.com&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
 &lt;br /&gt;
 # When hosted on an internal LAN or DMZ, it might look like this: &lt;br /&gt;
 listening-ip=192.168.1.100&lt;br /&gt;
 relay-ip=192.168.1.100&lt;br /&gt;
 external-ip=123.45.67.8&lt;br /&gt;
 &lt;br /&gt;
 # Or use the short-hand:&lt;br /&gt;
 external-ip=123.45.67.8/192.168.1.100&lt;br /&gt;
 &lt;br /&gt;
 # Specify listening ports; traditionally 3478 was unencrypted, and 5349 was TLS,&lt;br /&gt;
 # but now TLS is supported on both. It is possible to listen on 443, which will&lt;br /&gt;
 # likely provide connectivity for people behind port-limited firewalls; this will&lt;br /&gt;
 # conflict with any HTTPS web hosting on the same server though, unless you set&lt;br /&gt;
 # up a second IP address for it.&lt;br /&gt;
 listening-port=3478&lt;br /&gt;
 tls-listening-port=5349&lt;br /&gt;
 #tls-listening-port=443&lt;br /&gt;
 &lt;br /&gt;
 # Specify a UDP port range and ensure they are exposed through the firewall/router&lt;br /&gt;
 min-port=53490&lt;br /&gt;
 max-port=59999&lt;br /&gt;
 &lt;br /&gt;
 # SSL setup; &lt;br /&gt;
 cert=/path/to/talk.example.com/fullchain.cert&lt;br /&gt;
 pkey=/path/to/talk.example.com/privkey.pem&lt;br /&gt;
 no-tlsv1&lt;br /&gt;
 no-tlsv1_1&lt;br /&gt;
 &lt;br /&gt;
 # To use with NextCloud, set a shared secret here.&lt;br /&gt;
 use-auth-secret&lt;br /&gt;
 static-auth-secret=&amp;#039;&amp;#039;&amp;#039;your-shared-secret-string-here&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
 stale-nonce=600&lt;br /&gt;
 &lt;br /&gt;
 # Limit STUN amplification/gain attacks (coturn 4.5.2+)&lt;br /&gt;
 no-stun-backward-compatibility&lt;br /&gt;
 response-origin-only-with-rfc5780&lt;br /&gt;
 &lt;br /&gt;
 # RFC-5780 support requires two listening IP addresses and is for serious-cat&lt;br /&gt;
 # usage, so you can safely disable it for a small home NextCloud instance.&lt;br /&gt;
 no-rfc5780&lt;br /&gt;
&lt;br /&gt;
In your NextCloud Administration section, you can now configure Talk to use the STUN/TURN server, using your server URLs, and provide the same shared secret you configured above. For maximum compatibility, use both UDP and TCP, and both turn and turns (TLS) connections:&lt;br /&gt;
&lt;br /&gt;
 stun: &amp;#039;&amp;#039;&amp;#039;talk.example.com&amp;#039;&amp;#039;&amp;#039;:5349&lt;br /&gt;
 turn and turns: &amp;#039;&amp;#039;&amp;#039;talk.example.com&amp;#039;&amp;#039;&amp;#039;:5349&lt;br /&gt;
&lt;br /&gt;
Test your server [https://webrtc.github.io/samples/src/content/peerconnection/trickle-ice/ here]. If STUN is working, you should get {{code|srflx}} candidates, and {{code|relay}} candidates if TURN is working.&lt;br /&gt;
&lt;br /&gt;
Sources and further reading:&lt;br /&gt;
* NextCloud Talk documentation: [https://nextcloud-talk.readthedocs.io/en/latest/TURN/ TURN], [https://nextcloud-talk.readthedocs.io/en/latest/coturn coturn]&lt;br /&gt;
* NextCloud Help, [https://help.nextcloud.com/t/howto-setup-nextcloud-talk-with-turn-server/30794 1] [https://help.nextcloud.com/t/nextcloud-talk-app-could-not-establish-a-connection-a-turn-server/131069/31 2]&lt;br /&gt;
* Stack Overflow [https://stackoverflow.com/questions/42801361/install-rfc5766-turn-server-trying-to-bind-fd-to-ip-address-errno-99 1]&lt;br /&gt;
* [https://ourcodeworld.com/articles/read/1526/how-to-test-online-whether-a-stun-turn-server-is-working-properly-or-not Testing STUN/TURN]&lt;br /&gt;
&lt;br /&gt;
== Maintenance ==&lt;br /&gt;
&lt;br /&gt;
Keep the git checkout of NextCloud and its submodules up to date with git, and run the OCC upgrade command:&lt;br /&gt;
&lt;br /&gt;
 cd /var/www/nextcloud&lt;br /&gt;
 git pull&lt;br /&gt;
 git submodule update --init --recursive&lt;br /&gt;
 sudo -u www-data ./occ upgrade&lt;br /&gt;
&lt;br /&gt;
=== Cron job ===&lt;br /&gt;
&lt;br /&gt;
In the administrator settings select cron rather than other methods, and put this in {{code|/etc/cron.d/nextcloud}}&lt;br /&gt;
&lt;br /&gt;
 */5 * * * * www-data /usr/bin/php /var/www/nextcloud/cron.php&lt;/div&gt;</summary>
		<author><name>Johnno</name></author>
	</entry>
	<entry>
		<id>https://wiki.jon.geek.nz/index.php?title=NextCloud&amp;diff=2497</id>
		<title>NextCloud</title>
		<link rel="alternate" type="text/html" href="https://wiki.jon.geek.nz/index.php?title=NextCloud&amp;diff=2497"/>
		<updated>2023-09-07T08:35:48Z</updated>

		<summary type="html">&lt;p&gt;Johnno: /* NextCloud Talk */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Assumes Ubuntu 20.04, stable20 branch, and installing in {{code|/var/www/nextcloud}} for a cloud.&amp;#039;&amp;#039;&amp;#039;example.com&amp;#039;&amp;#039;&amp;#039; URL (c. December 2020).&lt;br /&gt;
&lt;br /&gt;
== Prerequisites ==&lt;br /&gt;
&lt;br /&gt;
Install some stuff first. This NextCloud recipe uses [[PostgreSQL]], Redis, Apache 2.4, FastCGI with PHP FPM, and Dehydrated for [[Letsencrypt]] SSL certificate maangement.&lt;br /&gt;
&lt;br /&gt;
 sudo apt install apache2 libapache2-mod-fcgid \&lt;br /&gt;
    php7.4-{bcmath,bz2,curl,gd,fpm,gmp,intl,json,mbstring,opcache,pgsql,tidy,xmlrpc,xsl,zip}&lt;br /&gt;
    php-{imagick,redis} composer dehydrated postgresql redis-server&lt;br /&gt;
&lt;br /&gt;
;NOTE: NextCloud works fine under nginx, I just can&amp;#039;t be bothered maintaining what goes in {{code|.htaccess}} which NextCloud expects to be writeable to keep itself updated.&lt;br /&gt;
&lt;br /&gt;
== Configuring Apache and PHP ==&lt;br /&gt;
&lt;br /&gt;
: &amp;#039;&amp;#039;See the [[PHP]] page for setting up PHP with Apache, FPM and Event MPM.&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
=== Add a virtual host for NextCloud ===&lt;br /&gt;
&lt;br /&gt;
It should look something like this:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;VirtualHost *:443&amp;gt;&lt;br /&gt;
   ServerName cloud.&amp;#039;&amp;#039;&amp;#039;example.com&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   DocumentRoot /var/www/nextcloud &lt;br /&gt;
 &lt;br /&gt;
   &amp;lt;Directory &amp;quot;/var/www/nexcloud&amp;quot;&amp;gt;&lt;br /&gt;
     Options FollowSymLinks MultiViews&lt;br /&gt;
     AllowOverride All&lt;br /&gt;
     Require all granted&lt;br /&gt;
     Satisfy Any &lt;br /&gt;
     SetEnv HOME /var/www/nextcloud&lt;br /&gt;
     SetEnv HTTP_HOME /var/www/nextcloud&lt;br /&gt;
 &lt;br /&gt;
     &amp;lt;IfModule mod_dav.c&amp;gt;&lt;br /&gt;
       Dav off&lt;br /&gt;
     &amp;lt;/IfModule&amp;gt;&lt;br /&gt;
   &amp;lt;/Directory&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
   SSLEngine On&lt;br /&gt;
   SSLCertificateFile ...&lt;br /&gt;
 &amp;lt;/VirtualHost&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== PHP settings ===&lt;br /&gt;
&lt;br /&gt;
Enable the opcache, increase the memory limit, and increase the maximum POST and file upload size so you can upload large files.&lt;br /&gt;
&lt;br /&gt;
== Create a database ==&lt;br /&gt;
&lt;br /&gt;
Create a database in [[PostgreSQL]]:&lt;br /&gt;
&lt;br /&gt;
 sudo -u postgres createuser -SDRP &amp;#039;&amp;#039;&amp;lt;nextcloud-user&amp;gt;&amp;#039;&amp;#039;&lt;br /&gt;
 sudo -u postgres createdb -E UTF8 -O &amp;#039;&amp;#039;&amp;lt;nextcloud-user&amp;gt;&amp;#039;&amp;#039; &amp;#039;&amp;#039;&amp;lt;nextcloud-dbname&amp;gt;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
== Install NextCloud ==&lt;br /&gt;
&lt;br /&gt;
We can just clone it from git:&lt;br /&gt;
&lt;br /&gt;
 git clone &amp;lt;nowiki&amp;gt;https://&amp;lt;/nowiki&amp;gt;github.com/nextcloud/server.git nextcloud&lt;br /&gt;
 cd nextcloud&lt;br /&gt;
 git checkout stable20  &amp;#039;&amp;#039;# or whatever the latest stable version is&amp;#039;&amp;#039;&lt;br /&gt;
 git submodule update --init --recursive&lt;br /&gt;
 chown www-data:www-data config apps .htaccess&lt;br /&gt;
&lt;br /&gt;
Create a directory for the cache and user data, which should not reside under the web root:&lt;br /&gt;
&lt;br /&gt;
 mkdir -p /var/lib/nextcloud/data /var/cache/nextcloud&lt;br /&gt;
 chown -R www-data:www-data /var/lib/nextcloud /var/cache/nextcloud&lt;br /&gt;
&lt;br /&gt;
== Configure NextCloud ==&lt;br /&gt;
&lt;br /&gt;
Edit the configuration file in {{code|config/config.php}} and check or consider these settings, and add the database and SMTP connection details:&lt;br /&gt;
&lt;br /&gt;
 $config =&amp;gt; [&lt;br /&gt;
   # ...&lt;br /&gt;
   #&lt;br /&gt;
   &amp;#039;passwordsalt&amp;#039; =&amp;gt; &amp;quot;&amp;#039;&amp;#039;&amp;lt;very long random string&amp;gt;&amp;#039;&amp;#039;&amp;quot;,&lt;br /&gt;
   &amp;#039;secret&amp;#039; =&amp;gt; &amp;quot;&amp;#039;&amp;#039;&amp;lt;a different very long random string&amp;gt;&amp;#039;&amp;#039;&amp;quot;,&lt;br /&gt;
   &amp;#039;trusted_domains&amp;#039; =&amp;gt; [&lt;br /&gt;
     0 =&amp;gt; &amp;quot;cloud.&amp;#039;&amp;#039;&amp;#039;example.com&amp;#039;&amp;#039;&amp;#039;&amp;quot;,&lt;br /&gt;
   ],&lt;br /&gt;
   &amp;#039;datadirectory&amp;#039; =&amp;gt; &amp;#039;/var/lib/nextcloud/data&amp;#039;,&lt;br /&gt;
   &amp;#039;overwrite.cli.url&amp;#039; =&amp;gt; &amp;#039;&amp;lt;nowiki&amp;gt;https://&amp;lt;/nowiki&amp;gt;cloud.&amp;#039;&amp;#039;&amp;#039;example.com&amp;#039;&amp;#039;&amp;#039;/&amp;#039;,&lt;br /&gt;
   &amp;#039;htaccess.RewriteBase&amp;#039; =&amp;gt; &amp;#039;/&amp;#039;,&lt;br /&gt;
 &lt;br /&gt;
   # Database connection details&lt;br /&gt;
   &amp;#039;dbtype&amp;#039; =&amp;gt; &amp;#039;pgsql&amp;#039;,&lt;br /&gt;
   &amp;#039;dbhost&amp;#039; =&amp;gt; &amp;#039;localhost&amp;#039;,&lt;br /&gt;
   &amp;#039;dbuser&amp;#039; =&amp;gt; &amp;quot;&amp;#039;&amp;#039;&amp;lt;nextcloud-dbuser&amp;gt;&amp;#039;&amp;#039;&amp;quot;,&lt;br /&gt;
   &amp;#039;dbpassword&amp;#039; =&amp;gt; &amp;quot;&amp;#039;&amp;#039;&amp;lt;password&amp;gt;&amp;#039;&amp;#039;&amp;quot;,&lt;br /&gt;
   &amp;#039;dbname&amp;#039; =&amp;gt; &amp;quot;&amp;#039;&amp;#039;&amp;lt;nextcloud-dbname&amp;gt;&amp;#039;&amp;#039;&amp;quot;,&lt;br /&gt;
   &amp;#039;dbtableprefix&amp;#039; =&amp;gt; &amp;#039;oc_&amp;#039;,&lt;br /&gt;
 &lt;br /&gt;
   # Force all URLs to use SSL or it may trip up things like OAuth&lt;br /&gt;
   &amp;#039;overwriteprotocol&amp;#039; =&amp;gt; &amp;#039;https&amp;#039;,&lt;br /&gt;
 &lt;br /&gt;
   # Use Redis and caching to make everything go faster&lt;br /&gt;
   &amp;#039;memcache.local&amp;#039; =&amp;gt; &amp;#039;\\OC\\Memcache\\Redis&amp;#039;,&lt;br /&gt;
   &amp;#039;memcache.locking&amp;#039; =&amp;gt; &amp;#039;\\OC\\Memcache\\Redis&amp;#039;,&lt;br /&gt;
   &amp;#039;redis&amp;#039; =&amp;gt; [&lt;br /&gt;
     &amp;#039;host&amp;#039; =&amp;gt; &amp;#039;localhost&amp;#039;,&lt;br /&gt;
     &amp;#039;port&amp;#039; =&amp;gt; 6379,&lt;br /&gt;
   ],&lt;br /&gt;
   &amp;#039;cache_path&amp;#039; =&amp;gt; &amp;#039;/var/cache/nextcloud&amp;#039;,&lt;br /&gt;
 &lt;br /&gt;
   # Send email details&lt;br /&gt;
   &amp;#039;mail_smtpmode&amp;#039; =&amp;gt; &amp;#039;smtp&amp;#039;,&lt;br /&gt;
   &amp;#039;mail_smtpsecure&amp;#039; =&amp;gt; &amp;#039;tls&amp;#039;,&lt;br /&gt;
   &amp;#039;mail_sendmailmode&amp;#039; =&amp;gt; &amp;#039;smtp&amp;#039;,&lt;br /&gt;
   &amp;#039;mail_from_address&amp;#039; =&amp;gt; &amp;quot;nexcloud@&amp;#039;&amp;#039;&amp;#039;example.com&amp;#039;&amp;#039;&amp;#039;&amp;quot;,&lt;br /&gt;
   &amp;#039;mail_domain&amp;#039; =&amp;gt; &amp;quot;&amp;#039;&amp;#039;&amp;#039;example.com&amp;#039;&amp;#039;&amp;#039;&amp;quot;,&lt;br /&gt;
   &amp;#039;mail_smtpauthtype&amp;#039; =&amp;gt; &amp;#039;PLAIN&amp;#039;,&lt;br /&gt;
   &amp;#039;mail_smtpauth&amp;#039; =&amp;gt; 1,&lt;br /&gt;
   &amp;#039;mail_smtphost&amp;#039; =&amp;gt; &amp;quot;mail.&amp;#039;&amp;#039;&amp;#039;example.com&amp;#039;&amp;#039;&amp;#039;&amp;quot;,&lt;br /&gt;
   &amp;#039;mail_smtpport&amp;#039; =&amp;gt; 587,&lt;br /&gt;
   &amp;#039;mail_smtpname&amp;#039; =&amp;gt; &amp;quot;&amp;#039;&amp;#039;&amp;lt;emailuser&amp;gt;&amp;#039;&amp;#039;&amp;quot;,&lt;br /&gt;
   &amp;#039;mail_smtppassword&amp;#039; =&amp;gt; &amp;quot;&amp;#039;&amp;#039;&amp;lt;emailpassword&amp;gt;&amp;#039;&amp;#039;&amp;quot;,&lt;br /&gt;
&lt;br /&gt;
Then navigate to the URL in the browser to install (or run the NextCloud {{code | ./occ}} tool from the command line).&lt;br /&gt;
&lt;br /&gt;
=== Clean URLs ===&lt;br /&gt;
&lt;br /&gt;
For clean URLs, make sure {{code | AllowOverride All}} is set for the parent directory; the {{code | /var/www}} definition is in the main {{code | /etc/apache2/apache.conf}}. Then run the follwing OCC command to enable the rewrite rules:&lt;br /&gt;
&lt;br /&gt;
 sudo -u www-data ./occ maintenance:update:htaccess&lt;br /&gt;
&lt;br /&gt;
=== Previews of other file types ===&lt;br /&gt;
&lt;br /&gt;
Edit {{code|/etc/ImageMagick/policy.xml}} and remove this line to get PDF previews to work:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;policy domain=&amp;quot;coder&amp;quot; rights=&amp;quot;none&amp;quot; pattern=&amp;quot;PDF&amp;quot; /&amp;gt; &amp;lt;!-- remove this line --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then add the following to {{code|config.php}} to get lots of other useful file previews:&lt;br /&gt;
   &amp;#039;enabledPreviewProviders&amp;#039; =&amp;gt; [&lt;br /&gt;
     # ...&lt;br /&gt;
     8 =&amp;gt; &amp;#039;OC\\Preview\\MarkDown&amp;#039;,&lt;br /&gt;
     9 =&amp;gt; &amp;#039;OC\\Preview\\Movie&amp;#039;,&lt;br /&gt;
     10 =&amp;gt; &amp;#039;OC\\Preview\\PDF&amp;#039;,&lt;br /&gt;
     11 =&amp;gt; &amp;#039;OC\\Preview\\OpenDocument&amp;#039;,&lt;br /&gt;
     12 =&amp;gt; &amp;#039;OC\\Preview\\MSOfficeDoc&amp;#039;,&lt;br /&gt;
     13 =&amp;gt; &amp;#039;OC\\Preview\\MSOffice2003&amp;#039;,&lt;br /&gt;
     14 =&amp;gt; &amp;#039;OC\\Preview\\MSOffice2007&amp;#039;,&lt;br /&gt;
   ],&lt;br /&gt;
&lt;br /&gt;
=== Photos ===&lt;br /&gt;
&lt;br /&gt;
Photos replaces the Gallery app, and is installed separately through the NC store or you can use git to manage it as a submodule. If it doesn&amp;#039;t work you might need to build its JavaScript resources by running {{code|make}} in its {{code|apps/photos}} directory. Alternatively you can resuscitate the Gallery app, which stopped working after NextCloud version 17, by updating its JavaScript dompurify library to a [https://raw.githubusercontent.com/nextcloud/gallery/ecb26a812f30a3f516964808ccfa6430be09b45e/js/vendor/dompurify/src/purify.js newer version] and bumping the app max version in {{code|apps/galleryappinfo/info.xml}} as follows (See also [https://github.com/nextcloud/gallery/pull/570/ pull request #570]):&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nextcloud min-version=&amp;quot;17&amp;quot; max-version=&amp;quot;&amp;#039;&amp;#039;&amp;#039;20&amp;#039;&amp;#039;&amp;#039;&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== NextCloud Talk ===&lt;br /&gt;
&lt;br /&gt;
To be at all useful, you need a TURN server. This is easiest achieved by installing and correctly configuring coturn, which also acts as a STUN server. STUN is for clients to figure out their external IP address, and TURN is for relaying UDP packets, e.g. for WebRTC.&lt;br /&gt;
&lt;br /&gt;
 sudo apt install coturn&lt;br /&gt;
&lt;br /&gt;
For it to actually do anything (it is disabled by default!) you need to edit {{code|/etc/default/coturn}} and make sure it contains the following, and is not commented out:&lt;br /&gt;
&lt;br /&gt;
 TURNSERVER_ENABLED=1&lt;br /&gt;
&lt;br /&gt;
Then in {{code|/etc/turnserver.conf}} you need to configure its IP addresses and ports, SSL certificate, and how it authenticates. See GitHub for a fully documented example [https://github.com/coturn/coturn/blob/master/examples/etc/turnserver.conf turnserver.conf] file:&lt;br /&gt;
&lt;br /&gt;
 server-name=&amp;#039;&amp;#039;&amp;#039;turn.example.com&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
 realm=&amp;#039;&amp;#039;&amp;#039;turn.example.com&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
 &lt;br /&gt;
 # When hosted on an internal LAN or DMZ, it might look like this: &lt;br /&gt;
 listening-ip=192.168.1.100&lt;br /&gt;
 relay-ip=192.168.1.100&lt;br /&gt;
 external-ip=123.45.67.8&lt;br /&gt;
 &lt;br /&gt;
 # Or use the short-hand:&lt;br /&gt;
 external-ip=123.45.67.8/192.168.1.100&lt;br /&gt;
 &lt;br /&gt;
 # Specify listening ports; traditionally 3478 was unencrypted, and 5349 was TLS,&lt;br /&gt;
 # but now TLS is supported on both. It is possible to listen on 443, which will&lt;br /&gt;
 # likely provide connectivity for people behind port-limited firewalls; this will&lt;br /&gt;
 # conflict with any HTTPS web hosting on the same server though, unless you set&lt;br /&gt;
 # up a second IP address for it.&lt;br /&gt;
 listening-port=3478&lt;br /&gt;
 tls-listening-port=5349&lt;br /&gt;
 #tls-listening-port=443&lt;br /&gt;
 &lt;br /&gt;
 # Specify a UDP port range and ensure they are exposed through the firewall/router&lt;br /&gt;
 min-port=53490&lt;br /&gt;
 max-port=59999&lt;br /&gt;
 &lt;br /&gt;
 # SSL setup; &lt;br /&gt;
 cert=/path/to/talk.example.com/fullchain.cert&lt;br /&gt;
 pkey=/path/to/talk.example.com/privkey.pem&lt;br /&gt;
 no-tlsv1&lt;br /&gt;
 no-tlsv1_1&lt;br /&gt;
 &lt;br /&gt;
 # To use with NextCloud, set a shared secret here.&lt;br /&gt;
 use-auth-secret&lt;br /&gt;
 static-auth-secret=&amp;#039;&amp;#039;&amp;#039;your-shared-secret-string-here&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
 stale-nonce=600&lt;br /&gt;
 &lt;br /&gt;
 # Limit STUN attacks (coturn 4.5.2&lt;br /&gt;
 no-rfc5780&lt;br /&gt;
 nl-stun-backward-compatibility&lt;br /&gt;
&lt;br /&gt;
In your NextCloud Administration section, you can now configure Talk to use the STUN/TURN server, using your server URLs, and provide the same shared secret you configured above. For maximum compatibility, use both UDP and TCP, and both turn and turns (TLS) connections:&lt;br /&gt;
&lt;br /&gt;
 stun: &amp;#039;&amp;#039;&amp;#039;talk.example.com&amp;#039;&amp;#039;&amp;#039;:5349&lt;br /&gt;
 turn and turns: &amp;#039;&amp;#039;&amp;#039;talk.example.com&amp;#039;&amp;#039;&amp;#039;:5349&lt;br /&gt;
&lt;br /&gt;
Test your server [https://webrtc.github.io/samples/src/content/peerconnection/trickle-ice/ here]. If STUN is working, you should get {{code|srflx}} candidates, and {{code|relay}} candidates if TURN is working.&lt;br /&gt;
&lt;br /&gt;
Sources and further reading:&lt;br /&gt;
* NextCloud Talk documentation: [https://nextcloud-talk.readthedocs.io/en/latest/TURN/ TURN], [https://nextcloud-talk.readthedocs.io/en/latest/coturn coturn]&lt;br /&gt;
* NextCloud Help, [https://help.nextcloud.com/t/howto-setup-nextcloud-talk-with-turn-server/30794 1] [https://help.nextcloud.com/t/nextcloud-talk-app-could-not-establish-a-connection-a-turn-server/131069/31 2]&lt;br /&gt;
* Stack Overflow [https://stackoverflow.com/questions/42801361/install-rfc5766-turn-server-trying-to-bind-fd-to-ip-address-errno-99 1]&lt;br /&gt;
* [https://ourcodeworld.com/articles/read/1526/how-to-test-online-whether-a-stun-turn-server-is-working-properly-or-not Testing STUN/TURN]&lt;br /&gt;
&lt;br /&gt;
== Maintenance ==&lt;br /&gt;
&lt;br /&gt;
Keep the git checkout of NextCloud and its submodules up to date with git, and run the OCC upgrade command:&lt;br /&gt;
&lt;br /&gt;
 cd /var/www/nextcloud&lt;br /&gt;
 git pull&lt;br /&gt;
 git submodule update --init --recursive&lt;br /&gt;
 sudo -u www-data ./occ upgrade&lt;br /&gt;
&lt;br /&gt;
=== Cron job ===&lt;br /&gt;
&lt;br /&gt;
In the administrator settings select cron rather than other methods, and put this in {{code|/etc/cron.d/nextcloud}}&lt;br /&gt;
&lt;br /&gt;
 */5 * * * * www-data /usr/bin/php /var/www/nextcloud/cron.php&lt;/div&gt;</summary>
		<author><name>Johnno</name></author>
	</entry>
	<entry>
		<id>https://wiki.jon.geek.nz/index.php?title=NextCloud&amp;diff=2496</id>
		<title>NextCloud</title>
		<link rel="alternate" type="text/html" href="https://wiki.jon.geek.nz/index.php?title=NextCloud&amp;diff=2496"/>
		<updated>2023-09-07T08:31:33Z</updated>

		<summary type="html">&lt;p&gt;Johnno: /* Configure NextCloud */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Assumes Ubuntu 20.04, stable20 branch, and installing in {{code|/var/www/nextcloud}} for a cloud.&amp;#039;&amp;#039;&amp;#039;example.com&amp;#039;&amp;#039;&amp;#039; URL (c. December 2020).&lt;br /&gt;
&lt;br /&gt;
== Prerequisites ==&lt;br /&gt;
&lt;br /&gt;
Install some stuff first. This NextCloud recipe uses [[PostgreSQL]], Redis, Apache 2.4, FastCGI with PHP FPM, and Dehydrated for [[Letsencrypt]] SSL certificate maangement.&lt;br /&gt;
&lt;br /&gt;
 sudo apt install apache2 libapache2-mod-fcgid \&lt;br /&gt;
    php7.4-{bcmath,bz2,curl,gd,fpm,gmp,intl,json,mbstring,opcache,pgsql,tidy,xmlrpc,xsl,zip}&lt;br /&gt;
    php-{imagick,redis} composer dehydrated postgresql redis-server&lt;br /&gt;
&lt;br /&gt;
;NOTE: NextCloud works fine under nginx, I just can&amp;#039;t be bothered maintaining what goes in {{code|.htaccess}} which NextCloud expects to be writeable to keep itself updated.&lt;br /&gt;
&lt;br /&gt;
== Configuring Apache and PHP ==&lt;br /&gt;
&lt;br /&gt;
: &amp;#039;&amp;#039;See the [[PHP]] page for setting up PHP with Apache, FPM and Event MPM.&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
=== Add a virtual host for NextCloud ===&lt;br /&gt;
&lt;br /&gt;
It should look something like this:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;VirtualHost *:443&amp;gt;&lt;br /&gt;
   ServerName cloud.&amp;#039;&amp;#039;&amp;#039;example.com&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   DocumentRoot /var/www/nextcloud &lt;br /&gt;
 &lt;br /&gt;
   &amp;lt;Directory &amp;quot;/var/www/nexcloud&amp;quot;&amp;gt;&lt;br /&gt;
     Options FollowSymLinks MultiViews&lt;br /&gt;
     AllowOverride All&lt;br /&gt;
     Require all granted&lt;br /&gt;
     Satisfy Any &lt;br /&gt;
     SetEnv HOME /var/www/nextcloud&lt;br /&gt;
     SetEnv HTTP_HOME /var/www/nextcloud&lt;br /&gt;
 &lt;br /&gt;
     &amp;lt;IfModule mod_dav.c&amp;gt;&lt;br /&gt;
       Dav off&lt;br /&gt;
     &amp;lt;/IfModule&amp;gt;&lt;br /&gt;
   &amp;lt;/Directory&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
   SSLEngine On&lt;br /&gt;
   SSLCertificateFile ...&lt;br /&gt;
 &amp;lt;/VirtualHost&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== PHP settings ===&lt;br /&gt;
&lt;br /&gt;
Enable the opcache, increase the memory limit, and increase the maximum POST and file upload size so you can upload large files.&lt;br /&gt;
&lt;br /&gt;
== Create a database ==&lt;br /&gt;
&lt;br /&gt;
Create a database in [[PostgreSQL]]:&lt;br /&gt;
&lt;br /&gt;
 sudo -u postgres createuser -SDRP &amp;#039;&amp;#039;&amp;lt;nextcloud-user&amp;gt;&amp;#039;&amp;#039;&lt;br /&gt;
 sudo -u postgres createdb -E UTF8 -O &amp;#039;&amp;#039;&amp;lt;nextcloud-user&amp;gt;&amp;#039;&amp;#039; &amp;#039;&amp;#039;&amp;lt;nextcloud-dbname&amp;gt;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
== Install NextCloud ==&lt;br /&gt;
&lt;br /&gt;
We can just clone it from git:&lt;br /&gt;
&lt;br /&gt;
 git clone &amp;lt;nowiki&amp;gt;https://&amp;lt;/nowiki&amp;gt;github.com/nextcloud/server.git nextcloud&lt;br /&gt;
 cd nextcloud&lt;br /&gt;
 git checkout stable20  &amp;#039;&amp;#039;# or whatever the latest stable version is&amp;#039;&amp;#039;&lt;br /&gt;
 git submodule update --init --recursive&lt;br /&gt;
 chown www-data:www-data config apps .htaccess&lt;br /&gt;
&lt;br /&gt;
Create a directory for the cache and user data, which should not reside under the web root:&lt;br /&gt;
&lt;br /&gt;
 mkdir -p /var/lib/nextcloud/data /var/cache/nextcloud&lt;br /&gt;
 chown -R www-data:www-data /var/lib/nextcloud /var/cache/nextcloud&lt;br /&gt;
&lt;br /&gt;
== Configure NextCloud ==&lt;br /&gt;
&lt;br /&gt;
Edit the configuration file in {{code|config/config.php}} and check or consider these settings, and add the database and SMTP connection details:&lt;br /&gt;
&lt;br /&gt;
 $config =&amp;gt; [&lt;br /&gt;
   # ...&lt;br /&gt;
   #&lt;br /&gt;
   &amp;#039;passwordsalt&amp;#039; =&amp;gt; &amp;quot;&amp;#039;&amp;#039;&amp;lt;very long random string&amp;gt;&amp;#039;&amp;#039;&amp;quot;,&lt;br /&gt;
   &amp;#039;secret&amp;#039; =&amp;gt; &amp;quot;&amp;#039;&amp;#039;&amp;lt;a different very long random string&amp;gt;&amp;#039;&amp;#039;&amp;quot;,&lt;br /&gt;
   &amp;#039;trusted_domains&amp;#039; =&amp;gt; [&lt;br /&gt;
     0 =&amp;gt; &amp;quot;cloud.&amp;#039;&amp;#039;&amp;#039;example.com&amp;#039;&amp;#039;&amp;#039;&amp;quot;,&lt;br /&gt;
   ],&lt;br /&gt;
   &amp;#039;datadirectory&amp;#039; =&amp;gt; &amp;#039;/var/lib/nextcloud/data&amp;#039;,&lt;br /&gt;
   &amp;#039;overwrite.cli.url&amp;#039; =&amp;gt; &amp;#039;&amp;lt;nowiki&amp;gt;https://&amp;lt;/nowiki&amp;gt;cloud.&amp;#039;&amp;#039;&amp;#039;example.com&amp;#039;&amp;#039;&amp;#039;/&amp;#039;,&lt;br /&gt;
   &amp;#039;htaccess.RewriteBase&amp;#039; =&amp;gt; &amp;#039;/&amp;#039;,&lt;br /&gt;
 &lt;br /&gt;
   # Database connection details&lt;br /&gt;
   &amp;#039;dbtype&amp;#039; =&amp;gt; &amp;#039;pgsql&amp;#039;,&lt;br /&gt;
   &amp;#039;dbhost&amp;#039; =&amp;gt; &amp;#039;localhost&amp;#039;,&lt;br /&gt;
   &amp;#039;dbuser&amp;#039; =&amp;gt; &amp;quot;&amp;#039;&amp;#039;&amp;lt;nextcloud-dbuser&amp;gt;&amp;#039;&amp;#039;&amp;quot;,&lt;br /&gt;
   &amp;#039;dbpassword&amp;#039; =&amp;gt; &amp;quot;&amp;#039;&amp;#039;&amp;lt;password&amp;gt;&amp;#039;&amp;#039;&amp;quot;,&lt;br /&gt;
   &amp;#039;dbname&amp;#039; =&amp;gt; &amp;quot;&amp;#039;&amp;#039;&amp;lt;nextcloud-dbname&amp;gt;&amp;#039;&amp;#039;&amp;quot;,&lt;br /&gt;
   &amp;#039;dbtableprefix&amp;#039; =&amp;gt; &amp;#039;oc_&amp;#039;,&lt;br /&gt;
 &lt;br /&gt;
   # Force all URLs to use SSL or it may trip up things like OAuth&lt;br /&gt;
   &amp;#039;overwriteprotocol&amp;#039; =&amp;gt; &amp;#039;https&amp;#039;,&lt;br /&gt;
 &lt;br /&gt;
   # Use Redis and caching to make everything go faster&lt;br /&gt;
   &amp;#039;memcache.local&amp;#039; =&amp;gt; &amp;#039;\\OC\\Memcache\\Redis&amp;#039;,&lt;br /&gt;
   &amp;#039;memcache.locking&amp;#039; =&amp;gt; &amp;#039;\\OC\\Memcache\\Redis&amp;#039;,&lt;br /&gt;
   &amp;#039;redis&amp;#039; =&amp;gt; [&lt;br /&gt;
     &amp;#039;host&amp;#039; =&amp;gt; &amp;#039;localhost&amp;#039;,&lt;br /&gt;
     &amp;#039;port&amp;#039; =&amp;gt; 6379,&lt;br /&gt;
   ],&lt;br /&gt;
   &amp;#039;cache_path&amp;#039; =&amp;gt; &amp;#039;/var/cache/nextcloud&amp;#039;,&lt;br /&gt;
 &lt;br /&gt;
   # Send email details&lt;br /&gt;
   &amp;#039;mail_smtpmode&amp;#039; =&amp;gt; &amp;#039;smtp&amp;#039;,&lt;br /&gt;
   &amp;#039;mail_smtpsecure&amp;#039; =&amp;gt; &amp;#039;tls&amp;#039;,&lt;br /&gt;
   &amp;#039;mail_sendmailmode&amp;#039; =&amp;gt; &amp;#039;smtp&amp;#039;,&lt;br /&gt;
   &amp;#039;mail_from_address&amp;#039; =&amp;gt; &amp;quot;nexcloud@&amp;#039;&amp;#039;&amp;#039;example.com&amp;#039;&amp;#039;&amp;#039;&amp;quot;,&lt;br /&gt;
   &amp;#039;mail_domain&amp;#039; =&amp;gt; &amp;quot;&amp;#039;&amp;#039;&amp;#039;example.com&amp;#039;&amp;#039;&amp;#039;&amp;quot;,&lt;br /&gt;
   &amp;#039;mail_smtpauthtype&amp;#039; =&amp;gt; &amp;#039;PLAIN&amp;#039;,&lt;br /&gt;
   &amp;#039;mail_smtpauth&amp;#039; =&amp;gt; 1,&lt;br /&gt;
   &amp;#039;mail_smtphost&amp;#039; =&amp;gt; &amp;quot;mail.&amp;#039;&amp;#039;&amp;#039;example.com&amp;#039;&amp;#039;&amp;#039;&amp;quot;,&lt;br /&gt;
   &amp;#039;mail_smtpport&amp;#039; =&amp;gt; 587,&lt;br /&gt;
   &amp;#039;mail_smtpname&amp;#039; =&amp;gt; &amp;quot;&amp;#039;&amp;#039;&amp;lt;emailuser&amp;gt;&amp;#039;&amp;#039;&amp;quot;,&lt;br /&gt;
   &amp;#039;mail_smtppassword&amp;#039; =&amp;gt; &amp;quot;&amp;#039;&amp;#039;&amp;lt;emailpassword&amp;gt;&amp;#039;&amp;#039;&amp;quot;,&lt;br /&gt;
&lt;br /&gt;
Then navigate to the URL in the browser to install (or run the NextCloud {{code | ./occ}} tool from the command line).&lt;br /&gt;
&lt;br /&gt;
=== Clean URLs ===&lt;br /&gt;
&lt;br /&gt;
For clean URLs, make sure {{code | AllowOverride All}} is set for the parent directory; the {{code | /var/www}} definition is in the main {{code | /etc/apache2/apache.conf}}. Then run the follwing OCC command to enable the rewrite rules:&lt;br /&gt;
&lt;br /&gt;
 sudo -u www-data ./occ maintenance:update:htaccess&lt;br /&gt;
&lt;br /&gt;
=== Previews of other file types ===&lt;br /&gt;
&lt;br /&gt;
Edit {{code|/etc/ImageMagick/policy.xml}} and remove this line to get PDF previews to work:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;policy domain=&amp;quot;coder&amp;quot; rights=&amp;quot;none&amp;quot; pattern=&amp;quot;PDF&amp;quot; /&amp;gt; &amp;lt;!-- remove this line --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then add the following to {{code|config.php}} to get lots of other useful file previews:&lt;br /&gt;
   &amp;#039;enabledPreviewProviders&amp;#039; =&amp;gt; [&lt;br /&gt;
     # ...&lt;br /&gt;
     8 =&amp;gt; &amp;#039;OC\\Preview\\MarkDown&amp;#039;,&lt;br /&gt;
     9 =&amp;gt; &amp;#039;OC\\Preview\\Movie&amp;#039;,&lt;br /&gt;
     10 =&amp;gt; &amp;#039;OC\\Preview\\PDF&amp;#039;,&lt;br /&gt;
     11 =&amp;gt; &amp;#039;OC\\Preview\\OpenDocument&amp;#039;,&lt;br /&gt;
     12 =&amp;gt; &amp;#039;OC\\Preview\\MSOfficeDoc&amp;#039;,&lt;br /&gt;
     13 =&amp;gt; &amp;#039;OC\\Preview\\MSOffice2003&amp;#039;,&lt;br /&gt;
     14 =&amp;gt; &amp;#039;OC\\Preview\\MSOffice2007&amp;#039;,&lt;br /&gt;
   ],&lt;br /&gt;
&lt;br /&gt;
=== Photos ===&lt;br /&gt;
&lt;br /&gt;
Photos replaces the Gallery app, and is installed separately through the NC store or you can use git to manage it as a submodule. If it doesn&amp;#039;t work you might need to build its JavaScript resources by running {{code|make}} in its {{code|apps/photos}} directory. Alternatively you can resuscitate the Gallery app, which stopped working after NextCloud version 17, by updating its JavaScript dompurify library to a [https://raw.githubusercontent.com/nextcloud/gallery/ecb26a812f30a3f516964808ccfa6430be09b45e/js/vendor/dompurify/src/purify.js newer version] and bumping the app max version in {{code|apps/galleryappinfo/info.xml}} as follows (See also [https://github.com/nextcloud/gallery/pull/570/ pull request #570]):&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nextcloud min-version=&amp;quot;17&amp;quot; max-version=&amp;quot;&amp;#039;&amp;#039;&amp;#039;20&amp;#039;&amp;#039;&amp;#039;&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== NextCloud Talk ===&lt;br /&gt;
&lt;br /&gt;
To be at all useful, you need a TURN server. This is easiest achieved by installing and correctly configuring coturn, which also acts as a STUN server. STUN is for clients to figure out their external IP address, and TURN is for relaying UDP packets, e.g. for WebRTC.&lt;br /&gt;
&lt;br /&gt;
 sudo apt install coturn&lt;br /&gt;
&lt;br /&gt;
For it to actually do anything (it is disabled by default!) you need to edit {{code|/etc/default/coturn}} and make sure it contains the following, and is not commented out:&lt;br /&gt;
&lt;br /&gt;
 TURNSERVER_ENABLED=1&lt;br /&gt;
&lt;br /&gt;
Then in {{code|/etc/turnserver.conf}} you need to configure its IP addresses and ports, SSL certificate, and how it authenticates. See GitHub for a fully documented example [https://github.com/coturn/coturn/blob/master/examples/etc/turnserver.conf turnserver.conf] file:&lt;br /&gt;
&lt;br /&gt;
 server-name=&amp;#039;&amp;#039;&amp;#039;turn.example.com&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
 realm=&amp;#039;&amp;#039;&amp;#039;turn.example.com&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
 &lt;br /&gt;
 # When hosted on an internal LAN or DMZ, it might look like this: &lt;br /&gt;
 listening-ip=192.168.1.100&lt;br /&gt;
 relay-ip=192.168.1.100&lt;br /&gt;
 exernal-ip=123.45.67.8&lt;br /&gt;
 # Or use the short-hand:&lt;br /&gt;
 external-ip=123.45.67.8/192.168.1.100&lt;br /&gt;
 &lt;br /&gt;
 # Specify listening ports; traditionally 3478 was unencrypted, and 5349 was TLS,&lt;br /&gt;
 # but now TLS is supported on both. It is possible to listen on 443, which will&lt;br /&gt;
 # likely provide connectivity for people behind port-limited firewalls; this will&lt;br /&gt;
 # conflict with any HTTPS web hosting on the same server though, unless you set&lt;br /&gt;
 # up a second IP address for it.&lt;br /&gt;
 listening-port=3478&lt;br /&gt;
 tls-listening-port=5349&lt;br /&gt;
 #tls-listening-port=443&lt;br /&gt;
 &lt;br /&gt;
 # Specify a UDP port range and ensure they are exposed through the firewall/router&lt;br /&gt;
 min-port=53490&lt;br /&gt;
 max-port=59999&lt;br /&gt;
 &lt;br /&gt;
 # SSL setup; &lt;br /&gt;
 cert=/path/to/talk.example.com/fullchain.cert&lt;br /&gt;
 pkey=/path/to/talk.example.com/privkey.pem&lt;br /&gt;
 no-tlsv1&lt;br /&gt;
 no-tlsv1_1&lt;br /&gt;
 &lt;br /&gt;
 # To use with NextCloud, set a shared secret here.&lt;br /&gt;
 use-auth-secret&lt;br /&gt;
 static-auth-secret=&amp;#039;&amp;#039;&amp;#039;your-shared-secret-string-here&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
 stale-nonce=600&lt;br /&gt;
 &lt;br /&gt;
 # Limit STUN attacks (coturn 4.1.2&lt;br /&gt;
 no-rfc5780&lt;br /&gt;
 nl-stun-backward-compatibility&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In your NextCloud Administration section, you can configure Talk to use your server, using your server URLs, and provide the same shared secret you used above for the TURN server. For maximum compatibility, use both UDP and TCP, and both turn and turns (TLS) connections:&lt;br /&gt;
&lt;br /&gt;
 stun: &amp;#039;&amp;#039;&amp;#039;talk.example.com&amp;#039;&amp;#039;&amp;#039;:5349&lt;br /&gt;
 turn and turns: &amp;#039;&amp;#039;&amp;#039;talk.example.com&amp;#039;&amp;#039;&amp;#039;:5349&lt;br /&gt;
&lt;br /&gt;
Test your server [https://webrtc.github.io/samples/src/content/peerconnection/trickle-ice/ here]. If STUN is working, you should get {{code|srflx}} candidates, and {{code|relay}} candidates if TURN is working.&lt;br /&gt;
&lt;br /&gt;
Sources and further reading:&lt;br /&gt;
* NextCloud Talk documentation: [https://nextcloud-talk.readthedocs.io/en/latest/TURN/ TURN], [https://nextcloud-talk.readthedocs.io/en/latest/coturn coturn]&lt;br /&gt;
* NextCloud Help, [https://help.nextcloud.com/t/howto-setup-nextcloud-talk-with-turn-server/30794 1] [https://help.nextcloud.com/t/nextcloud-talk-app-could-not-establish-a-connection-a-turn-server/131069/31 2]&lt;br /&gt;
* Stack Overflow [https://stackoverflow.com/questions/42801361/install-rfc5766-turn-server-trying-to-bind-fd-to-ip-address-errno-99 1]&lt;br /&gt;
* [https://ourcodeworld.com/articles/read/1526/how-to-test-online-whether-a-stun-turn-server-is-working-properly-or-not Testing STUN/TURN]&lt;br /&gt;
&lt;br /&gt;
== Maintenance ==&lt;br /&gt;
&lt;br /&gt;
Keep the git checkout of NextCloud and its submodules up to date with git, and run the OCC upgrade command:&lt;br /&gt;
&lt;br /&gt;
 cd /var/www/nextcloud&lt;br /&gt;
 git pull&lt;br /&gt;
 git submodule update --init --recursive&lt;br /&gt;
 sudo -u www-data ./occ upgrade&lt;br /&gt;
&lt;br /&gt;
=== Cron job ===&lt;br /&gt;
&lt;br /&gt;
In the administrator settings select cron rather than other methods, and put this in {{code|/etc/cron.d/nextcloud}}&lt;br /&gt;
&lt;br /&gt;
 */5 * * * * www-data /usr/bin/php /var/www/nextcloud/cron.php&lt;/div&gt;</summary>
		<author><name>Johnno</name></author>
	</entry>
	<entry>
		<id>https://wiki.jon.geek.nz/index.php?title=Hacks&amp;diff=2495</id>
		<title>Hacks</title>
		<link rel="alternate" type="text/html" href="https://wiki.jon.geek.nz/index.php?title=Hacks&amp;diff=2495"/>
		<updated>2023-07-15T03:50:19Z</updated>

		<summary type="html">&lt;p&gt;Johnno: /* Ditch Snap */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Image renaming by create date ==&lt;br /&gt;
&lt;br /&gt;
When you have a bunch of files from your old Android phone with a timestamp filename (e.g. 1388042328550.jpg), you can rename them thus:&lt;br /&gt;
&lt;br /&gt;
 for f in 1*.jpg; do&lt;br /&gt;
   mv $f $(date +IMG_%Y%m%d_%H%M%S.jpg -d @$(echo $f|cut -c 1-10))&lt;br /&gt;
 done&lt;br /&gt;
&lt;br /&gt;
Otherwise, we can fish out the Create Date from the EXIF data, using exiftool:&lt;br /&gt;
&lt;br /&gt;
 exiftool &amp;#039;-FileName&amp;lt;CreateDate&amp;#039; -d %Y%m%d_%H%M%S%%-c.%%e .&lt;br /&gt;
&lt;br /&gt;
== Use etckeeper ==&lt;br /&gt;
&lt;br /&gt;
It saves your bacon. Store changes to the {{path|/etc}} directory in git, uses hooks to commit changes when packages are updated, puppet runs, etc. Stash your own changes with useful commit messages. Look up stuff in history when something goes wrong, figure out what changes happened when packages are added or updated.&lt;br /&gt;
&lt;br /&gt;
=== Fix the daily commit bug ===&lt;br /&gt;
&lt;br /&gt;
Unfortunately since about 18.04 there is a bug where a systemd timer and a cron.daily task compete to commit a daily commit if needed; unfortunately one of them doesn&amp;#039;t bother to check the {{path|etckeeper.conf}} file to see whether you&amp;#039;ve disabled it. If you have &amp;lt;code&amp;gt;DISABLE_DAILY_AUTOCOMMITS=1&amp;lt;/code&amp;gt; in your config file, then you probably don&amp;#039;t want daily auto commits. If this is so, run this to disable the systemd timer:&lt;br /&gt;
&lt;br /&gt;
 systemctl disable --now etckeeper.timer&lt;br /&gt;
&lt;br /&gt;
== Repair broken or rotated phone videos ==&lt;br /&gt;
&lt;br /&gt;
You can fix broken video .tmp files from your Android phone using [https://github.com/ponchio/untrunc/ untrunc]. This will create a fixed.mp4 file in cwd:&lt;br /&gt;
&lt;br /&gt;
 untrunc working_video_from_the_same_camera.mp4 broken.mk4.tmp&lt;br /&gt;
&lt;br /&gt;
Did your phone unhelpfully rotate your video? Fix the metadata:&lt;br /&gt;
&lt;br /&gt;
 ffmpeg -i original.mp4 -acodec copy -vcodec copy -metadata:s:v:0 rotate=0 unrotated.mp4&lt;br /&gt;
&lt;br /&gt;
Or, did you actually film your shit the wrong way up? You&amp;#039;ll need to re-encode it:&lt;br /&gt;
&lt;br /&gt;
 ffmpeg -i original.mp4 -acodec copy -vcodec libx264 -crf 20 -metadata:s:v:0 rotate=0 unrotated.mp4&lt;br /&gt;
&lt;br /&gt;
== Export your photos ==&lt;br /&gt;
&lt;br /&gt;
Before uploading your photos, remove all the EXIF tags, and reduce the resolution; nobody needs 5000x4000 pixels, much less corporations hoovering up your stuff to put in adverts.&lt;br /&gt;
&lt;br /&gt;
 mkdir tmp&lt;br /&gt;
 for f in $.jpg; do&lt;br /&gt;
   convert -resize 1600x1200 $f tmp/$f&lt;br /&gt;
   exiftool -all= -P -overwrite_original tmp/$f&lt;br /&gt;
 done&lt;br /&gt;
&lt;br /&gt;
== Clean out your revoked and expired PGP keys ==&lt;br /&gt;
&lt;br /&gt;
Spring-clean your gpg database, make it go faster. Just go:&lt;br /&gt;
&lt;br /&gt;
 gpg --delete-keys $(gpg --list-public-keys|grep -PB1 &amp;#039;expired|revoked&amp;#039;|grep &amp;#039;^\s&amp;#039;)&lt;br /&gt;
&lt;br /&gt;
Obviously. If you can&amp;#039;t be arsed confirming each key, add &amp;lt;tt&amp;gt;--batch --yes&amp;lt;/tt&amp;gt; to the first gpg call.&lt;br /&gt;
&lt;br /&gt;
== Firefox opening your shit in gedit ==&lt;br /&gt;
&lt;br /&gt;
I don&amp;#039;t know, who thought that was a good idea? Jesus.&lt;br /&gt;
&lt;br /&gt;
 sed -i &amp;#039;s#.*octet-stream.*#application/octet-stream=xdg-open#&amp;#039; ~/.local/share/applications/mimeapps.list ~/.config/mimeapps.list&lt;br /&gt;
&lt;br /&gt;
== GNOME not sorting your folders first ==&lt;br /&gt;
&lt;br /&gt;
It&amp;#039;s not in a dialog anywhere, and a pretty lame default behaviour.&lt;br /&gt;
 dconf write /org/gnome/nautilus/preferences/sort-directories-first true&lt;br /&gt;
&lt;br /&gt;
== GNOME not dealing with WebP images ==&lt;br /&gt;
&lt;br /&gt;
I mean, it&amp;#039;s 2021 and WebP is only what, ten years old? Jesus. See solution on [https://askubuntu.com/a/617068 AskUbuntu].&lt;br /&gt;
&lt;br /&gt;
== Restoring huge databases to PostgreSQL ==&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;See also:&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039; &amp;#039;&amp;#039;[[PostgreSQL]]&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Skip some huge tables by dumping the TOC, removing culprit large tables, and restore with the edited TOC, e.g.&lt;br /&gt;
&lt;br /&gt;
 pg_restore -l huge.dump &amp;gt; TOC&lt;br /&gt;
 # edit the TOC file...&lt;br /&gt;
 pg_restore -L TOC -d dbname huge.dump&lt;br /&gt;
&lt;br /&gt;
== Output PostgreSQL queries to CSV ==&lt;br /&gt;
&lt;br /&gt;
 COPY (SELECT &amp;lt;query&amp;gt; ...) TO STDOUT CSV HEADER;&lt;br /&gt;
&lt;br /&gt;
== Turn off the shitty default &amp;quot;visual&amp;quot; mouse mode in vim ==&lt;br /&gt;
&lt;br /&gt;
Christ. Add this to ~/.vimrc&lt;br /&gt;
 set mouse-=a&lt;br /&gt;
&lt;br /&gt;
== Too many leftover git branches merged into master? Nukem! ==&lt;br /&gt;
&lt;br /&gt;
This will remove any branches on your local git repo that have been merged to master.&lt;br /&gt;
&lt;br /&gt;
 for i in $(for b in $(git branch|grep -v &amp;#039;\*&amp;#039;); do git branch $b --merged master; done); \&lt;br /&gt;
     do git branch -D $i; \&lt;br /&gt;
 done&lt;br /&gt;
&lt;br /&gt;
== Move your MySQL databases ==&lt;br /&gt;
&lt;br /&gt;
Used to be you could move your /var/lib/mysql directory somewhere else and symlink it. You can, but in newer distros with Apparmor you&amp;#039;ll need to declare it:&lt;br /&gt;
&lt;br /&gt;
 # In /etc/apparmor.d/tunables/alias&lt;br /&gt;
 alias /var/lib/mysql/ -&amp;gt; /mnt/wherever/mysql/,&lt;br /&gt;
&lt;br /&gt;
Note the trailing comma.&lt;br /&gt;
&lt;br /&gt;
== Split audio CD rips using the cue file ==&lt;br /&gt;
&lt;br /&gt;
Single-file FLAC or Ape files of a CD can be split up using the .cue file for both the timestamps and the tagging data. Also, install flacon (from a PPA).&lt;br /&gt;
&lt;br /&gt;
 sudo apt install shntool&lt;br /&gt;
 shnsplit -o flac cdimage.flac -f cdimage.cue -t &amp;#039;%n.%t&amp;#039;&lt;br /&gt;
&lt;br /&gt;
You may need to do tags again, if they didn&amp;#039;t stick:&lt;br /&gt;
&lt;br /&gt;
 sudo apt install cuetools&lt;br /&gt;
 cuetag cdimage.cue *.flac&lt;br /&gt;
&lt;br /&gt;
== Ditch Snap ==&lt;br /&gt;
&lt;br /&gt;
=== 1. Install Firefox properly ===&lt;br /&gt;
&lt;br /&gt;
Ubuntu 22.04 replaces the Firefox Debian package with a pseudo-package that installs it using Snap. This is no longer optional, and it is also stupid, annoying, slow, and potentially insecure for many reasons.&amp;lt;ref&amp;gt;Brandon Hopkins. [https://techhut.tv/flatpak-vs-snap-vs-appimage/ &amp;quot;Flatpak vs. Snap vs. AppImage - Linux Packaging Benchmarks&amp;quot;] TechHut, April 2022.&amp;lt;/ref&amp;gt; Several Firefox extensions that need to talk to other applications don&amp;#039;t currently work in Snap installed Firefox, including things like Zotero and Keepass.&lt;br /&gt;
&lt;br /&gt;
It also completely fails to find and import any existing Firefox profile. Snap apps for whatever stupid reason keep settings in a hard-coded ~/snap folder. Who thought that was a good idea? What&amp;#039;s wrong with ~/.config and/or ~/.local, or couldn&amp;#039;t they even use ~/.snap? Good grief.&lt;br /&gt;
&lt;br /&gt;
Luckily, we can use the Mozilla Team PPA instead.&amp;lt;ref&amp;gt;Ji M. [https://ubuntuhandbook.org/index.php/2022/04/install-firefox-deb-ubuntu-22-04/ &amp;quot;How to Install Latest Firefox as classic Deb in Ubuntu 22.04&amp;quot;] Ubuntu Handbook, April 2022.&amp;lt;/ref&amp;gt; In summary:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Remove Firefox entirely:&lt;br /&gt;
snap remove firefox&lt;br /&gt;
apt remove firefox&lt;br /&gt;
&lt;br /&gt;
# Add the Mozilla Team PPA and install:&lt;br /&gt;
add-apt-repository ppa:mozillateam/ppa&lt;br /&gt;
apt update&lt;br /&gt;
apt install -t &amp;#039;o=LP-PPA-mozillateam&amp;#039; firefox&lt;br /&gt;
&lt;br /&gt;
# Pin to the Mozilla Team PPA so we never get the Snap pseudo-package&lt;br /&gt;
echo &amp;#039;Package: firefox*&lt;br /&gt;
Pin: release o=LP-PPA-mozillateam&lt;br /&gt;
Pin-Priority: 501&amp;#039; &amp;gt; /etc/apt/preferences.d/mozillateam-ppa.pref&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 2. Remove snap ===&lt;br /&gt;
&lt;br /&gt;
You can also remove snap entirely as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# get a list of things installed with snap:&lt;br /&gt;
snap list&lt;br /&gt;
&lt;br /&gt;
# remove them one by one:&lt;br /&gt;
snap uninstall &amp;#039;&amp;#039;program1&amp;#039;&amp;#039;&lt;br /&gt;
snap uninstall &amp;#039;&amp;#039;program2&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
# once there&amp;#039;s nothing left, remove snap:&lt;br /&gt;
apt purge snapd&lt;br /&gt;
&lt;br /&gt;
# then prevent it ever being re-installed with a pin preference:&lt;br /&gt;
echo &amp;#039;Package: snapd&lt;br /&gt;
 Pin: release a=*&lt;br /&gt;
 Pin-Priority: -10&amp;#039; &amp;gt; /etc/apt/preferences.d/no-snap.pref&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Fancy PostgreSQL prompts==&lt;br /&gt;
&lt;br /&gt;
For a coloured prompt including what user, connection, and host you&amp;#039;re on, stick this in ~/.psqlrc or /etc/postgresql-common/psqlrc:&lt;br /&gt;
&lt;br /&gt;
 \set PROMPT1 &amp;#039;%[%033[1m%](%n@%[%033[1;35m%]%M%[%033[m%]%[%033[1m%] on %[%033[1;31m%]%`hostname`%[%033[m%]%[%033[1m%]) \n%/%R%#%[%033[m%] &amp;#039;&lt;br /&gt;
 \set PROMPT2 &amp;#039;%[%033[1m%]%/%R%#%[%033[m%] &amp;#039;&lt;br /&gt;
 \set PROMPT3 &amp;#039;%[%033[1m%]&amp;gt;&amp;gt;%[%033[m%] &amp;#039;&lt;br /&gt;
&lt;br /&gt;
Escape codes use &amp;#039;%&amp;#039; character, documented here: [https://www.postgresql.org/docs/current/app-psql.html#APP-PSQL-PROMPTING Psql Prompts].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Notes==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;/div&gt;</summary>
		<author><name>Johnno</name></author>
	</entry>
	<entry>
		<id>https://wiki.jon.geek.nz/index.php?title=PHP&amp;diff=2494</id>
		<title>PHP</title>
		<link rel="alternate" type="text/html" href="https://wiki.jon.geek.nz/index.php?title=PHP&amp;diff=2494"/>
		<updated>2023-05-19T21:27:09Z</updated>

		<summary type="html">&lt;p&gt;Johnno: /* Deny access to git repositories */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;: &amp;#039;&amp;#039;These instructions assume Ubuntu LTS (currently 20.04, c. August 2021) and are easily adapted to a Docker or other container definition, Ansible playbook, etc.&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
There&amp;#039;s a lot of talk about using Nginx instead of Apache, and for some things it&amp;#039;s probably easier to configure or maintain, especially if you&amp;#039;re writing IaC, but some things still assume or prefer Apache, particularly in PHP land. WordPress and NextCloud are example PHP applications that want to modify their {{code|.htaccess}} files in-place, for example to keep up with security developments.&lt;br /&gt;
&lt;br /&gt;
Perhaps part of the reason for the currently fashionable dim view of Apache&amp;#039;s performance is that PHP is often run in production using mod-php, which &amp;#039;&amp;#039;at best&amp;#039;&amp;#039; should only be used on a development workstation, if at all. Apart from being incompatible with HTTP/2, it is a CPU and memory hog, since it can only run using Apache&amp;#039;s horribly inefficient prefork multi-process management (MPM). Apache has several modules for dealing with MPM, but can only have one MPM module enabled at a time. Other much better, multithreaded, more efficient and fast MPM modules have been around for nearly two decades, and since version 5.4 of PHP (late 2011) we can use Apache&amp;#039;s Event MPM and FastCGI modules with PHP-FPM. More information is available on the Apache [https://cwiki.apache.org/confluence/display/httpd/PHP-FPM httpd wiki].&lt;br /&gt;
&lt;br /&gt;
With PHP processes being handled much more efficiently, and by being able to finally enable HTTP/2 in Apache, it all actually goes like the clappers.&lt;br /&gt;
&lt;br /&gt;
== Prerequisites ==&lt;br /&gt;
&lt;br /&gt;
Install at least the following packages:&lt;br /&gt;
&lt;br /&gt;
 sudo apt install apache2 libapache2-mod-fcgid php-fpm php7.4-{fpm,opcache}&lt;br /&gt;
&lt;br /&gt;
You&amp;#039;ll need various PHP extensions to host a real PHP application; for example [[NextCloud]] requires PHP composer, [[PostgreSQL]], Redis, and Dehydrated is useful for managing [[Letsencrypt]] SSL certificates.&lt;br /&gt;
&lt;br /&gt;
 sudo apt install php-{imagick,redis} \&lt;br /&gt;
     php7.4-{bcmath,bz2,curl,gd,gmp,intl,json,mbstring,pgsql,soap,tidy,xmlrpc,xsl,zip} \&lt;br /&gt;
     composer postgresql redis-server dehydrated&lt;br /&gt;
&lt;br /&gt;
== Set up Apache == &lt;br /&gt;
&lt;br /&gt;
Enable the required Apache configurations and modules:&lt;br /&gt;
&lt;br /&gt;
 a2enconf php7.4-fpm&lt;br /&gt;
 a2enmod dir env headers http2 mpm_event proxy_fcgi rewrite setenvif ssl&lt;br /&gt;
 systemctl restart apache2&lt;br /&gt;
&lt;br /&gt;
You should now be able to define your virtual hosts in {{code|/etc/apache2/sites-available}} and enable them, with PHP support.&lt;br /&gt;
&lt;br /&gt;
=== Deny access to git repositories ===&lt;br /&gt;
&lt;br /&gt;
Add a global config to deny access to git repositories and other hidden stuff, in {{code|/etc/apache2/conf-available/deny-git.conf}}:&lt;br /&gt;
&lt;br /&gt;
 &amp;#039;&amp;#039;# /etc/apache2/conf-available/deny-git.conf&amp;#039;&amp;#039;&lt;br /&gt;
 &amp;lt;LocationMatch &amp;quot;/\.(git|hg|bzr|svn|cvs|tag|ht)&amp;quot;&amp;gt;&lt;br /&gt;
   # Old apache:&lt;br /&gt;
   # Order deny,allow&lt;br /&gt;
   # deny from all&lt;br /&gt;
   Require all denied&lt;br /&gt;
 &amp;lt;/LocationMatch&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then enable it with:&lt;br /&gt;
&lt;br /&gt;
 a2enconf deny-git&lt;br /&gt;
 systemctl reload apache2&lt;br /&gt;
&lt;br /&gt;
=== Add a virtual host ===&lt;br /&gt;
&lt;br /&gt;
A virtual host for a typical PHP web application should look something like this:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;VirtualHost *:443&amp;gt;&lt;br /&gt;
   ServerName app.&amp;#039;&amp;#039;&amp;#039;example.com&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   DocumentRoot /var/www/app&lt;br /&gt;
 &lt;br /&gt;
   &amp;lt;Directory &amp;quot;/var/www/app&amp;quot;&amp;gt;&lt;br /&gt;
     Options FollowSymLinks MultiViews&lt;br /&gt;
     AllowOverride All&lt;br /&gt;
     Require all granted&lt;br /&gt;
   &amp;lt;/Directory&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
   SSLEngine On&lt;br /&gt;
   SSLCertificateFile ...&lt;br /&gt;
 &amp;lt;/VirtualHost&amp;gt;&lt;br /&gt;
&lt;br /&gt;
See the [[Letsencrypt]] page for how to sort out your SSL certificates on pet servers.&lt;br /&gt;
&lt;br /&gt;
== Configure PHP ==&lt;br /&gt;
&lt;br /&gt;
The configuration for PHP code hosted by Apache using PHP-FPM is located under {{code|/etc/php/7.4/fpm}}.&lt;br /&gt;
&lt;br /&gt;
You will not be able to use mod-php {{code|php_value}} directives in Apache configuration; either try and do without, or set environment variables instead.&lt;br /&gt;
&lt;br /&gt;
PHP works a lot better with a few extra things configured. Enable the opcache, increase the memory limit, and depending on what you&amp;#039;re hosting, increase the maximum POST size so users can upload photos and other large files. Other fun helpful things include using Redis for PHP sessions, and tuning the FPM process parameters to make stuff more efficient under load.&lt;br /&gt;
&lt;br /&gt;
=== Keep your PHP custom settings and tweaks separate ===&lt;br /&gt;
&lt;br /&gt;
Since Debian now moves files around with each new version of PHP, you can keep your customisations to the {{code|php.ini}} file in a local configuration. For example, instead of editing {{code|/etc/php/7.4/fpm/php.ini}}, put these settings in {{code|/etc/php/local/php.ini}}:&lt;br /&gt;
&lt;br /&gt;
 ; /etc/php/local/php.ini&lt;br /&gt;
 ; Override settings in the dist php.ini here&lt;br /&gt;
 ; make a symbolic link to this file in /etc/php/&amp;#039;&amp;#039;&amp;lt;version&amp;gt;&amp;#039;&amp;#039;/fpm/conf.d/99-local.ini&lt;br /&gt;
 max_execution_time = 60&lt;br /&gt;
 memory_limit = 512M&lt;br /&gt;
 post_max_size = 500M&lt;br /&gt;
 upload_max_filesize = 500M&lt;br /&gt;
 opcache.enable=1&lt;br /&gt;
&lt;br /&gt;
Then we add a symbolic link in the {{code|conf.d}} directory where you need it, for example:&lt;br /&gt;
&lt;br /&gt;
 ln -s /etc/php/local/php.ini /etc/php/7.4/fpm/conf.d/99-local.ini&lt;/div&gt;</summary>
		<author><name>Johnno</name></author>
	</entry>
	<entry>
		<id>https://wiki.jon.geek.nz/index.php?title=PHP&amp;diff=2493</id>
		<title>PHP</title>
		<link rel="alternate" type="text/html" href="https://wiki.jon.geek.nz/index.php?title=PHP&amp;diff=2493"/>
		<updated>2023-05-19T21:17:31Z</updated>

		<summary type="html">&lt;p&gt;Johnno: /* Deny access to git repositories */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;: &amp;#039;&amp;#039;These instructions assume Ubuntu LTS (currently 20.04, c. August 2021) and are easily adapted to a Docker or other container definition, Ansible playbook, etc.&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
There&amp;#039;s a lot of talk about using Nginx instead of Apache, and for some things it&amp;#039;s probably easier to configure or maintain, especially if you&amp;#039;re writing IaC, but some things still assume or prefer Apache, particularly in PHP land. WordPress and NextCloud are example PHP applications that want to modify their {{code|.htaccess}} files in-place, for example to keep up with security developments.&lt;br /&gt;
&lt;br /&gt;
Perhaps part of the reason for the currently fashionable dim view of Apache&amp;#039;s performance is that PHP is often run in production using mod-php, which &amp;#039;&amp;#039;at best&amp;#039;&amp;#039; should only be used on a development workstation, if at all. Apart from being incompatible with HTTP/2, it is a CPU and memory hog, since it can only run using Apache&amp;#039;s horribly inefficient prefork multi-process management (MPM). Apache has several modules for dealing with MPM, but can only have one MPM module enabled at a time. Other much better, multithreaded, more efficient and fast MPM modules have been around for nearly two decades, and since version 5.4 of PHP (late 2011) we can use Apache&amp;#039;s Event MPM and FastCGI modules with PHP-FPM. More information is available on the Apache [https://cwiki.apache.org/confluence/display/httpd/PHP-FPM httpd wiki].&lt;br /&gt;
&lt;br /&gt;
With PHP processes being handled much more efficiently, and by being able to finally enable HTTP/2 in Apache, it all actually goes like the clappers.&lt;br /&gt;
&lt;br /&gt;
== Prerequisites ==&lt;br /&gt;
&lt;br /&gt;
Install at least the following packages:&lt;br /&gt;
&lt;br /&gt;
 sudo apt install apache2 libapache2-mod-fcgid php-fpm php7.4-{fpm,opcache}&lt;br /&gt;
&lt;br /&gt;
You&amp;#039;ll need various PHP extensions to host a real PHP application; for example [[NextCloud]] requires PHP composer, [[PostgreSQL]], Redis, and Dehydrated is useful for managing [[Letsencrypt]] SSL certificates.&lt;br /&gt;
&lt;br /&gt;
 sudo apt install php-{imagick,redis} \&lt;br /&gt;
     php7.4-{bcmath,bz2,curl,gd,gmp,intl,json,mbstring,pgsql,soap,tidy,xmlrpc,xsl,zip} \&lt;br /&gt;
     composer postgresql redis-server dehydrated&lt;br /&gt;
&lt;br /&gt;
== Set up Apache == &lt;br /&gt;
&lt;br /&gt;
Enable the required Apache configurations and modules:&lt;br /&gt;
&lt;br /&gt;
 a2enconf php7.4-fpm&lt;br /&gt;
 a2enmod dir env headers http2 mpm_event proxy_fcgi rewrite setenvif ssl&lt;br /&gt;
 systemctl restart apache2&lt;br /&gt;
&lt;br /&gt;
You should now be able to define your virtual hosts in {{code|/etc/apache2/sites-available}} and enable them, with PHP support.&lt;br /&gt;
&lt;br /&gt;
=== Deny access to git repositories ===&lt;br /&gt;
&lt;br /&gt;
Add a global config to deny access to git repositories and other hidden stuff, in {{code|/etc/apache2/conf-available/deny-git.conf}}:&lt;br /&gt;
&lt;br /&gt;
 &amp;#039;&amp;#039;# /etc/apache2/conf-available/deny-git.conf&amp;#039;&amp;#039;&lt;br /&gt;
 &amp;lt;LocationMatch &amp;quot;/\.(git|hg|bzr|svn|cvs|tag|ht)&amp;quot;&amp;gt;&lt;br /&gt;
   Order deny,allow&lt;br /&gt;
   deny from all&lt;br /&gt;
 &amp;lt;/LocationMatch&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then enable it with:&lt;br /&gt;
&lt;br /&gt;
 a2enconf deny-git&lt;br /&gt;
 systemctl reload apache2&lt;br /&gt;
&lt;br /&gt;
=== Add a virtual host ===&lt;br /&gt;
&lt;br /&gt;
A virtual host for a typical PHP web application should look something like this:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;VirtualHost *:443&amp;gt;&lt;br /&gt;
   ServerName app.&amp;#039;&amp;#039;&amp;#039;example.com&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   DocumentRoot /var/www/app&lt;br /&gt;
 &lt;br /&gt;
   &amp;lt;Directory &amp;quot;/var/www/app&amp;quot;&amp;gt;&lt;br /&gt;
     Options FollowSymLinks MultiViews&lt;br /&gt;
     AllowOverride All&lt;br /&gt;
     Require all granted&lt;br /&gt;
   &amp;lt;/Directory&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
   SSLEngine On&lt;br /&gt;
   SSLCertificateFile ...&lt;br /&gt;
 &amp;lt;/VirtualHost&amp;gt;&lt;br /&gt;
&lt;br /&gt;
See the [[Letsencrypt]] page for how to sort out your SSL certificates on pet servers.&lt;br /&gt;
&lt;br /&gt;
== Configure PHP ==&lt;br /&gt;
&lt;br /&gt;
The configuration for PHP code hosted by Apache using PHP-FPM is located under {{code|/etc/php/7.4/fpm}}.&lt;br /&gt;
&lt;br /&gt;
You will not be able to use mod-php {{code|php_value}} directives in Apache configuration; either try and do without, or set environment variables instead.&lt;br /&gt;
&lt;br /&gt;
PHP works a lot better with a few extra things configured. Enable the opcache, increase the memory limit, and depending on what you&amp;#039;re hosting, increase the maximum POST size so users can upload photos and other large files. Other fun helpful things include using Redis for PHP sessions, and tuning the FPM process parameters to make stuff more efficient under load.&lt;br /&gt;
&lt;br /&gt;
=== Keep your PHP custom settings and tweaks separate ===&lt;br /&gt;
&lt;br /&gt;
Since Debian now moves files around with each new version of PHP, you can keep your customisations to the {{code|php.ini}} file in a local configuration. For example, instead of editing {{code|/etc/php/7.4/fpm/php.ini}}, put these settings in {{code|/etc/php/local/php.ini}}:&lt;br /&gt;
&lt;br /&gt;
 ; /etc/php/local/php.ini&lt;br /&gt;
 ; Override settings in the dist php.ini here&lt;br /&gt;
 ; make a symbolic link to this file in /etc/php/&amp;#039;&amp;#039;&amp;lt;version&amp;gt;&amp;#039;&amp;#039;/fpm/conf.d/99-local.ini&lt;br /&gt;
 max_execution_time = 60&lt;br /&gt;
 memory_limit = 512M&lt;br /&gt;
 post_max_size = 500M&lt;br /&gt;
 upload_max_filesize = 500M&lt;br /&gt;
 opcache.enable=1&lt;br /&gt;
&lt;br /&gt;
Then we add a symbolic link in the {{code|conf.d}} directory where you need it, for example:&lt;br /&gt;
&lt;br /&gt;
 ln -s /etc/php/local/php.ini /etc/php/7.4/fpm/conf.d/99-local.ini&lt;/div&gt;</summary>
		<author><name>Johnno</name></author>
	</entry>
	<entry>
		<id>https://wiki.jon.geek.nz/index.php?title=Fuel_cell_vehicles&amp;diff=2492</id>
		<title>Fuel cell vehicles</title>
		<link rel="alternate" type="text/html" href="https://wiki.jon.geek.nz/index.php?title=Fuel_cell_vehicles&amp;diff=2492"/>
		<updated>2023-03-02T23:46:17Z</updated>

		<summary type="html">&lt;p&gt;Johnno: /* Hydrogen interests are fossil fuel interests */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Background ==&lt;br /&gt;
&lt;br /&gt;
A &amp;#039;&amp;#039;fuel cell electric vehicle&amp;#039;&amp;#039; (FCEV) is an &amp;#039;&amp;#039;electric vehicle&amp;#039;&amp;#039; (EV)—that is, a vehicle propelled&lt;br /&gt;
using only electric motors—powered by the electricity generated by passing fuel and oxidant through&lt;br /&gt;
a &amp;#039;&amp;#039;fuel cell&amp;#039;&amp;#039;.&amp;lt;ref name=&amp;quot;note-1&amp;quot;&amp;gt;In practice, they usually have an additional small battery for storing extra charge&lt;br /&gt;
from regenerative braking, which can also be used to power the motors, to improve range.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== So what is a fuel cell? ===&lt;br /&gt;
[[File:Toyota Mirai fuel cell badge SAO 2016 9043.jpg|thumb]]&lt;br /&gt;
A fuel cell creates an electric current from the catalysed reaction of a fuel (say, hydrogen gas, H₂) and an oxidant, often oxygen&lt;br /&gt;
(O₂) from air. First demonstrated in the early nineteenth century, modern fuel cells are based on the&lt;br /&gt;
hydrogen-powered alkaline or &amp;quot;Bacon&amp;quot; fuel cells invented in the 1930s by English engineer Francis&lt;br /&gt;
Bacon.&amp;lt;ref name=&amp;quot;note-2&amp;quot;&amp;gt;Not Francis Bacon (1561–1626), the English philosopher and Lord Chancellor.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Most fuel cells produce low voltages, typically less than one volt, so they are usually&lt;br /&gt;
arranged in series into fuel cell &amp;#039;&amp;#039;&amp;quot;stacks&amp;quot;&amp;#039;&amp;#039; for practical high voltage use such as powering vehicles.&lt;br /&gt;
&lt;br /&gt;
== Fuel cell efficiency ==&lt;br /&gt;
&lt;br /&gt;
Fuel cells can have high thermal efficiencies of up to 85% in &amp;#039;&amp;#039;combined heat and power&amp;#039;&amp;#039; (CHP)&lt;br /&gt;
applications, despite having lower electrical efficiencies, but this means running at very high&lt;br /&gt;
temperatures. Conversely, the smaller fuel cell designs suitable for vehicles have a higher&lt;br /&gt;
electrical efficiency and operate at more manageable temperatures.&lt;br /&gt;
&lt;br /&gt;
The fuel cell stack powering the 2019 Hyundai Nexo has a reported 60% electrical efficiency.&lt;br /&gt;
&lt;br /&gt;
== Cost ==&lt;br /&gt;
&lt;br /&gt;
Fuel cells are very expensive. This is mainly because they rely on platinum-group metals as catalysts for&lt;br /&gt;
the REDOX reactions that extract electrons from the fuel without overtly combusting it.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;Platinum group metals are very expensive.&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
They are very rare, and difficult to refine. The huge increase in demand that would be needed for fuel cell vehicles globally would only make them even more expensive.&lt;br /&gt;
&lt;br /&gt;
In contrast, the principal limiting metal in the production of battery electric vehicles, lithium, is abundant and dirt cheap, even considering the similar huge increase in demand anticipated over the next few decades for batteries in EVs and grid scale applications.&lt;br /&gt;
&lt;br /&gt;
== Hydrogen as a fuel ==&lt;br /&gt;
&lt;br /&gt;
Hydrogen is an attractive fuel for many reasons. It can be produced from water through electrolysis,&lt;br /&gt;
and when combusted produces the same amount of water it was derived from. There are however a lot of&lt;br /&gt;
problems to overcome for it to be a sensible option for powering private transportation.&lt;br /&gt;
&lt;br /&gt;
=== Hydrogen interests are fossil fuel interests ===&lt;br /&gt;
&lt;br /&gt;
First and most significantly of all, water electrolysis is expensive because it requires huge&lt;br /&gt;
amounts of electricity. Consequently, &amp;#039;&amp;#039;over 95% of the world&amp;#039;s hydrogen is produced from fossil fuels&amp;#039;&amp;#039;.&lt;br /&gt;
Specifically, from the steam reformation of natural gas (methane), which is approximately:&lt;br /&gt;
&lt;br /&gt;
: CH₄ + H₂O → 3H₂ + CO&lt;br /&gt;
&lt;br /&gt;
The carbon monoxide is used in further industrial/chemical processes, or burnt to produce energy,&lt;br /&gt;
which produces CO₂.&lt;br /&gt;
&lt;br /&gt;
This means of course that currently, powering your car with hydrogen is effectively powering it with&lt;br /&gt;
natural gas, but in a much less efficient and far more expensive manner than if you had just powered&lt;br /&gt;
it with methane directly.&lt;br /&gt;
&lt;br /&gt;
Hydrogen is being researched and hyped by the fossil fuel industry, desperate to re-purpose their&lt;br /&gt;
colossal global infrastructure assets, which are about to be ruinously stranded over the coming&lt;br /&gt;
decades by the highly disruptive combination of exponential growth in solar photovoltaics, electric&lt;br /&gt;
vehicles, battery technology advances, and ongoing global fossil fuel divestment.&lt;br /&gt;
&lt;br /&gt;
Hydrogen is thus a massive waste of energy, resources, investment and time, for very little gain.&lt;br /&gt;
&lt;br /&gt;
=== Power density ===&lt;br /&gt;
[[File:Hyundai NEXO Hydrogen Fuel Cell Car beim Autosalon Genf 2018 i.jpg|thumb|Hydrogen fuel tank in a Hyundai Nexo]]&lt;br /&gt;
Hydrogen is the lightest element, so while its energy-to-mass ratio is impressive, its very low&lt;br /&gt;
density works against it. To store hydrogen at the sorts of high power-to-volume efficiencies that&lt;br /&gt;
we are used to with liquid hydrocarbon fuels, we need to compress it in tanks capable of extremely&lt;br /&gt;
high pressure, or as a cryogenic liquid kept at -252°C, which is practical only with space&lt;br /&gt;
programme budgets.&lt;br /&gt;
&lt;br /&gt;
For example, travelling 600 km in a modern FCEV requires only 4-5 kg of H₂ gas to power the fuel&lt;br /&gt;
cell, but to store this seemingly modest amount of fuel on-board requires an 80 litre tank&lt;br /&gt;
pressurised to 70 MPa, three times higher than a typical CNG tank.&lt;br /&gt;
&lt;br /&gt;
=== Safety ===&lt;br /&gt;
&lt;br /&gt;
As you can imagine, not everyone wants to drive around sitting on a tank of explosive gas compressed&lt;br /&gt;
to 700 atmospheres. Reliable safety data for how such storage tanks perform in accidents and&lt;br /&gt;
collisions is not available.&lt;br /&gt;
&lt;br /&gt;
With a detonation velocity at standard pressure of about 3-4 km/s, hydrogen is highly explosive and&lt;br /&gt;
thus much more dangerous in failure situations than petrol, given that at the point of any&lt;br /&gt;
detonation it will already be a rapidly decompressing gas mixing with air across a large expanding&lt;br /&gt;
surface area.&amp;lt;ref name=&amp;quot;note-3&amp;quot;&amp;gt;In short, such bad, very boom, wow.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The safest and most power-dense way to store hydrogen remains bonding it to carbon; hydrocarbons&lt;br /&gt;
have a very high energy-to-volume ratio, are stable liquids at room temperature, and are relatively&lt;br /&gt;
safe when handled correctly, even in failure situations.&lt;br /&gt;
&lt;br /&gt;
=== Loss from leaks, transportation and storage ===&lt;br /&gt;
&lt;br /&gt;
As already mentioned hydrogen is the lightest element, its nucleus consisting of a single proton. It is very&lt;br /&gt;
difficult for anything made of matter to be any smaller. This means that molecular hydrogen gas, H₂,&lt;br /&gt;
being the smallest molecule that can exist, will inevitably escape through the walls of all storage&lt;br /&gt;
devices, given sufficient time. Consequently, loss through the process of generating, pumping,&lt;br /&gt;
transporting and storing hydrogen is both measurable and significant.&lt;br /&gt;
&lt;br /&gt;
=== Damage to the ozone layer ===&lt;br /&gt;
&lt;br /&gt;
Since H₂ is also far too light to be held by Earth&amp;#039;s gravity, it escapes upwards through the&lt;br /&gt;
atmosphere and into space. On its way to space &amp;#039;&amp;#039;it passes through and damages the ozone layer&amp;#039;&amp;#039;,&lt;br /&gt;
where it permanently reacts with ozone to form water:&lt;br /&gt;
&lt;br /&gt;
: 3H₂ + O₃ → 3H₂O&lt;br /&gt;
&lt;br /&gt;
This is an irreversible (non-equilibrium) reaction. It also never gets mentioned anywhere, and seems to&lt;br /&gt;
only be known to meteorologists.&lt;br /&gt;
&lt;br /&gt;
== Overall efficiency ==&lt;br /&gt;
&lt;br /&gt;
To measure this we have to take into account where the hydrogen comes from. Currently, hydrogen fuel is just refined natural gas, with the CO₂ emissions occurring at the point of production.&lt;br /&gt;
&lt;br /&gt;
For a hydrogen-powered fuel cell vehicle to play the sustainability game, its hydrogen must be sourced from the electrolysis of water, which requires a large amount of energy, which we&amp;#039;ll call &amp;#039;&amp;#039;e&amp;#039;&amp;#039;. Specifically, hydrolysis requires electricity, and involves loss due to DC conversion and heat, so only about 70% of the input energy is available as hydrogen fuel.&lt;br /&gt;
&lt;br /&gt;
Note that already, before the hydrogen has even been siphoned, pumped, compressed and transported to a nearby hydrogen filling station, the battery-powered electric vehicle (BEV) can use 100% of the generated electricity.&lt;br /&gt;
&lt;br /&gt;
After generation of electricity and hydrogen fuel:&lt;br /&gt;
&lt;br /&gt;
* FCEV: &amp;#039;&amp;#039;e&amp;#039;&amp;#039; = 70%&lt;br /&gt;
* BEV: &amp;#039;&amp;#039;e&amp;#039;&amp;#039; = 100%&lt;br /&gt;
&lt;br /&gt;
We now have hydrogen gas which needs to be pressurised and transported to your local filling station, each at about a 10% loss (either through actual loss of gas or the consumption of extra energy). For the sake of argument let&amp;#039;s assume this is all done using more borrowed electricity, which leaves us with just over half of the energy spent available as hydrogen fuel.&lt;br /&gt;
&lt;br /&gt;
Meanwhile the full unit of electricity is transmitted to your garage at about 5% transmission loss and stored in your battery EV with about 85% efficiency; there is some loss from charger equipment AC/DC conversion and as heat.&lt;br /&gt;
&lt;br /&gt;
After fuel transportation and fueling/charging the vehicle:&amp;lt;ref name=&amp;quot;note-distributed-h2-gen&amp;quot;&amp;gt;The hydrogen fuel transportation step could be eliminated if fuel filling stations had sufficient installed solar PV and a piped water supply; eliminating this step results in a slightly higher 35% final efficiency. This would however massively increase the cost of building the currently non-existent infrastructure of hydrogen filling stations, and move the complex industrial production and processing of hydrogen gas into built-up and residential areas.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* FCEV: &amp;#039;&amp;#039;e&amp;#039;&amp;#039; = 56%&lt;br /&gt;
* BEV: &amp;#039;&amp;#039;e&amp;#039;&amp;#039; = 80%&lt;br /&gt;
&lt;br /&gt;
Now we consume the on-board energy to propel the vehicle. The FCEV converts the H₂ fuel into electricity with 60% efficiency at best, which powers the electric motors which are about 90-95% efficient. Meanwhile the BEV simply dumps the battery charge directly to the motors, at about 90% efficiency overall.&lt;br /&gt;
&lt;br /&gt;
At the point of propelling the vehicle forward:&lt;br /&gt;
&lt;br /&gt;
* FCEV: &amp;#039;&amp;#039;e&amp;#039;&amp;#039; = 31%&lt;br /&gt;
* BEV: &amp;#039;&amp;#039;e&amp;#039;&amp;#039; = 72%&lt;br /&gt;
&lt;br /&gt;
Compared to a fuel cell EV, &amp;#039;&amp;#039;a battery EV is more than twice as efficient&amp;#039;&amp;#039;, and this is the best imaginable scenario. In reality, compression and transportation of fuel gases is done with existing ship rail and road infrastructure, which currently involves high usage of fossil fuels and thus CO₂ emissions.&lt;br /&gt;
&lt;br /&gt;
It is a sad fact that in 2020 most of the world&amp;#039;s electricity is still generated by burning fossil fuels and emitting CO₂. Using this electricity to refine water into hydrogen, just to power a fuel cell powered electric vehicle at a dismal 31% efficiency is not really helping, when you could just replace the hydrogen tank and fuel cell with a big battery and go more than twice the distance.&lt;br /&gt;
&lt;br /&gt;
=== Comparison with petrol-powered cars ===&lt;br /&gt;
&lt;br /&gt;
A battery EV also wins against petrol-powered cars &amp;#039;&amp;#039;even when we burn all of the petrol to generate its electricity&amp;#039;&amp;#039;, because while the combustion emits CO₂, it is still far more efficient to dump the electricity into an EV battery directly than to use trucks to transport petrol to filling stations and use it to power an internal combustion engine. Even in 2020 most car engines operate at a pretty terrible 20-25% efficiency.&lt;br /&gt;
&lt;br /&gt;
Many pundits think we are truly witnessing a revolution in transport not seen since the disappearance of steam traction engines and horses a hundred years ago; it&amp;#039;s just that nobody in 2020 has noticed yet, the same way nobody noticed the internet in 1995.&lt;br /&gt;
&lt;br /&gt;
== Is there still a case for Hydrogen? ==&lt;br /&gt;
[[File:First London bus ESQ64993 (ex LK53 MBV), 2003 Mercedez-Benz Citaro fuel cell, London Transport Museum Acton depot, 7 August 2011 (5).jpg|thumb]]&lt;br /&gt;
Yes.&lt;br /&gt;
&lt;br /&gt;
Hydrogen fuel cells make more sense at scale, where batteries would take up too much space or weight, or when connection to the grid is not practical. On large vessels, they could replace the use of fossil fuels and positively transform entire sectors, such as shipping and aviation. They also have potential for use in large scale CHP applications, remote installations, and certain grid-scale operations.&lt;br /&gt;
&lt;br /&gt;
== Glossary ==&lt;br /&gt;
&lt;br /&gt;
;BEV: Battery Electric Vehicle. An electric vehicle powered with electricity stored in an on-board battery.&lt;br /&gt;
;CNG: Compressed Natural Gas.&lt;br /&gt;
;EV: Electric Vehicle. A vehicle propelled by electric motors.&lt;br /&gt;
;FCEV: Fuel Cell Electric Vehicle. An electric vehicle powered with electricity generated from a fuel cell.&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
* Naam, Ramez, May 2020. [https://rameznaam.com/2020/05/14/solars-future-is-insanely-cheap-2020/ &amp;quot;Solar’s Future is Insanely Cheap&amp;quot;]&lt;br /&gt;
* Voelcker, John, October 2018. [https://www.greencarreports.com/news/1119347_2019-hyundai-nexo-first-drive-of-380-mile-fuel-cell-crossover-utility &amp;quot;2019 Hyundai Nexo: first drive of 380-mile fuel-cell crossover utility&amp;quot;], Green Car Reports.&lt;br /&gt;
* Smith, Colin, 2 September 2020. [https://www.stuff.co.nz/motoring/122649949/hydrogen-cars-and-their-future-in-new-zealand &amp;quot;Hydrogen cars and their future in New Zealand&amp;quot;], Stuff.&lt;br /&gt;
* [https://www.nzhydrogen.org/nz-hydrogen-projects &amp;quot;Current Hydrogen projects in New Zealand&amp;quot;], Hydrogen New Zealand Association&lt;br /&gt;
* Moyle, M. P., et al., March 1960. [https://dx.doi.org/10.1002/aic.690060118 &amp;quot;Detonation Characteristics of Hydrogen-Oxygen Mixtures&amp;quot;], AIChE Journal, American Institute of Chemical Engineers.&lt;br /&gt;
* Ball, P., June 2003. [https://www.nature.com/news/2003/030609/full/news030609-14.html &amp;quot;Hydrogen fuel could widen ozone hole&amp;quot;], Nature News. DOI: [https://dx.doi.org/10.1038/news030609-14 10.1038/news030609-14]&amp;lt;!--&amp;lt;ref name=&amp;quot;nature-2003-ozone&amp;quot;&amp;gt;{{Cite web |last=Ball |first=Philip |title=Hydrogen fuel could widen ozone hole |work=Nature News |date=13 June 2003 |url= https://www.nature.com/news/2003/030609/full/news030609-14.html |access-date=17 May 2021 |doi=10.1038/news030609-14 }}&amp;lt;/ref&amp;gt;--&amp;gt;&lt;br /&gt;
* Bossel, Ulf, October 2006. [https://doi.org/10.1109/JPROC.2006.883715 &amp;quot;Does a Hydrogen Economy Make Sense?&amp;quot;] Proceedings of the IEEE &amp;#039;&amp;#039;&amp;#039;94&amp;#039;&amp;#039;&amp;#039;:10.&lt;br /&gt;
&lt;br /&gt;
== Notes ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;/div&gt;</summary>
		<author><name>Johnno</name></author>
	</entry>
	<entry>
		<id>https://wiki.jon.geek.nz/index.php?title=Score_testing&amp;diff=2491</id>
		<title>Score testing</title>
		<link rel="alternate" type="text/html" href="https://wiki.jon.geek.nz/index.php?title=Score_testing&amp;diff=2491"/>
		<updated>2023-01-20T02:36:49Z</updated>

		<summary type="html">&lt;p&gt;Johnno: /* CVE-2020-17354 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:Score_PNG_output_in_dark_theme.png|thumb|Unreadable Score extension output in dark mode]]&lt;br /&gt;
Hopefully I can get the Score extension working to produce SVG output on upstream task [https://phabricator.wikimedia.org/T49578 T49578]. The transparent PNG image normally produced needs white background styling otherwise it&amp;#039;s unreadable in dark mode.&lt;br /&gt;
;Update December 2022: my patch was merged! :) now we wait for it to be tested and deployed into Wikipedia. There are a few other issues, including some security and sandboxing concerns, e.g. CVE-2020-17354 (see below). Also, this wiki is running on a 32-bit Debian 10 (Buster), which has LilyPond 2.19 (32 bit builds not supported after 2.22). I&amp;#039;m not game enough to try and compile LilyPond myself, and I&amp;#039;m not even sure Scheme 2 runs in 32-bit(?) so I&amp;#039;m testing the SVG Score output over on my [https://mw-master.test.jon.geek.nz test instance] (which is not guaranteed to be up at all times).&lt;br /&gt;
&lt;br /&gt;
== Examples ==&lt;br /&gt;
Range of the [https://en.wikipedia.org/wiki/Contrabass_trombone contrabass trombone], as used on Wikipedia:&lt;br /&gt;
&amp;lt;score lang=&amp;quot;lilypond&amp;quot;&amp;gt;&lt;br /&gt;
  {&lt;br /&gt;
    \new Staff \with { \remove &amp;quot;Time_signature_engraver&amp;quot; }&lt;br /&gt;
    \clef bass \key c \major \cadenzaOn&lt;br /&gt;
    \ottava #-1 \tweak font-size #-2 fis,,,1 \finger \markup \text &amp;quot;poss.&amp;quot;&lt;br /&gt;
    \ottava #0  c,,1 \glissando d&amp;#039;1&lt;br /&gt;
    \tweak font-size #-2 f&amp;#039;1&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/score&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The Spear motif from &amp;#039;&amp;#039;Das Rheingold&amp;#039;&amp;#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;score lang=&amp;quot;lilypond&amp;quot;&amp;gt;&lt;br /&gt;
  \layout { ragged-right = ##t \context { \Score \omit BarNumber } }&lt;br /&gt;
  \relative g {&lt;br /&gt;
    \override DynamicTextSpanner.style = #&amp;#039;none&lt;br /&gt;
    \override Hairpin.minimum-length = #5&lt;br /&gt;
    \clef bass \key c \major&lt;br /&gt;
    g2~ \ff g8 f8 e8. d16&lt;br /&gt;
    c4 b a g  f e d c  \break&lt;br /&gt;
    b a g f  e1~ \dim\!  &amp;lt;&amp;lt; e1~ { s2 s4 s4 \&amp;gt; } &amp;gt;&amp;gt;  e4 \! \p r4 r2&lt;br /&gt;
  }&amp;lt;/score&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The Summit from &amp;#039;&amp;#039;Eine Alpensinfonie&amp;#039;&amp;#039;, which may or may not be a contrabass trombone excerpt, but probably ought to be:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;score&amp;gt;&lt;br /&gt;
\relative c, {&lt;br /&gt;
  \time 4/4&lt;br /&gt;
  \clef bass&lt;br /&gt;
  \key c \major&lt;br /&gt;
&lt;br /&gt;
  r2 r4\ff g\tenuto&lt;br /&gt;
  c2.\tenuto c4\tenuto&lt;br /&gt;
  g&amp;#039;2.\tenuto g4\tenuto&lt;br /&gt;
  c1&lt;br /&gt;
  e2~ e4.. b16&lt;br /&gt;
  a1&lt;br /&gt;
  g1&lt;br /&gt;
  c8 r8 r4 r2&lt;br /&gt;
  \bar &amp;quot;|.&amp;quot;&lt;br /&gt;
} &lt;br /&gt;
&amp;lt;/score&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== CVE-2020-17354 ==&lt;br /&gt;
&lt;br /&gt;
See [https://phabricator.wikimedia.org/T259210 T259210]. Looks like this has been fixed (assuming we&amp;#039;re supposed to see the system id in the rendered music); can&amp;#039;t reproduce as currently stands, with LilyPond 2.19 (Buster), MediaWiki on REL1_35 and Score on REL1_35.&lt;br /&gt;
&lt;br /&gt;
1. PoC from task: &amp;lt;score raw=1&amp;gt; \header { tagline = ##f } &lt;br /&gt;
{&lt;br /&gt;
  \relative { c&amp;#039; }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#(begin&lt;br /&gt;
  (define location 1)&lt;br /&gt;
  (display &amp;quot;With output-def-scope\n&amp;quot;)&lt;br /&gt;
  (eval &amp;#039;(system &amp;quot;id&amp;quot;) (ly:output-def-scope #{ \midi {} #}))&lt;br /&gt;
  (display &amp;quot;With output-def-lookup\n&amp;quot;)&lt;br /&gt;
  ((ly:output-def-lookup #{ \midi {} #} &amp;#039;system) &amp;quot;id&amp;quot;)&lt;br /&gt;
)&lt;br /&gt;
&amp;lt;/score&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2. Notehead stencil hack PoC, contributed in [https://phabricator.wikimedia.org/T259210#6368852 comment] from LilyPond developer Han-wen Nienhuys: &amp;lt;score raw=1&amp;gt; \header { tagline = ##f }&lt;br /&gt;
{&lt;br /&gt;
  \override NoteHead.text = \system&lt;br /&gt;
  \override NoteHead.stencil =&lt;br /&gt;
  #(lambda (grob)&lt;br /&gt;
    ((cdr (assoc &amp;#039;text&lt;br /&gt;
	   (cadr (ly:grob-alist-chain grob &amp;#039;())))) &amp;quot;id&amp;quot;)&lt;br /&gt;
    #f)&lt;br /&gt;
  c4&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/score&amp;gt;&lt;/div&gt;</summary>
		<author><name>Johnno</name></author>
	</entry>
	<entry>
		<id>https://wiki.jon.geek.nz/index.php?title=Score_testing&amp;diff=2490</id>
		<title>Score testing</title>
		<link rel="alternate" type="text/html" href="https://wiki.jon.geek.nz/index.php?title=Score_testing&amp;diff=2490"/>
		<updated>2023-01-20T02:26:44Z</updated>

		<summary type="html">&lt;p&gt;Johnno: /* CVE-2020-17354 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:Score_PNG_output_in_dark_theme.png|thumb|Unreadable Score extension output in dark mode]]&lt;br /&gt;
Hopefully I can get the Score extension working to produce SVG output on upstream task [https://phabricator.wikimedia.org/T49578 T49578]. The transparent PNG image normally produced needs white background styling otherwise it&amp;#039;s unreadable in dark mode.&lt;br /&gt;
;Update December 2022: my patch was merged! :) now we wait for it to be tested and deployed into Wikipedia. There are a few other issues, including some security and sandboxing concerns, e.g. CVE-2020-17354 (see below). Also, this wiki is running on a 32-bit Debian 10 (Buster), which has LilyPond 2.19 (32 bit builds not supported after 2.22). I&amp;#039;m not game enough to try and compile LilyPond myself, and I&amp;#039;m not even sure Scheme 2 runs in 32-bit(?) so I&amp;#039;m testing the SVG Score output over on my [https://mw-master.test.jon.geek.nz test instance] (which is not guaranteed to be up at all times).&lt;br /&gt;
&lt;br /&gt;
== Examples ==&lt;br /&gt;
Range of the [https://en.wikipedia.org/wiki/Contrabass_trombone contrabass trombone], as used on Wikipedia:&lt;br /&gt;
&amp;lt;score lang=&amp;quot;lilypond&amp;quot;&amp;gt;&lt;br /&gt;
  {&lt;br /&gt;
    \new Staff \with { \remove &amp;quot;Time_signature_engraver&amp;quot; }&lt;br /&gt;
    \clef bass \key c \major \cadenzaOn&lt;br /&gt;
    \ottava #-1 \tweak font-size #-2 fis,,,1 \finger \markup \text &amp;quot;poss.&amp;quot;&lt;br /&gt;
    \ottava #0  c,,1 \glissando d&amp;#039;1&lt;br /&gt;
    \tweak font-size #-2 f&amp;#039;1&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/score&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The Spear motif from &amp;#039;&amp;#039;Das Rheingold&amp;#039;&amp;#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;score lang=&amp;quot;lilypond&amp;quot;&amp;gt;&lt;br /&gt;
  \layout { ragged-right = ##t \context { \Score \omit BarNumber } }&lt;br /&gt;
  \relative g {&lt;br /&gt;
    \override DynamicTextSpanner.style = #&amp;#039;none&lt;br /&gt;
    \override Hairpin.minimum-length = #5&lt;br /&gt;
    \clef bass \key c \major&lt;br /&gt;
    g2~ \ff g8 f8 e8. d16&lt;br /&gt;
    c4 b a g  f e d c  \break&lt;br /&gt;
    b a g f  e1~ \dim\!  &amp;lt;&amp;lt; e1~ { s2 s4 s4 \&amp;gt; } &amp;gt;&amp;gt;  e4 \! \p r4 r2&lt;br /&gt;
  }&amp;lt;/score&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The Summit from &amp;#039;&amp;#039;Eine Alpensinfonie&amp;#039;&amp;#039;, which may or may not be a contrabass trombone excerpt, but probably ought to be:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;score&amp;gt;&lt;br /&gt;
\relative c, {&lt;br /&gt;
  \time 4/4&lt;br /&gt;
  \clef bass&lt;br /&gt;
  \key c \major&lt;br /&gt;
&lt;br /&gt;
  r2 r4\ff g\tenuto&lt;br /&gt;
  c2.\tenuto c4\tenuto&lt;br /&gt;
  g&amp;#039;2.\tenuto g4\tenuto&lt;br /&gt;
  c1&lt;br /&gt;
  e2~ e4.. b16&lt;br /&gt;
  a1&lt;br /&gt;
  g1&lt;br /&gt;
  c8 r8 r4 r2&lt;br /&gt;
  \bar &amp;quot;|.&amp;quot;&lt;br /&gt;
} &lt;br /&gt;
&amp;lt;/score&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== CVE-2020-17354 ==&lt;br /&gt;
&lt;br /&gt;
See [https://phabricator.wikimedia.org/T259210 T259210]. Looks like this has been fixed (assuming we&amp;#039;re supposed to see the system id in the rendered music); can&amp;#039;t reproduce as currently stands, with LilyPond 2.19 (Buster), MediaWiki on REL1_35 and Score on master.&lt;br /&gt;
&lt;br /&gt;
1. PoC from task: &amp;lt;score raw=1&amp;gt; \header { tagline = ##f } &lt;br /&gt;
{&lt;br /&gt;
  \relative { c&amp;#039; }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#(begin&lt;br /&gt;
  (define location 1)&lt;br /&gt;
  (display &amp;quot;With output-def-scope\n&amp;quot;)&lt;br /&gt;
  (eval &amp;#039;(system &amp;quot;id&amp;quot;) (ly:output-def-scope #{ \midi {} #}))&lt;br /&gt;
  (display &amp;quot;With output-def-lookup\n&amp;quot;)&lt;br /&gt;
  ((ly:output-def-lookup #{ \midi {} #} &amp;#039;system) &amp;quot;id&amp;quot;)&lt;br /&gt;
)&lt;br /&gt;
&amp;lt;/score&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2. Notehead stencil hack PoC, contributed in [https://phabricator.wikimedia.org/T259210#6368852 comment] from LilyPond developer Han-wen Nienhuys: &amp;lt;score raw=1&amp;gt; \header { tagline = ##f }&lt;br /&gt;
{&lt;br /&gt;
  \override NoteHead.text = \system&lt;br /&gt;
  \override NoteHead.stencil =&lt;br /&gt;
  #(lambda (grob)&lt;br /&gt;
    ((cdr (assoc &amp;#039;text&lt;br /&gt;
	   (cadr (ly:grob-alist-chain grob &amp;#039;())))) &amp;quot;id&amp;quot;)&lt;br /&gt;
    #f)&lt;br /&gt;
  c4&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/score&amp;gt;&lt;/div&gt;</summary>
		<author><name>Johnno</name></author>
	</entry>
	<entry>
		<id>https://wiki.jon.geek.nz/index.php?title=Score_testing&amp;diff=2489</id>
		<title>Score testing</title>
		<link rel="alternate" type="text/html" href="https://wiki.jon.geek.nz/index.php?title=Score_testing&amp;diff=2489"/>
		<updated>2023-01-20T02:25:42Z</updated>

		<summary type="html">&lt;p&gt;Johnno: /* CVE-2020-17354 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:Score_PNG_output_in_dark_theme.png|thumb|Unreadable Score extension output in dark mode]]&lt;br /&gt;
Hopefully I can get the Score extension working to produce SVG output on upstream task [https://phabricator.wikimedia.org/T49578 T49578]. The transparent PNG image normally produced needs white background styling otherwise it&amp;#039;s unreadable in dark mode.&lt;br /&gt;
;Update December 2022: my patch was merged! :) now we wait for it to be tested and deployed into Wikipedia. There are a few other issues, including some security and sandboxing concerns, e.g. CVE-2020-17354 (see below). Also, this wiki is running on a 32-bit Debian 10 (Buster), which has LilyPond 2.19 (32 bit builds not supported after 2.22). I&amp;#039;m not game enough to try and compile LilyPond myself, and I&amp;#039;m not even sure Scheme 2 runs in 32-bit(?) so I&amp;#039;m testing the SVG Score output over on my [https://mw-master.test.jon.geek.nz test instance] (which is not guaranteed to be up at all times).&lt;br /&gt;
&lt;br /&gt;
== Examples ==&lt;br /&gt;
Range of the [https://en.wikipedia.org/wiki/Contrabass_trombone contrabass trombone], as used on Wikipedia:&lt;br /&gt;
&amp;lt;score lang=&amp;quot;lilypond&amp;quot;&amp;gt;&lt;br /&gt;
  {&lt;br /&gt;
    \new Staff \with { \remove &amp;quot;Time_signature_engraver&amp;quot; }&lt;br /&gt;
    \clef bass \key c \major \cadenzaOn&lt;br /&gt;
    \ottava #-1 \tweak font-size #-2 fis,,,1 \finger \markup \text &amp;quot;poss.&amp;quot;&lt;br /&gt;
    \ottava #0  c,,1 \glissando d&amp;#039;1&lt;br /&gt;
    \tweak font-size #-2 f&amp;#039;1&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/score&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The Spear motif from &amp;#039;&amp;#039;Das Rheingold&amp;#039;&amp;#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;score lang=&amp;quot;lilypond&amp;quot;&amp;gt;&lt;br /&gt;
  \layout { ragged-right = ##t \context { \Score \omit BarNumber } }&lt;br /&gt;
  \relative g {&lt;br /&gt;
    \override DynamicTextSpanner.style = #&amp;#039;none&lt;br /&gt;
    \override Hairpin.minimum-length = #5&lt;br /&gt;
    \clef bass \key c \major&lt;br /&gt;
    g2~ \ff g8 f8 e8. d16&lt;br /&gt;
    c4 b a g  f e d c  \break&lt;br /&gt;
    b a g f  e1~ \dim\!  &amp;lt;&amp;lt; e1~ { s2 s4 s4 \&amp;gt; } &amp;gt;&amp;gt;  e4 \! \p r4 r2&lt;br /&gt;
  }&amp;lt;/score&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The Summit from &amp;#039;&amp;#039;Eine Alpensinfonie&amp;#039;&amp;#039;, which may or may not be a contrabass trombone excerpt, but probably ought to be:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;score&amp;gt;&lt;br /&gt;
\relative c, {&lt;br /&gt;
  \time 4/4&lt;br /&gt;
  \clef bass&lt;br /&gt;
  \key c \major&lt;br /&gt;
&lt;br /&gt;
  r2 r4\ff g\tenuto&lt;br /&gt;
  c2.\tenuto c4\tenuto&lt;br /&gt;
  g&amp;#039;2.\tenuto g4\tenuto&lt;br /&gt;
  c1&lt;br /&gt;
  e2~ e4.. b16&lt;br /&gt;
  a1&lt;br /&gt;
  g1&lt;br /&gt;
  c8 r8 r4 r2&lt;br /&gt;
  \bar &amp;quot;|.&amp;quot;&lt;br /&gt;
} &lt;br /&gt;
&amp;lt;/score&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== CVE-2020-17354 ==&lt;br /&gt;
&lt;br /&gt;
See [https://phabricator.wikimedia.org/T259210 T259210]. Looks like this has been fixed (assuming we&amp;#039;re supposed to see the system id in the rendered music); can&amp;#039;t reproduce as currently stands, with LilyPond 2.19 (Buster), MediaWiki on REL1_39 and Score on master.&lt;br /&gt;
&lt;br /&gt;
1. PoC from task: &amp;lt;score raw=1&amp;gt; \header { tagline = ##f } &lt;br /&gt;
{&lt;br /&gt;
  \relative { c&amp;#039; }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#(begin&lt;br /&gt;
  (define location 1)&lt;br /&gt;
  (display &amp;quot;With output-def-scope\n&amp;quot;)&lt;br /&gt;
  (eval &amp;#039;(system &amp;quot;id&amp;quot;) (ly:output-def-scope #{ \midi {} #}))&lt;br /&gt;
  (display &amp;quot;With output-def-lookup\n&amp;quot;)&lt;br /&gt;
  ((ly:output-def-lookup #{ \midi {} #} &amp;#039;system) &amp;quot;id&amp;quot;)&lt;br /&gt;
)&lt;br /&gt;
&amp;lt;/score&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2. Notehead stencil hack PoC, contributed in [https://phabricator.wikimedia.org/T259210#6368852 comment] from LilyPond developer Han-wen Nienhuys: &amp;lt;score raw=1&amp;gt; \header { tagline = ##f }&lt;br /&gt;
{&lt;br /&gt;
  \override NoteHead.text = \system&lt;br /&gt;
  \override NoteHead.stencil =&lt;br /&gt;
  #(lambda (grob)&lt;br /&gt;
    ((cdr (assoc &amp;#039;text&lt;br /&gt;
	   (cadr (ly:grob-alist-chain grob &amp;#039;())))) &amp;quot;id&amp;quot;)&lt;br /&gt;
    #f)&lt;br /&gt;
  c4&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/score&amp;gt;&lt;/div&gt;</summary>
		<author><name>Johnno</name></author>
	</entry>
	<entry>
		<id>https://wiki.jon.geek.nz/index.php?title=Score_testing&amp;diff=2488</id>
		<title>Score testing</title>
		<link rel="alternate" type="text/html" href="https://wiki.jon.geek.nz/index.php?title=Score_testing&amp;diff=2488"/>
		<updated>2023-01-20T02:22:59Z</updated>

		<summary type="html">&lt;p&gt;Johnno: /* CV-2020-17354 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:Score_PNG_output_in_dark_theme.png|thumb|Unreadable Score extension output in dark mode]]&lt;br /&gt;
Hopefully I can get the Score extension working to produce SVG output on upstream task [https://phabricator.wikimedia.org/T49578 T49578]. The transparent PNG image normally produced needs white background styling otherwise it&amp;#039;s unreadable in dark mode.&lt;br /&gt;
;Update December 2022: my patch was merged! :) now we wait for it to be tested and deployed into Wikipedia. There are a few other issues, including some security and sandboxing concerns, e.g. CVE-2020-17354 (see below). Also, this wiki is running on a 32-bit Debian 10 (Buster), which has LilyPond 2.19 (32 bit builds not supported after 2.22). I&amp;#039;m not game enough to try and compile LilyPond myself, and I&amp;#039;m not even sure Scheme 2 runs in 32-bit(?) so I&amp;#039;m testing the SVG Score output over on my [https://mw-master.test.jon.geek.nz test instance] (which is not guaranteed to be up at all times).&lt;br /&gt;
&lt;br /&gt;
== Examples ==&lt;br /&gt;
Range of the [https://en.wikipedia.org/wiki/Contrabass_trombone contrabass trombone], as used on Wikipedia:&lt;br /&gt;
&amp;lt;score lang=&amp;quot;lilypond&amp;quot;&amp;gt;&lt;br /&gt;
  {&lt;br /&gt;
    \new Staff \with { \remove &amp;quot;Time_signature_engraver&amp;quot; }&lt;br /&gt;
    \clef bass \key c \major \cadenzaOn&lt;br /&gt;
    \ottava #-1 \tweak font-size #-2 fis,,,1 \finger \markup \text &amp;quot;poss.&amp;quot;&lt;br /&gt;
    \ottava #0  c,,1 \glissando d&amp;#039;1&lt;br /&gt;
    \tweak font-size #-2 f&amp;#039;1&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/score&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The Spear motif from &amp;#039;&amp;#039;Das Rheingold&amp;#039;&amp;#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;score lang=&amp;quot;lilypond&amp;quot;&amp;gt;&lt;br /&gt;
  \layout { ragged-right = ##t \context { \Score \omit BarNumber } }&lt;br /&gt;
  \relative g {&lt;br /&gt;
    \override DynamicTextSpanner.style = #&amp;#039;none&lt;br /&gt;
    \override Hairpin.minimum-length = #5&lt;br /&gt;
    \clef bass \key c \major&lt;br /&gt;
    g2~ \ff g8 f8 e8. d16&lt;br /&gt;
    c4 b a g  f e d c  \break&lt;br /&gt;
    b a g f  e1~ \dim\!  &amp;lt;&amp;lt; e1~ { s2 s4 s4 \&amp;gt; } &amp;gt;&amp;gt;  e4 \! \p r4 r2&lt;br /&gt;
  }&amp;lt;/score&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The Summit from &amp;#039;&amp;#039;Eine Alpensinfonie&amp;#039;&amp;#039;, which may or may not be a contrabass trombone excerpt, but probably ought to be:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;score&amp;gt;&lt;br /&gt;
\relative c, {&lt;br /&gt;
  \time 4/4&lt;br /&gt;
  \clef bass&lt;br /&gt;
  \key c \major&lt;br /&gt;
&lt;br /&gt;
  r2 r4\ff g\tenuto&lt;br /&gt;
  c2.\tenuto c4\tenuto&lt;br /&gt;
  g&amp;#039;2.\tenuto g4\tenuto&lt;br /&gt;
  c1&lt;br /&gt;
  e2~ e4.. b16&lt;br /&gt;
  a1&lt;br /&gt;
  g1&lt;br /&gt;
  c8 r8 r4 r2&lt;br /&gt;
  \bar &amp;quot;|.&amp;quot;&lt;br /&gt;
} &lt;br /&gt;
&amp;lt;/score&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== CVE-2020-17354 ==&lt;br /&gt;
&lt;br /&gt;
See [https://phabricator.wikimedia.org/T259210 T259210]. Looks like either the syntax of the vuln PoC needs updating, and/or they&amp;#039;ve been fixed. Can&amp;#039;t reproduce as currently stands, with LilyPond 2.19 (Buster), MediaWiki on REL1_39 and Score on master.&lt;br /&gt;
&lt;br /&gt;
1. PoC from task: &amp;lt;score raw=1&amp;gt; \header { tagline = ##f } &lt;br /&gt;
{&lt;br /&gt;
  \relative { c&amp;#039; }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#(begin&lt;br /&gt;
  (define location 1)&lt;br /&gt;
  (display &amp;quot;With output-def-scope\n&amp;quot;)&lt;br /&gt;
  (eval &amp;#039;(system &amp;quot;id&amp;quot;) (ly:output-def-scope #{ \midi {} #}))&lt;br /&gt;
  (display &amp;quot;With output-def-lookup\n&amp;quot;)&lt;br /&gt;
  ((ly:output-def-lookup #{ \midi {} #} &amp;#039;system) &amp;quot;id&amp;quot;)&lt;br /&gt;
)&lt;br /&gt;
&amp;lt;/score&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2. Notehead stencil hack PoC, contributed in [https://phabricator.wikimedia.org/T259210#6368852 comment] from LilyPond developer Han-wen Nienhuys: &amp;lt;score raw=1&amp;gt; \header { tagline = ##f }&lt;br /&gt;
{&lt;br /&gt;
  \override NoteHead.text = \system&lt;br /&gt;
  \override NoteHead.stencil =&lt;br /&gt;
  #(lambda (grob)&lt;br /&gt;
    ((cdr (assoc &amp;#039;text&lt;br /&gt;
	   (cadr (ly:grob-alist-chain grob &amp;#039;())))) &amp;quot;id&amp;quot;)&lt;br /&gt;
    #f)&lt;br /&gt;
  c4&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/score&amp;gt;&lt;/div&gt;</summary>
		<author><name>Johnno</name></author>
	</entry>
	<entry>
		<id>https://wiki.jon.geek.nz/index.php?title=Score_testing&amp;diff=2487</id>
		<title>Score testing</title>
		<link rel="alternate" type="text/html" href="https://wiki.jon.geek.nz/index.php?title=Score_testing&amp;diff=2487"/>
		<updated>2023-01-20T01:40:24Z</updated>

		<summary type="html">&lt;p&gt;Johnno: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:Score_PNG_output_in_dark_theme.png|thumb|Unreadable Score extension output in dark mode]]&lt;br /&gt;
Hopefully I can get the Score extension working to produce SVG output on upstream task [https://phabricator.wikimedia.org/T49578 T49578]. The transparent PNG image normally produced needs white background styling otherwise it&amp;#039;s unreadable in dark mode.&lt;br /&gt;
;Update December 2022: my patch was merged! :) now we wait for it to be tested and deployed into Wikipedia. There are a few other issues, including some security and sandboxing concerns, e.g. CVE-2020-17354 (see below). Also, this wiki is running on a 32-bit Debian 10 (Buster), which has LilyPond 2.19 (32 bit builds not supported after 2.22). I&amp;#039;m not game enough to try and compile LilyPond myself, and I&amp;#039;m not even sure Scheme 2 runs in 32-bit(?) so I&amp;#039;m testing the SVG Score output over on my [https://mw-master.test.jon.geek.nz test instance] (which is not guaranteed to be up at all times).&lt;br /&gt;
&lt;br /&gt;
== Examples ==&lt;br /&gt;
Range of the [https://en.wikipedia.org/wiki/Contrabass_trombone contrabass trombone], as used on Wikipedia:&lt;br /&gt;
&amp;lt;score lang=&amp;quot;lilypond&amp;quot;&amp;gt;&lt;br /&gt;
  {&lt;br /&gt;
    \new Staff \with { \remove &amp;quot;Time_signature_engraver&amp;quot; }&lt;br /&gt;
    \clef bass \key c \major \cadenzaOn&lt;br /&gt;
    \ottava #-1 \tweak font-size #-2 fis,,,1 \finger \markup \text &amp;quot;poss.&amp;quot;&lt;br /&gt;
    \ottava #0  c,,1 \glissando d&amp;#039;1&lt;br /&gt;
    \tweak font-size #-2 f&amp;#039;1&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/score&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The Spear motif from &amp;#039;&amp;#039;Das Rheingold&amp;#039;&amp;#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;score lang=&amp;quot;lilypond&amp;quot;&amp;gt;&lt;br /&gt;
  \layout { ragged-right = ##t \context { \Score \omit BarNumber } }&lt;br /&gt;
  \relative g {&lt;br /&gt;
    \override DynamicTextSpanner.style = #&amp;#039;none&lt;br /&gt;
    \override Hairpin.minimum-length = #5&lt;br /&gt;
    \clef bass \key c \major&lt;br /&gt;
    g2~ \ff g8 f8 e8. d16&lt;br /&gt;
    c4 b a g  f e d c  \break&lt;br /&gt;
    b a g f  e1~ \dim\!  &amp;lt;&amp;lt; e1~ { s2 s4 s4 \&amp;gt; } &amp;gt;&amp;gt;  e4 \! \p r4 r2&lt;br /&gt;
  }&amp;lt;/score&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The Summit from &amp;#039;&amp;#039;Eine Alpensinfonie&amp;#039;&amp;#039;, which may or may not be a contrabass trombone excerpt, but probably ought to be:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;score&amp;gt;&lt;br /&gt;
\relative c, {&lt;br /&gt;
  \time 4/4&lt;br /&gt;
  \clef bass&lt;br /&gt;
  \key c \major&lt;br /&gt;
&lt;br /&gt;
  r2 r4\ff g\tenuto&lt;br /&gt;
  c2.\tenuto c4\tenuto&lt;br /&gt;
  g&amp;#039;2.\tenuto g4\tenuto&lt;br /&gt;
  c1&lt;br /&gt;
  e2~ e4.. b16&lt;br /&gt;
  a1&lt;br /&gt;
  g1&lt;br /&gt;
  c8 r8 r4 r2&lt;br /&gt;
  \bar &amp;quot;|.&amp;quot;&lt;br /&gt;
} &lt;br /&gt;
&amp;lt;/score&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== CV-2020-17354 ==&lt;br /&gt;
&lt;br /&gt;
See [https://phabricator.wikimedia.org/T259210 T259210]. Looks like either the syntax of the vuln PoC needs updating, and/or they&amp;#039;ve been fixed. Can&amp;#039;t reproduce as currently stands, with LilyPond 2.19 (Buster), MediaWiki on REL1_39 and Score on master.&lt;br /&gt;
&lt;br /&gt;
1. PoC from task: &amp;lt;score raw=1&amp;gt; \header { tagline = ##f } &lt;br /&gt;
{&lt;br /&gt;
  \relative { c&amp;#039; }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#(begin&lt;br /&gt;
  (define location 1)&lt;br /&gt;
  (display &amp;quot;With output-def-scope\n&amp;quot;)&lt;br /&gt;
  (eval &amp;#039;(system &amp;quot;id&amp;quot;) (ly:output-def-scope #{ \midi {} #}))&lt;br /&gt;
  (display &amp;quot;With output-def-lookup\n&amp;quot;)&lt;br /&gt;
  ((ly:output-def-lookup #{ \midi {} #} &amp;#039;system) &amp;quot;id&amp;quot;)&lt;br /&gt;
)&lt;br /&gt;
&amp;lt;/score&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2. Notehead stencil hack PoC, contributed in [https://phabricator.wikimedia.org/T259210#6368852 comment] from LilyPond developer Han-wen Nienhuys: &amp;lt;score raw=1&amp;gt; \header { tagline = ##f }&lt;br /&gt;
{&lt;br /&gt;
  \override NoteHead.text = \system&lt;br /&gt;
  \override NoteHead.stencil =&lt;br /&gt;
  #(lambda (grob)&lt;br /&gt;
    ((cdr (assoc &amp;#039;text&lt;br /&gt;
	   (cadr (ly:grob-alist-chain grob &amp;#039;())))) &amp;quot;id&amp;quot;)&lt;br /&gt;
    #f)&lt;br /&gt;
  c4&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/score&amp;gt;&lt;/div&gt;</summary>
		<author><name>Johnno</name></author>
	</entry>
	<entry>
		<id>https://wiki.jon.geek.nz/index.php?title=Score_testing&amp;diff=2486</id>
		<title>Score testing</title>
		<link rel="alternate" type="text/html" href="https://wiki.jon.geek.nz/index.php?title=Score_testing&amp;diff=2486"/>
		<updated>2023-01-20T01:28:19Z</updated>

		<summary type="html">&lt;p&gt;Johnno: /* CV-2020-17354 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:Score_PNG_output_in_dark_theme.png|thumb|Unreadable Score extension output in dark mode]]&lt;br /&gt;
Hopefully I can get the Score extension working to produce SVG output on upstream task [https://phabricator.wikimedia.org/T49578 T49578]. The transparent PNG image normally produced needs white background styling otherwise it&amp;#039;s unreadable in dark mode.&lt;br /&gt;
;Update December 2022: my patch was merged! :) now we wait for it to be tested and deployed into Wikipedia. There are a few other issues, including some security and sandboxing concerns, e.g. CVE-2020-17354 (see below). Also, this wiki is running on a 32-bit Debian 10 (Buster), which has LilyPond 2.19 (32 bit builds not supported after 2.22). I&amp;#039;m not game enough to try and compile LilyPond myself, and I&amp;#039;m not even sure Scheme 2 runs in 32-bit(?) so I&amp;#039;m testing the SVG Score output over on my [https://mw-master.test.jon.geek.nz test instance] (which is not guaranteed to be up at all times).&lt;br /&gt;
&lt;br /&gt;
== Examples ==&lt;br /&gt;
Range of the [https://en.wikipedia.org/wiki/Contrabass_trombone contrabass trombone], as used on Wikipedia:&lt;br /&gt;
&amp;lt;score lang=&amp;quot;lilypond&amp;quot;&amp;gt;&lt;br /&gt;
  {&lt;br /&gt;
    \new Staff \with { \remove &amp;quot;Time_signature_engraver&amp;quot; }&lt;br /&gt;
    \clef bass \key c \major \cadenzaOn&lt;br /&gt;
    \ottava #-1 \tweak font-size #-2 fis,,,1 \finger \markup \text &amp;quot;poss.&amp;quot;&lt;br /&gt;
    \ottava #0  c,,1 \glissando d&amp;#039;1&lt;br /&gt;
    \tweak font-size #-2 f&amp;#039;1&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/score&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The Spear motif from &amp;#039;&amp;#039;Das Rheingold&amp;#039;&amp;#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;score lang=&amp;quot;lilypond&amp;quot;&amp;gt;&lt;br /&gt;
  \layout { ragged-right = ##t \context { \Score \omit BarNumber } }&lt;br /&gt;
  \relative g {&lt;br /&gt;
    \override DynamicTextSpanner.style = #&amp;#039;none&lt;br /&gt;
    \override Hairpin.minimum-length = #5&lt;br /&gt;
    \clef bass \key c \major&lt;br /&gt;
    g2~ \ff g8 f8 e8. d16&lt;br /&gt;
    c4 b a g  f e d c  \break&lt;br /&gt;
    b a g f  e1~ \dim\!  &amp;lt;&amp;lt; e1~ { s2 s4 s4 \&amp;gt; } &amp;gt;&amp;gt;  e4 \! \p r4 r2&lt;br /&gt;
  }&amp;lt;/score&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The Summit from &amp;#039;&amp;#039;Eine Alpensinfonie&amp;#039;&amp;#039;, which may or may not be a contrabass trombone excerpt, but probably ought to be:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;score&amp;gt;&lt;br /&gt;
\relative c, {&lt;br /&gt;
  \time 4/4&lt;br /&gt;
  \clef bass&lt;br /&gt;
  \key c \major&lt;br /&gt;
&lt;br /&gt;
  r2 r4\ff g\tenuto&lt;br /&gt;
  c2.\tenuto c4\tenuto&lt;br /&gt;
  g&amp;#039;2.\tenuto g4\tenuto&lt;br /&gt;
  c1&lt;br /&gt;
  e2~ e4.. b16&lt;br /&gt;
  a1&lt;br /&gt;
  g1&lt;br /&gt;
  c8 r8 r4 r2&lt;br /&gt;
  \bar &amp;quot;|.&amp;quot;&lt;br /&gt;
} &lt;br /&gt;
&amp;lt;/score&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== CV-2020-17354 ==&lt;br /&gt;
&lt;br /&gt;
See [https://phabricator.wikimedia.org/T259210 T259210]. Looks like either the syntax of the vuln PoC needs updating, and/or they&amp;#039;ve been fixed. Can&amp;#039;t repro as currently stands, with LilyPond 2.19 (Buster), MediaWiki on REL1_39 and Score on master.&lt;br /&gt;
&lt;br /&gt;
1. With defined location: &amp;lt;score raw=1&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  \relative { c&amp;#039; }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#(begin&lt;br /&gt;
  (define location 1)&lt;br /&gt;
  (display &amp;quot;With output-def-scope\n&amp;quot;)&lt;br /&gt;
  (eval &amp;#039;(system &amp;quot;id&amp;quot;) (ly:output-def-scope #{ \midi {} #}))&lt;br /&gt;
  (display &amp;quot;With output-def-lookup\n&amp;quot;)&lt;br /&gt;
  ((ly:output-def-lookup #{ \midi {} #} &amp;#039;system) &amp;quot;id&amp;quot;)&lt;br /&gt;
)&lt;br /&gt;
&amp;lt;/score&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2. and without: &amp;lt;score raw=1&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  \relative { c&amp;#039; }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#(begin&lt;br /&gt;
  (display &amp;quot;With output-def-scope\n&amp;quot;)&lt;br /&gt;
  (eval &amp;#039;(system &amp;quot;id&amp;quot;) (ly:output-def-scope #{ \midi {} #}))&lt;br /&gt;
  (display &amp;quot;With output-def-lookup\n&amp;quot;)&lt;br /&gt;
  ((ly:output-def-lookup #{ \midi {} #} &amp;#039;system) &amp;quot;id&amp;quot;)&lt;br /&gt;
)&lt;br /&gt;
&amp;lt;/score&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3. Variant in comment from Han-wen Nienhuys: &amp;lt;score&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
  \override NoteHead.text = \system&lt;br /&gt;
  \override NoteHead.stencil =&lt;br /&gt;
  #(lambda (grob)&lt;br /&gt;
    ((cdr (assoc &amp;#039;text&lt;br /&gt;
	   (cadr (ly:grob-alist-chain grob &amp;#039;())))) &amp;quot;id&amp;quot;)&lt;br /&gt;
    #f)&lt;br /&gt;
  c4&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/score&amp;gt;&lt;/div&gt;</summary>
		<author><name>Johnno</name></author>
	</entry>
	<entry>
		<id>https://wiki.jon.geek.nz/index.php?title=Score_testing&amp;diff=2485</id>
		<title>Score testing</title>
		<link rel="alternate" type="text/html" href="https://wiki.jon.geek.nz/index.php?title=Score_testing&amp;diff=2485"/>
		<updated>2023-01-19T22:20:55Z</updated>

		<summary type="html">&lt;p&gt;Johnno: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:Score_PNG_output_in_dark_theme.png|thumb|Unreadable Score extension output in dark mode]]&lt;br /&gt;
Hopefully I can get the Score extension working to produce SVG output on upstream task [https://phabricator.wikimedia.org/T49578 T49578]. The transparent PNG image normally produced needs white background styling otherwise it&amp;#039;s unreadable in dark mode.&lt;br /&gt;
;Update December 2022: my patch was merged! :) now we wait for it to be tested and deployed into Wikipedia. There are a few other issues, including some security and sandboxing concerns, e.g. CVE-2020-17354 (see below). Also, this wiki is running on a 32-bit Debian 10 (Buster), which has LilyPond 2.19 (32 bit builds not supported after 2.22). I&amp;#039;m not game enough to try and compile LilyPond myself, and I&amp;#039;m not even sure Scheme 2 runs in 32-bit(?) so I&amp;#039;m testing the SVG Score output over on my [https://mw-master.test.jon.geek.nz test instance] (which is not guaranteed to be up at all times).&lt;br /&gt;
&lt;br /&gt;
== Examples ==&lt;br /&gt;
Range of the [https://en.wikipedia.org/wiki/Contrabass_trombone contrabass trombone], as used on Wikipedia:&lt;br /&gt;
&amp;lt;score lang=&amp;quot;lilypond&amp;quot;&amp;gt;&lt;br /&gt;
  {&lt;br /&gt;
    \new Staff \with { \remove &amp;quot;Time_signature_engraver&amp;quot; }&lt;br /&gt;
    \clef bass \key c \major \cadenzaOn&lt;br /&gt;
    \ottava #-1 \tweak font-size #-2 fis,,,1 \finger \markup \text &amp;quot;poss.&amp;quot;&lt;br /&gt;
    \ottava #0  c,,1 \glissando d&amp;#039;1&lt;br /&gt;
    \tweak font-size #-2 f&amp;#039;1&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/score&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The Spear motif from &amp;#039;&amp;#039;Das Rheingold&amp;#039;&amp;#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;score lang=&amp;quot;lilypond&amp;quot;&amp;gt;&lt;br /&gt;
  \layout { ragged-right = ##t \context { \Score \omit BarNumber } }&lt;br /&gt;
  \relative g {&lt;br /&gt;
    \override DynamicTextSpanner.style = #&amp;#039;none&lt;br /&gt;
    \override Hairpin.minimum-length = #5&lt;br /&gt;
    \clef bass \key c \major&lt;br /&gt;
    g2~ \ff g8 f8 e8. d16&lt;br /&gt;
    c4 b a g  f e d c  \break&lt;br /&gt;
    b a g f  e1~ \dim\!  &amp;lt;&amp;lt; e1~ { s2 s4 s4 \&amp;gt; } &amp;gt;&amp;gt;  e4 \! \p r4 r2&lt;br /&gt;
  }&amp;lt;/score&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The Summit from &amp;#039;&amp;#039;Eine Alpensinfonie&amp;#039;&amp;#039;, which may or may not be a contrabass trombone excerpt, but probably ought to be:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;score&amp;gt;&lt;br /&gt;
\relative c, {&lt;br /&gt;
  \time 4/4&lt;br /&gt;
  \clef bass&lt;br /&gt;
  \key c \major&lt;br /&gt;
&lt;br /&gt;
  r2 r4\ff g\tenuto&lt;br /&gt;
  c2.\tenuto c4\tenuto&lt;br /&gt;
  g&amp;#039;2.\tenuto g4\tenuto&lt;br /&gt;
  c1&lt;br /&gt;
  e2~ e4.. b16&lt;br /&gt;
  a1&lt;br /&gt;
  g1&lt;br /&gt;
  c8 r8 r4 r2&lt;br /&gt;
  \bar &amp;quot;|.&amp;quot;&lt;br /&gt;
} &lt;br /&gt;
&amp;lt;/score&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== CV-2020-17354 ==&lt;br /&gt;
&lt;br /&gt;
See [https://phabricator.wikimedia.org/T259210 T259210]. Looks like either the syntax of the vuln PoC needs updating, and/or they&amp;#039;ve been fixed. Can&amp;#039;t repro as currently stands, with LilyPond 2.19 (Buster), MediaWiki on REL1_39 and Score on master.&lt;br /&gt;
&lt;br /&gt;
1. With defined location: &amp;lt;score&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  \relative { c&amp;#039; }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#(begin&lt;br /&gt;
  (define location 1)&lt;br /&gt;
  (display &amp;quot;With output-def-scope\n&amp;quot;)&lt;br /&gt;
  (eval &amp;#039;(system &amp;quot;id&amp;quot;) (ly:output-def-scope #{ \midi {} #}))&lt;br /&gt;
  (display &amp;quot;With output-def-lookup\n&amp;quot;)&lt;br /&gt;
  ((ly:output-def-lookup #{ \midi {} #} &amp;#039;system) &amp;quot;id&amp;quot;)&lt;br /&gt;
)&lt;br /&gt;
&amp;lt;/score&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2. and without: &amp;lt;score&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  \relative { c&amp;#039; }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#(begin&lt;br /&gt;
  (display &amp;quot;With output-def-scope\n&amp;quot;)&lt;br /&gt;
  (eval &amp;#039;(system &amp;quot;id&amp;quot;) (ly:output-def-scope #{ \midi {} #}))&lt;br /&gt;
  (display &amp;quot;With output-def-lookup\n&amp;quot;)&lt;br /&gt;
  ((ly:output-def-lookup #{ \midi {} #} &amp;#039;system) &amp;quot;id&amp;quot;)&lt;br /&gt;
)&lt;br /&gt;
&amp;lt;/score&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3. Variant in comment from Han-wen Nienhuys: &amp;lt;score&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
  \override NoteHead.text = \system&lt;br /&gt;
  \override NoteHead.stencil =&lt;br /&gt;
  #(lambda (grob)&lt;br /&gt;
    ((cdr (assoc &amp;#039;text&lt;br /&gt;
	   (cadr (ly:grob-alist-chain grob &amp;#039;())))) &amp;quot;id&amp;quot;)&lt;br /&gt;
    #f)&lt;br /&gt;
  c4&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/score&amp;gt;&lt;/div&gt;</summary>
		<author><name>Johnno</name></author>
	</entry>
	<entry>
		<id>https://wiki.jon.geek.nz/index.php?title=Score_testing&amp;diff=2484</id>
		<title>Score testing</title>
		<link rel="alternate" type="text/html" href="https://wiki.jon.geek.nz/index.php?title=Score_testing&amp;diff=2484"/>
		<updated>2023-01-19T22:19:10Z</updated>

		<summary type="html">&lt;p&gt;Johnno: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:Score_PNG_output_in_dark_theme.png|thumb|Unreadable Score extension output in dark mode]]&lt;br /&gt;
Hopefully I can get the Score extension working to produce SVG output on upstream task [https://phabricator.wikimedia.org/T49578 T49578]. The transparent PNG image normally produced needs white background styling otherwise it&amp;#039;s unreadable in dark mode.&lt;br /&gt;
;Update December 2022: my patch was merged! :) now we wait for it to be tested and deployed into Wikipedia. There are a few other issues, including some security and sandboxing concerns, e.g. CVE-2020-17354 (see below). Also, this wiki is running on a 32-bit server, which only supports up to LilyPond 2.22 (I&amp;#039;m not game enough to try and compile LilyPond myself, and I&amp;#039;m not even sure Scheme 2 runs in 32-bit?) So I&amp;#039;m testing the SVG Score output over on my [https://mw-master.test.jon.geek.nz test instance] (which is not guaranteed to be up at all times).&lt;br /&gt;
&lt;br /&gt;
== Examples ==&lt;br /&gt;
Range of the [https://en.wikipedia.org/wiki/Contrabass_trombone contrabass trombone], as used on Wikipedia:&lt;br /&gt;
&amp;lt;score lang=&amp;quot;lilypond&amp;quot;&amp;gt;&lt;br /&gt;
  {&lt;br /&gt;
    \new Staff \with { \remove &amp;quot;Time_signature_engraver&amp;quot; }&lt;br /&gt;
    \clef bass \key c \major \cadenzaOn&lt;br /&gt;
    \ottava #-1 \tweak font-size #-2 fis,,,1 \finger \markup \text &amp;quot;poss.&amp;quot;&lt;br /&gt;
    \ottava #0  c,,1 \glissando d&amp;#039;1&lt;br /&gt;
    \tweak font-size #-2 f&amp;#039;1&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/score&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The Spear motif from &amp;#039;&amp;#039;Das Rheingold&amp;#039;&amp;#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;score lang=&amp;quot;lilypond&amp;quot;&amp;gt;&lt;br /&gt;
  \layout { ragged-right = ##t \context { \Score \omit BarNumber } }&lt;br /&gt;
  \relative g {&lt;br /&gt;
    \override DynamicTextSpanner.style = #&amp;#039;none&lt;br /&gt;
    \override Hairpin.minimum-length = #5&lt;br /&gt;
    \clef bass \key c \major&lt;br /&gt;
    g2~ \ff g8 f8 e8. d16&lt;br /&gt;
    c4 b a g  f e d c  \break&lt;br /&gt;
    b a g f  e1~ \dim\!  &amp;lt;&amp;lt; e1~ { s2 s4 s4 \&amp;gt; } &amp;gt;&amp;gt;  e4 \! \p r4 r2&lt;br /&gt;
  }&amp;lt;/score&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The Summit from &amp;#039;&amp;#039;Eine Alpensinfonie&amp;#039;&amp;#039;, which may or may not be a contrabass trombone excerpt, but probably ought to be:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;score&amp;gt;&lt;br /&gt;
\relative c, {&lt;br /&gt;
  \time 4/4&lt;br /&gt;
  \clef bass&lt;br /&gt;
  \key c \major&lt;br /&gt;
&lt;br /&gt;
  r2 r4\ff g\tenuto&lt;br /&gt;
  c2.\tenuto c4\tenuto&lt;br /&gt;
  g&amp;#039;2.\tenuto g4\tenuto&lt;br /&gt;
  c1&lt;br /&gt;
  e2~ e4.. b16&lt;br /&gt;
  a1&lt;br /&gt;
  g1&lt;br /&gt;
  c8 r8 r4 r2&lt;br /&gt;
  \bar &amp;quot;|.&amp;quot;&lt;br /&gt;
} &lt;br /&gt;
&amp;lt;/score&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== CV-2020-17354 ==&lt;br /&gt;
&lt;br /&gt;
See [https://phabricator.wikimedia.org/T259210 T259210]. Looks like either the syntax of the vuln PoC needs updating, and/or they&amp;#039;ve been fixed. Can&amp;#039;t repro as currently stands, with LilyPond 2.19 (Buster), MediaWiki on REL1_39 and Score on master.&lt;br /&gt;
&lt;br /&gt;
1. With defined location: &amp;lt;score&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  \relative { c&amp;#039; }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#(begin&lt;br /&gt;
  (define location 1)&lt;br /&gt;
  (display &amp;quot;With output-def-scope\n&amp;quot;)&lt;br /&gt;
  (eval &amp;#039;(system &amp;quot;id&amp;quot;) (ly:output-def-scope #{ \midi {} #}))&lt;br /&gt;
  (display &amp;quot;With output-def-lookup\n&amp;quot;)&lt;br /&gt;
  ((ly:output-def-lookup #{ \midi {} #} &amp;#039;system) &amp;quot;id&amp;quot;)&lt;br /&gt;
)&lt;br /&gt;
&amp;lt;/score&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2. and without: &amp;lt;score&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  \relative { c&amp;#039; }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#(begin&lt;br /&gt;
  (display &amp;quot;With output-def-scope\n&amp;quot;)&lt;br /&gt;
  (eval &amp;#039;(system &amp;quot;id&amp;quot;) (ly:output-def-scope #{ \midi {} #}))&lt;br /&gt;
  (display &amp;quot;With output-def-lookup\n&amp;quot;)&lt;br /&gt;
  ((ly:output-def-lookup #{ \midi {} #} &amp;#039;system) &amp;quot;id&amp;quot;)&lt;br /&gt;
)&lt;br /&gt;
&amp;lt;/score&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3. Variant in comment from Han-wen Nienhuys: &amp;lt;score&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
  \override NoteHead.text = \system&lt;br /&gt;
  \override NoteHead.stencil =&lt;br /&gt;
  #(lambda (grob)&lt;br /&gt;
    ((cdr (assoc &amp;#039;text&lt;br /&gt;
	   (cadr (ly:grob-alist-chain grob &amp;#039;())))) &amp;quot;id&amp;quot;)&lt;br /&gt;
    #f)&lt;br /&gt;
  c4&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/score&amp;gt;&lt;/div&gt;</summary>
		<author><name>Johnno</name></author>
	</entry>
	<entry>
		<id>https://wiki.jon.geek.nz/index.php?title=Score_testing&amp;diff=2483</id>
		<title>Score testing</title>
		<link rel="alternate" type="text/html" href="https://wiki.jon.geek.nz/index.php?title=Score_testing&amp;diff=2483"/>
		<updated>2023-01-19T22:15:11Z</updated>

		<summary type="html">&lt;p&gt;Johnno: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:Score_PNG_output_in_dark_theme.png|thumb|Unreadable Score extension output in dark mode]]&lt;br /&gt;
Hopefully I can get the Score extension working to produce SVG output on upstream task [https://phabricator.wikimedia.org/T49578 T49578]. The transparent PNG image normally produced needs white background styling otherwise it&amp;#039;s unreadable in dark mode.&lt;br /&gt;
;Update December 2022: my patch was merged! :) now we wait for it to be tested and deployed into Wikipedia. There are a few other issues, including some security and sandboxing concerns, e.g. CVE-2020-17354 (see below). Also, this wiki is running on a 32-bit server, which only supports up to LilyPond 2.22 (I&amp;#039;m not game enough to try and compile LilyPond myself, and I&amp;#039;m not even sure Scheme 2 runs in 32-bit?) So I&amp;#039;m testing the SVG Score output over on my [https://mw-master.test.jon.geek.nz test instance] (which is not guaranteed to be up at all times).&lt;br /&gt;
&lt;br /&gt;
== Examples ==&lt;br /&gt;
Range of the [https://en.wikipedia.org/wiki/Contrabass_trombone contrabass trombone], as used on Wikipedia:&lt;br /&gt;
&amp;lt;score lang=&amp;quot;lilypond&amp;quot;&amp;gt;&lt;br /&gt;
  {&lt;br /&gt;
    \new Staff \with { \remove &amp;quot;Time_signature_engraver&amp;quot; }&lt;br /&gt;
    \clef bass \key c \major \cadenzaOn&lt;br /&gt;
    \ottava #-1 \tweak font-size #-2 fis,,,1 \finger \markup \text &amp;quot;poss.&amp;quot;&lt;br /&gt;
    \ottava #0  c,,1 \glissando d&amp;#039;1&lt;br /&gt;
    \tweak font-size #-2 f&amp;#039;1&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/score&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The Spear motif from &amp;#039;&amp;#039;Das Rheingold&amp;#039;&amp;#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;score lang=&amp;quot;lilypond&amp;quot;&amp;gt;&lt;br /&gt;
  \layout { ragged-right = ##t \context { \Score \omit BarNumber } }&lt;br /&gt;
  \relative g {&lt;br /&gt;
    \override DynamicTextSpanner.style = #&amp;#039;none&lt;br /&gt;
    \override Hairpin.minimum-length = #5&lt;br /&gt;
    \clef bass \key c \major&lt;br /&gt;
    g2~ \ff g8 f8 e8. d16&lt;br /&gt;
    c4 b a g  f e d c  \break&lt;br /&gt;
    b a g f  e1~ \dim\!  &amp;lt;&amp;lt; e1~ { s2 s4 s4 \&amp;gt; } &amp;gt;&amp;gt;  e4 \! \p r4 r2&lt;br /&gt;
  }&amp;lt;/score&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The Summit from &amp;#039;&amp;#039;Eine Alpensinfonie&amp;#039;&amp;#039;, which may or may not be a contrabass trombone excerpt, but probably ought to be:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;score&amp;gt;&lt;br /&gt;
\relative c, {&lt;br /&gt;
  \time 4/4&lt;br /&gt;
  \clef bass&lt;br /&gt;
  \key c \major&lt;br /&gt;
&lt;br /&gt;
  r2 r4\ff g\tenuto&lt;br /&gt;
  c2.\tenuto c4\tenuto&lt;br /&gt;
  g&amp;#039;2.\tenuto g4\tenuto&lt;br /&gt;
  c1&lt;br /&gt;
  e2~ e4.. b16&lt;br /&gt;
  a1&lt;br /&gt;
  g1&lt;br /&gt;
  c8 r8 r4 r2&lt;br /&gt;
  \bar &amp;quot;|.&amp;quot;&lt;br /&gt;
} &lt;br /&gt;
&amp;lt;/score&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== CV-2020-17354 ==&lt;br /&gt;
&lt;br /&gt;
See [https://phabricator.wikimedia.org/T259210 T259210]. Looks like either the syntax of the PoC vulns need updating, and/or they&amp;#039;ve been fixed. Can&amp;#039;t repro as currently stands, with LilyPond 2.24 and Score on latest master.&lt;br /&gt;
&lt;br /&gt;
1. With defined location: &amp;lt;score&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  \relative { c&amp;#039; }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#(begin&lt;br /&gt;
  (define location 1)&lt;br /&gt;
  (display &amp;quot;With output-def-scope\n&amp;quot;)&lt;br /&gt;
  (eval &amp;#039;(system &amp;quot;id&amp;quot;) (ly:output-def-scope #{ \midi {} #}))&lt;br /&gt;
  (display &amp;quot;With output-def-lookup\n&amp;quot;)&lt;br /&gt;
  ((ly:output-def-lookup #{ \midi {} #} &amp;#039;system) &amp;quot;id&amp;quot;)&lt;br /&gt;
)&lt;br /&gt;
&amp;lt;/score&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2. and without: &amp;lt;score&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  \relative { c&amp;#039; }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#(begin&lt;br /&gt;
  (display &amp;quot;With output-def-scope\n&amp;quot;)&lt;br /&gt;
  (eval &amp;#039;(system &amp;quot;id&amp;quot;) (ly:output-def-scope #{ \midi {} #}))&lt;br /&gt;
  (display &amp;quot;With output-def-lookup\n&amp;quot;)&lt;br /&gt;
  ((ly:output-def-lookup #{ \midi {} #} &amp;#039;system) &amp;quot;id&amp;quot;)&lt;br /&gt;
)&lt;br /&gt;
&amp;lt;/score&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3. Variant in comment from Han-wen Nienhuys: &amp;lt;score&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
  \override NoteHead.text = \system&lt;br /&gt;
  \override NoteHead.stencil =&lt;br /&gt;
  #(lambda (grob)&lt;br /&gt;
    ((cdr (assoc &amp;#039;text&lt;br /&gt;
	   (cadr (ly:grob-alist-chain grob &amp;#039;())))) &amp;quot;id&amp;quot;)&lt;br /&gt;
    #f)&lt;br /&gt;
  c4&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/score&amp;gt;&lt;/div&gt;</summary>
		<author><name>Johnno</name></author>
	</entry>
	<entry>
		<id>https://wiki.jon.geek.nz/index.php?title=Score_testing&amp;diff=2482</id>
		<title>Score testing</title>
		<link rel="alternate" type="text/html" href="https://wiki.jon.geek.nz/index.php?title=Score_testing&amp;diff=2482"/>
		<updated>2023-01-19T20:46:28Z</updated>

		<summary type="html">&lt;p&gt;Johnno: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:Score_PNG_output_in_dark_theme.png|thumb|Unreadable Score extension output in dark mode]]&lt;br /&gt;
Hopefully I can get the Score extension working to [https://phabricator.wikimedia.org/T49578 produce SVG output], instead of the transparent PNG image that needs a white background styling for dark mode otherwise it&amp;#039;s unreadable.&lt;br /&gt;
;Update Januuary 2023: my patch was merged! :) now we wait for it to be tested and deployed. There are a few other issues, including some security and sandboxing concerns, e.g. CVE-2020-17354.&lt;br /&gt;
&lt;br /&gt;
== Examples ==&lt;br /&gt;
Range of the [https://en.wikipedia.org/wiki/Contrabass_trombone contrabass trombone], as used on Wikipedia:&lt;br /&gt;
&amp;lt;score lang=&amp;quot;lilypond&amp;quot;&amp;gt;&lt;br /&gt;
  {&lt;br /&gt;
    \new Staff \with { \remove &amp;quot;Time_signature_engraver&amp;quot; }&lt;br /&gt;
    \clef bass \key c \major \cadenzaOn&lt;br /&gt;
    \ottava #-1 \tweak font-size #-2 fis,,,1 \finger \markup \text &amp;quot;poss.&amp;quot;&lt;br /&gt;
    \ottava #0  c,,1 \glissando d&amp;#039;1&lt;br /&gt;
    \tweak font-size #-2 f&amp;#039;1&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/score&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The Spear motif from &amp;#039;&amp;#039;Das Rheingold&amp;#039;&amp;#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;score lang=&amp;quot;lilypond&amp;quot;&amp;gt;&lt;br /&gt;
  \layout { ragged-right = ##t \context { \Score \omit BarNumber } }&lt;br /&gt;
  \relative g {&lt;br /&gt;
    \override DynamicTextSpanner.style = #&amp;#039;none&lt;br /&gt;
    \override Hairpin.minimum-length = #5&lt;br /&gt;
    \clef bass \key c \major&lt;br /&gt;
    g2~ \ff g8 f8 e8. d16&lt;br /&gt;
    c4 b a g  f e d c  \break&lt;br /&gt;
    b a g f  e1~ \dim\!  &amp;lt;&amp;lt; e1~ { s2 s4 s4 \&amp;gt; } &amp;gt;&amp;gt;  e4 \! \p r4 r2&lt;br /&gt;
  }&amp;lt;/score&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The Summit from &amp;#039;&amp;#039;Eine Alpensinfonie&amp;#039;&amp;#039;, which may or may not be a contrabass trombone excerpt, but probably ought to be:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;score&amp;gt;&lt;br /&gt;
\relative c, {&lt;br /&gt;
  \time 4/4&lt;br /&gt;
  \clef bass&lt;br /&gt;
  \key c \major&lt;br /&gt;
&lt;br /&gt;
  r2 r4\ff g\tenuto&lt;br /&gt;
  c2.\tenuto c4\tenuto&lt;br /&gt;
  g&amp;#039;2.\tenuto g4\tenuto&lt;br /&gt;
  c1&lt;br /&gt;
  e2~ e4.. b16&lt;br /&gt;
  a1&lt;br /&gt;
  g1&lt;br /&gt;
  c8 r8 r4 r2&lt;br /&gt;
  \bar &amp;quot;|.&amp;quot;&lt;br /&gt;
} &lt;br /&gt;
&amp;lt;/score&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== CV-2020-17354 ==&lt;br /&gt;
&lt;br /&gt;
See [https://phabricator.wikimedia.org/T259210 T259210]&lt;br /&gt;
&lt;br /&gt;
1. With defined location: &amp;lt;score&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  \relative { c&amp;#039; }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#(begin&lt;br /&gt;
  (define location 1)&lt;br /&gt;
  (display &amp;quot;With output-def-scope\n&amp;quot;)&lt;br /&gt;
  (eval &amp;#039;(system &amp;quot;id&amp;quot;) (ly:output-def-scope #{ \midi {} #}))&lt;br /&gt;
  (display &amp;quot;With output-def-lookup\n&amp;quot;)&lt;br /&gt;
  ((ly:output-def-lookup #{ \midi {} #} &amp;#039;system) &amp;quot;id&amp;quot;)&lt;br /&gt;
)&lt;br /&gt;
&amp;lt;/score&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2. and without: &amp;lt;score&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  \relative { c&amp;#039; }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#(begin&lt;br /&gt;
  (display &amp;quot;With output-def-scope\n&amp;quot;)&lt;br /&gt;
  (eval &amp;#039;(system &amp;quot;id&amp;quot;) (ly:output-def-scope #{ \midi {} #}))&lt;br /&gt;
  (display &amp;quot;With output-def-lookup\n&amp;quot;)&lt;br /&gt;
  ((ly:output-def-lookup #{ \midi {} #} &amp;#039;system) &amp;quot;id&amp;quot;)&lt;br /&gt;
)&lt;br /&gt;
&amp;lt;/score&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3. Variant in comment from Han-wen Nienhuys: &amp;lt;score&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
  \override NoteHead.text = \system&lt;br /&gt;
  \override NoteHead.stencil =&lt;br /&gt;
  #(lambda (grob)&lt;br /&gt;
    ((cdr (assoc &amp;#039;text&lt;br /&gt;
	   (cadr (ly:grob-alist-chain grob &amp;#039;())))) &amp;quot;id&amp;quot;)&lt;br /&gt;
    #f)&lt;br /&gt;
  c4&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/score&amp;gt;&lt;/div&gt;</summary>
		<author><name>Johnno</name></author>
	</entry>
	<entry>
		<id>https://wiki.jon.geek.nz/index.php?title=Score_examples&amp;diff=2481</id>
		<title>Score examples</title>
		<link rel="alternate" type="text/html" href="https://wiki.jon.geek.nz/index.php?title=Score_examples&amp;diff=2481"/>
		<updated>2022-12-01T11:16:11Z</updated>

		<summary type="html">&lt;p&gt;Johnno: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;See also:&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039; [[Score examples SVG]]&lt;br /&gt;
&lt;br /&gt;
;Note 1: This wiki applies a solid white background to all Score output, as a temporary fix for otherwise unreadable transparent PNG images when in dark-mode.&lt;br /&gt;
;Note 2: To yoink Lilypond snippets from Wikipedia articles, see [https://en.wikipedia.org/wiki/Special:PagesWithProp?propname=score&amp;amp;namespace=0 Special:PagesWithProp] and search for the &amp;quot;score&amp;quot; property.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
From [https://en.wikipedia.org/wiki/Cadence Cadence]:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;score lang=&amp;quot;lilypond&amp;quot;&amp;gt;&lt;br /&gt;
   \new PianoStaff &amp;lt;&amp;lt;&lt;br /&gt;
      \new Staff &amp;lt;&amp;lt;&lt;br /&gt;
         \new Voice \relative c&amp;#039;&amp;#039; {&lt;br /&gt;
             \stemUp \clef treble \key e \minor \time 4/4&lt;br /&gt;
             \partial2 b4 b a g fis2 e1&lt;br /&gt;
             }&lt;br /&gt;
         \new Voice \relative c&amp;#039; {&lt;br /&gt;
             \stemDown&lt;br /&gt;
              \partial2 e4 e8 dis e fis g e e4 dis b1&lt;br /&gt;
              }&lt;br /&gt;
            &amp;gt;&amp;gt;&lt;br /&gt;
     \new Staff &amp;lt;&amp;lt;&lt;br /&gt;
         \new Voice \relative c&amp;#039; {&lt;br /&gt;
             \stemUp \clef bass \key e \minor \time 4/4&lt;br /&gt;
             \partial2 g8 a b4 c b cis b8 a! gis1&lt;br /&gt;
             }&lt;br /&gt;
         \new Voice \relative c {&lt;br /&gt;
             \stemDown&lt;br /&gt;
             \partial2 e8 fis g e c d e c ais4 b e,1&lt;br /&gt;
             }&lt;br /&gt;
         &amp;gt;&amp;gt;&lt;br /&gt;
    &amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;/score&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Multi-system input ==&lt;br /&gt;
&lt;br /&gt;
From [https://en.wikipedia.org/wiki/String_Quartet_No._1_(Górecki) String Quartet No. 1 (Górecki)]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;score lang=&amp;quot;lilypond&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
 \relative {&lt;br /&gt;
 \key c \minor&lt;br /&gt;
 \clef &amp;quot;treble_(8)&amp;quot;&lt;br /&gt;
 \time 4/4&lt;br /&gt;
    c&amp;#039;1 as2 bes2 c2 c2 es2 d2 c1 es1 f2 es2&lt;br /&gt;
    d2 c2 c2 bes2 c1 c1 f2 d2 es2 g2 f2 es2 f1&lt;br /&gt;
    f1 bes,2 c2 d2 es2 f2 d2 c1 c1 bes2 as2 bes2 g2&lt;br /&gt;
    as2 bes2 g1 f1 as2 bes2 c2 as2 bes2 g2 f1&lt;br /&gt;
}&lt;br /&gt;
 \addlyrics {&lt;br /&gt;
        Już się zmierz -- cha, nad -- cho -- dzi noc, po -- pro -- śmy&lt;br /&gt;
        Bo -- ga o po -- moc, a -- by on na -- szym stra -- żem był,&lt;br /&gt;
        od złych czar -- tów nas o -- bro -- nił, któ -- rzy naj -- wię -- cej&lt;br /&gt;
        w_ciem -- no -- ści u -- ży -- wa -- ją swej chy -- tro -- ści. \bar &amp;quot;||&amp;quot;&lt;br /&gt;
    }&lt;br /&gt;
}&amp;lt;/score&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Testing raw input ==&lt;br /&gt;
&lt;br /&gt;
;Note: this requires safe mode to be disabled, which it isn&amp;#039;t on this wiki.&lt;br /&gt;
From [https://en.wikipedia.org/wiki/Keyboard_Sonata,_K._141_(Scarlatti) Keyboard Sonata, K. 141 (Scarlatti)], testing raw=1:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;score raw=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
\version &amp;quot;2.18.2&amp;quot;&lt;br /&gt;
\header {&lt;br /&gt;
  tagline = ##f&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
% thèmes&lt;br /&gt;
temaRep = { \repeat unfold 6 { d16 } \repeat unfold 6 { f } \repeat unfold 6 { e } \repeat unfold 6 { d } \repeat unfold 6 { e } \repeat unfold 6 { a }&lt;br /&gt;
  % ms. 7&lt;br /&gt;
  d16 bes a g f e | f g a d, e cis }&lt;br /&gt;
temaBass = { &amp;lt; d g a d &amp;gt;8 r8 r8 | q r8 r8 | &amp;lt; a&amp;#039; cis e a &amp;gt;8 r8 r8 | &amp;lt; bes cis d g &amp;gt;8 r8 r8 | &amp;lt; a d e a &amp;gt;8 r8 r8 |&lt;br /&gt;
   % ms. 6&lt;br /&gt;
   &amp;lt; f a d &amp;gt;8 r8 r8 | &amp;lt; g bes d g &amp;gt;8 r8 r8 | &amp;lt; a d f &amp;gt;4 &amp;lt; a e&amp;#039; g &amp;gt;8 }&lt;br /&gt;
temaBassG = { &amp;lt; d g a d &amp;gt;8 r8 r8 | q r8 r8 | &amp;lt; a&amp;#039; d e a &amp;gt;8 r8 r8 | &amp;lt; bes d g &amp;gt;8 r8 r8 | &amp;lt; a d e a &amp;gt;8 r8 r8 |&lt;br /&gt;
   % ms. 6&lt;br /&gt;
   &amp;lt; f a d &amp;gt;8 r8 r8 | &amp;lt; g bes d g &amp;gt;8 r8 r8 | &amp;lt; a d f &amp;gt;4 &amp;lt; a e&amp;#039; g &amp;gt;8 }&lt;br /&gt;
&lt;br /&gt;
% petites notes&lt;br /&gt;
trillD = { \tag #&amp;#039;print { d8.\trill } \tag #&amp;#039;midi { e32 d e d~ d } }&lt;br /&gt;
trillG = { \tag #&amp;#039;print { g8.\trill } \tag #&amp;#039;midi { a32 g a g~ g } }&lt;br /&gt;
&lt;br /&gt;
upper = \relative c&amp;#039;&amp;#039; {&lt;br /&gt;
  \clef treble &lt;br /&gt;
  \key d \minor&lt;br /&gt;
  \time 3/8&lt;br /&gt;
  \tempo 4. = 80&lt;br /&gt;
  % \tempo 8 = 210&lt;br /&gt;
  \set Staff.midiInstrument = #&amp;quot;harpsichord&amp;quot;&lt;br /&gt;
&lt;br /&gt;
  s8*0^&amp;quot;Allegro&amp;quot; \temaRep | d16 bes a g f e { \relative c&amp;#039; \temaRep } | d4. | \repeat unfold 2 { a&amp;#039;&amp;#039;4.~ | a16 e cis a g&amp;#039; e } | &lt;br /&gt;
  % ms. 23&lt;br /&gt;
  a4. | bes16 g d bes g bes | g&amp;#039;4. | a16 f c a f a | &lt;br /&gt;
  % ms. 27&lt;br /&gt;
  f&amp;#039;4. | g16 e c g e g | e&amp;#039;4. | f16 d a f d f | f&amp;#039; e d c bes a | &lt;br /&gt;
  % ms. 32&lt;br /&gt;
  bes&amp;#039;16 a g f e d | \repeat unfold 2 { cis16 d \trillD cis32 d | e f g16 \trillG f32 g } | &lt;br /&gt;
  % ms. 37&lt;br /&gt;
  a16 e cis a e cis | \change Staff = &amp;quot;lower&amp;quot; a16 e cis a e cis | \tempo 8 = 130  a4.&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
lower = \relative c {&lt;br /&gt;
  \clef bass&lt;br /&gt;
  \key d \minor&lt;br /&gt;
  \time 3/8&lt;br /&gt;
  \set Staff.midiInstrument = #&amp;quot;harpsichord&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    % **************************************&lt;br /&gt;
    \temaBass | &amp;lt;&amp;lt; { d8 } \\ { d,4 s8 } &amp;gt;&amp;gt;&lt;br /&gt;
    \relative c, \temaBassG &amp;lt; d, d&amp;#039; &amp;gt;4.&lt;br /&gt;
    % ms. 19&lt;br /&gt;
    \repeat unfold 2 { a&amp;#039;&amp;#039;&amp;#039;16 f d a f d | a4. }&lt;br /&gt;
    a&amp;#039;&amp;#039;16 f d a f d | g,4.&lt;br /&gt;
    g&amp;#039;&amp;#039;16 e c g e c | f,4.&lt;br /&gt;
    f&amp;#039;&amp;#039;16 d bes f d bes | e,4.&lt;br /&gt;
    e&amp;#039;&amp;#039;16 cis a e cis a | d,4.&lt;br /&gt;
    &amp;lt;&amp;lt; { d&amp;#039;&amp;#039;4. | \repeat unfold 5 { g4. } a8 } \\ { d,,8 e f | g a bes | \repeat unfold 4 { a8 bes4 } a8 } &amp;gt;&amp;gt;&lt;br /&gt;
    s4&lt;br /&gt;
    s4. | s4.&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
thePianoStaff = \new PianoStaff &amp;lt;&amp;lt;&lt;br /&gt;
    \set PianoStaff.instrumentName = #&amp;quot;Clav.&amp;quot;&lt;br /&gt;
    \new Staff = &amp;quot;upper&amp;quot; \upper&lt;br /&gt;
    \new Staff = &amp;quot;lower&amp;quot; \lower&lt;br /&gt;
  &amp;gt;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
\score {&lt;br /&gt;
  \keepWithTag #&amp;#039;print \thePianoStaff&lt;br /&gt;
  \layout {&lt;br /&gt;
      #(layout-set-staff-size 17)&lt;br /&gt;
    \context {&lt;br /&gt;
      \Score&lt;br /&gt;
     \override SpacingSpanner.common-shortest-duration = #(ly:make-moment 1/2)&lt;br /&gt;
      \remove &amp;quot;Metronome_mark_engraver&amp;quot;&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
\score {&lt;br /&gt;
  \keepWithTag #&amp;#039;midi \thePianoStaff&lt;br /&gt;
  \midi { }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/score&amp;gt;&lt;/div&gt;</summary>
		<author><name>Johnno</name></author>
	</entry>
	<entry>
		<id>https://wiki.jon.geek.nz/index.php?title=Score_examples_SVG&amp;diff=2480</id>
		<title>Score examples SVG</title>
		<link rel="alternate" type="text/html" href="https://wiki.jon.geek.nz/index.php?title=Score_examples_SVG&amp;diff=2480"/>
		<updated>2022-11-30T06:04:14Z</updated>

		<summary type="html">&lt;p&gt;Johnno: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;;Note 1: This page is a simulation of [[Score examples]], using the Score-generated SVG output from a SVG-patched version of the Score extension; see [https://phabricator.wikimedia.org/T49578 T49578].&lt;br /&gt;
&lt;br /&gt;
;Note 2: To yoink Lilypond snippets from Wikipedia articles, see [https://en.wikipedia.org/wiki/Special:PagesWithProp?propname=score&amp;amp;namespace=0 Special:PagesWithProp] and search for the &amp;quot;score&amp;quot; property in Article space.&lt;br /&gt;
&lt;br /&gt;
From [https://en.wikipedia.org/wiki/Cadence Cadence]:&lt;br /&gt;
&lt;br /&gt;
[[File:ru47w83v.svg]]&lt;br /&gt;
&lt;br /&gt;
== Multi-system input ==&lt;br /&gt;
&lt;br /&gt;
From [https://en.wikipedia.org/wiki/String_Quartet_No._1_(Górecki) String Quartet No. 1 (Górecki)]&lt;br /&gt;
&lt;br /&gt;
[[File:0og4sm0i.svg]]&lt;br /&gt;
&lt;br /&gt;
== Testing raw input ==&lt;br /&gt;
&lt;br /&gt;
And some [https://en.wikipedia.org/wiki/Keyboard_Sonata,_K._141_(Scarlatti) Keyboard Sonata, K. 141 (Scarlatti)], testing raw=1:&lt;br /&gt;
&lt;br /&gt;
[[File:7hc4jfka.svg]]&lt;/div&gt;</summary>
		<author><name>Johnno</name></author>
	</entry>
	<entry>
		<id>https://wiki.jon.geek.nz/index.php?title=Score_examples&amp;diff=2479</id>
		<title>Score examples</title>
		<link rel="alternate" type="text/html" href="https://wiki.jon.geek.nz/index.php?title=Score_examples&amp;diff=2479"/>
		<updated>2022-11-30T06:01:33Z</updated>

		<summary type="html">&lt;p&gt;Johnno: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;;Note 1: This wiki applies a solid white background to all Score output, as a temporary fix for otherwise unreadable transparent PNG images when in dark-mode.&lt;br /&gt;
;Note 2: To yoink Lilypond snippets from Wikipedia articles, see [https://en.wikipedia.org/wiki/Special:PagesWithProp?propname=score&amp;amp;namespace=0 Special:PagesWithProp] and search for the &amp;quot;score&amp;quot; property.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
From [https://en.wikipedia.org/wiki/Cadence Cadence]:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;score lang=&amp;quot;lilypond&amp;quot;&amp;gt;&lt;br /&gt;
   \new PianoStaff &amp;lt;&amp;lt;&lt;br /&gt;
      \new Staff &amp;lt;&amp;lt;&lt;br /&gt;
         \new Voice \relative c&amp;#039;&amp;#039; {&lt;br /&gt;
             \stemUp \clef treble \key e \minor \time 4/4&lt;br /&gt;
             \partial2 b4 b a g fis2 e1&lt;br /&gt;
             }&lt;br /&gt;
         \new Voice \relative c&amp;#039; {&lt;br /&gt;
             \stemDown&lt;br /&gt;
              \partial2 e4 e8 dis e fis g e e4 dis b1&lt;br /&gt;
              }&lt;br /&gt;
            &amp;gt;&amp;gt;&lt;br /&gt;
     \new Staff &amp;lt;&amp;lt;&lt;br /&gt;
         \new Voice \relative c&amp;#039; {&lt;br /&gt;
             \stemUp \clef bass \key e \minor \time 4/4&lt;br /&gt;
             \partial2 g8 a b4 c b cis b8 a! gis1&lt;br /&gt;
             }&lt;br /&gt;
         \new Voice \relative c {&lt;br /&gt;
             \stemDown&lt;br /&gt;
             \partial2 e8 fis g e c d e c ais4 b e,1&lt;br /&gt;
             }&lt;br /&gt;
         &amp;gt;&amp;gt;&lt;br /&gt;
    &amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;/score&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Multi-system input ==&lt;br /&gt;
&lt;br /&gt;
From [https://en.wikipedia.org/wiki/String_Quartet_No._1_(Górecki) String Quartet No. 1 (Górecki)]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;score lang=&amp;quot;lilypond&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
 \relative {&lt;br /&gt;
 \key c \minor&lt;br /&gt;
 \clef &amp;quot;treble_(8)&amp;quot;&lt;br /&gt;
 \time 4/4&lt;br /&gt;
    c&amp;#039;1 as2 bes2 c2 c2 es2 d2 c1 es1 f2 es2&lt;br /&gt;
    d2 c2 c2 bes2 c1 c1 f2 d2 es2 g2 f2 es2 f1&lt;br /&gt;
    f1 bes,2 c2 d2 es2 f2 d2 c1 c1 bes2 as2 bes2 g2&lt;br /&gt;
    as2 bes2 g1 f1 as2 bes2 c2 as2 bes2 g2 f1&lt;br /&gt;
}&lt;br /&gt;
 \addlyrics {&lt;br /&gt;
        Już się zmierz -- cha, nad -- cho -- dzi noc, po -- pro -- śmy&lt;br /&gt;
        Bo -- ga o po -- moc, a -- by on na -- szym stra -- żem był,&lt;br /&gt;
        od złych czar -- tów nas o -- bro -- nił, któ -- rzy naj -- wię -- cej&lt;br /&gt;
        w_ciem -- no -- ści u -- ży -- wa -- ją swej chy -- tro -- ści. \bar &amp;quot;||&amp;quot;&lt;br /&gt;
    }&lt;br /&gt;
}&amp;lt;/score&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Testing raw input ==&lt;br /&gt;
&lt;br /&gt;
;Note: this requires safe mode to be disabled, which it isn&amp;#039;t on this wiki.&lt;br /&gt;
From [https://en.wikipedia.org/wiki/Keyboard_Sonata,_K._141_(Scarlatti) Keyboard Sonata, K. 141 (Scarlatti)], testing raw=1:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;score raw=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
\version &amp;quot;2.18.2&amp;quot;&lt;br /&gt;
\header {&lt;br /&gt;
  tagline = ##f&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
% thèmes&lt;br /&gt;
temaRep = { \repeat unfold 6 { d16 } \repeat unfold 6 { f } \repeat unfold 6 { e } \repeat unfold 6 { d } \repeat unfold 6 { e } \repeat unfold 6 { a }&lt;br /&gt;
  % ms. 7&lt;br /&gt;
  d16 bes a g f e | f g a d, e cis }&lt;br /&gt;
temaBass = { &amp;lt; d g a d &amp;gt;8 r8 r8 | q r8 r8 | &amp;lt; a&amp;#039; cis e a &amp;gt;8 r8 r8 | &amp;lt; bes cis d g &amp;gt;8 r8 r8 | &amp;lt; a d e a &amp;gt;8 r8 r8 |&lt;br /&gt;
   % ms. 6&lt;br /&gt;
   &amp;lt; f a d &amp;gt;8 r8 r8 | &amp;lt; g bes d g &amp;gt;8 r8 r8 | &amp;lt; a d f &amp;gt;4 &amp;lt; a e&amp;#039; g &amp;gt;8 }&lt;br /&gt;
temaBassG = { &amp;lt; d g a d &amp;gt;8 r8 r8 | q r8 r8 | &amp;lt; a&amp;#039; d e a &amp;gt;8 r8 r8 | &amp;lt; bes d g &amp;gt;8 r8 r8 | &amp;lt; a d e a &amp;gt;8 r8 r8 |&lt;br /&gt;
   % ms. 6&lt;br /&gt;
   &amp;lt; f a d &amp;gt;8 r8 r8 | &amp;lt; g bes d g &amp;gt;8 r8 r8 | &amp;lt; a d f &amp;gt;4 &amp;lt; a e&amp;#039; g &amp;gt;8 }&lt;br /&gt;
&lt;br /&gt;
% petites notes&lt;br /&gt;
trillD = { \tag #&amp;#039;print { d8.\trill } \tag #&amp;#039;midi { e32 d e d~ d } }&lt;br /&gt;
trillG = { \tag #&amp;#039;print { g8.\trill } \tag #&amp;#039;midi { a32 g a g~ g } }&lt;br /&gt;
&lt;br /&gt;
upper = \relative c&amp;#039;&amp;#039; {&lt;br /&gt;
  \clef treble &lt;br /&gt;
  \key d \minor&lt;br /&gt;
  \time 3/8&lt;br /&gt;
  \tempo 4. = 80&lt;br /&gt;
  % \tempo 8 = 210&lt;br /&gt;
  \set Staff.midiInstrument = #&amp;quot;harpsichord&amp;quot;&lt;br /&gt;
&lt;br /&gt;
  s8*0^&amp;quot;Allegro&amp;quot; \temaRep | d16 bes a g f e { \relative c&amp;#039; \temaRep } | d4. | \repeat unfold 2 { a&amp;#039;&amp;#039;4.~ | a16 e cis a g&amp;#039; e } | &lt;br /&gt;
  % ms. 23&lt;br /&gt;
  a4. | bes16 g d bes g bes | g&amp;#039;4. | a16 f c a f a | &lt;br /&gt;
  % ms. 27&lt;br /&gt;
  f&amp;#039;4. | g16 e c g e g | e&amp;#039;4. | f16 d a f d f | f&amp;#039; e d c bes a | &lt;br /&gt;
  % ms. 32&lt;br /&gt;
  bes&amp;#039;16 a g f e d | \repeat unfold 2 { cis16 d \trillD cis32 d | e f g16 \trillG f32 g } | &lt;br /&gt;
  % ms. 37&lt;br /&gt;
  a16 e cis a e cis | \change Staff = &amp;quot;lower&amp;quot; a16 e cis a e cis | \tempo 8 = 130  a4.&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
lower = \relative c {&lt;br /&gt;
  \clef bass&lt;br /&gt;
  \key d \minor&lt;br /&gt;
  \time 3/8&lt;br /&gt;
  \set Staff.midiInstrument = #&amp;quot;harpsichord&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    % **************************************&lt;br /&gt;
    \temaBass | &amp;lt;&amp;lt; { d8 } \\ { d,4 s8 } &amp;gt;&amp;gt;&lt;br /&gt;
    \relative c, \temaBassG &amp;lt; d, d&amp;#039; &amp;gt;4.&lt;br /&gt;
    % ms. 19&lt;br /&gt;
    \repeat unfold 2 { a&amp;#039;&amp;#039;&amp;#039;16 f d a f d | a4. }&lt;br /&gt;
    a&amp;#039;&amp;#039;16 f d a f d | g,4.&lt;br /&gt;
    g&amp;#039;&amp;#039;16 e c g e c | f,4.&lt;br /&gt;
    f&amp;#039;&amp;#039;16 d bes f d bes | e,4.&lt;br /&gt;
    e&amp;#039;&amp;#039;16 cis a e cis a | d,4.&lt;br /&gt;
    &amp;lt;&amp;lt; { d&amp;#039;&amp;#039;4. | \repeat unfold 5 { g4. } a8 } \\ { d,,8 e f | g a bes | \repeat unfold 4 { a8 bes4 } a8 } &amp;gt;&amp;gt;&lt;br /&gt;
    s4&lt;br /&gt;
    s4. | s4.&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
thePianoStaff = \new PianoStaff &amp;lt;&amp;lt;&lt;br /&gt;
    \set PianoStaff.instrumentName = #&amp;quot;Clav.&amp;quot;&lt;br /&gt;
    \new Staff = &amp;quot;upper&amp;quot; \upper&lt;br /&gt;
    \new Staff = &amp;quot;lower&amp;quot; \lower&lt;br /&gt;
  &amp;gt;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
\score {&lt;br /&gt;
  \keepWithTag #&amp;#039;print \thePianoStaff&lt;br /&gt;
  \layout {&lt;br /&gt;
      #(layout-set-staff-size 17)&lt;br /&gt;
    \context {&lt;br /&gt;
      \Score&lt;br /&gt;
     \override SpacingSpanner.common-shortest-duration = #(ly:make-moment 1/2)&lt;br /&gt;
      \remove &amp;quot;Metronome_mark_engraver&amp;quot;&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
\score {&lt;br /&gt;
  \keepWithTag #&amp;#039;midi \thePianoStaff&lt;br /&gt;
  \midi { }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/score&amp;gt;&lt;/div&gt;</summary>
		<author><name>Johnno</name></author>
	</entry>
	<entry>
		<id>https://wiki.jon.geek.nz/index.php?title=Score_examples_SVG&amp;diff=2478</id>
		<title>Score examples SVG</title>
		<link rel="alternate" type="text/html" href="https://wiki.jon.geek.nz/index.php?title=Score_examples_SVG&amp;diff=2478"/>
		<updated>2022-11-30T05:56:40Z</updated>

		<summary type="html">&lt;p&gt;Johnno: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;;Note 1: This page is the SVG output version of [[Score examples]], using a hacked version of the Score extension; see [https://phabricator.wikimedia.org/T49578 T49578].&lt;br /&gt;
&lt;br /&gt;
;Note 2: To yoink Lilypond snippets from Wikipedia articles, see [https://en.wikipedia.org/wiki/Special:PagesWithProp?propname=score&amp;amp;namespace=0 Special:PagesWithProp] and search for the &amp;quot;score&amp;quot; property in Article space.&lt;br /&gt;
&lt;br /&gt;
From [https://en.wikipedia.org/wiki/Cadence Cadence]:&lt;br /&gt;
&lt;br /&gt;
[[File:ru47w83v.svg]]&lt;br /&gt;
&lt;br /&gt;
== Multi-system input ==&lt;br /&gt;
&lt;br /&gt;
From [https://en.wikipedia.org/wiki/String_Quartet_No._1_(Górecki) String Quartet No. 1 (Górecki)]&lt;br /&gt;
&lt;br /&gt;
[[File:0og4sm0i.svg]]&lt;br /&gt;
&lt;br /&gt;
== Testing raw input ==&lt;br /&gt;
&lt;br /&gt;
And some [https://en.wikipedia.org/wiki/Keyboard_Sonata,_K._141_(Scarlatti) Keyboard Sonata, K. 141 (Scarlatti)], testing raw=1:&lt;br /&gt;
&lt;br /&gt;
[[File:7hc4jfka.svg]]&lt;/div&gt;</summary>
		<author><name>Johnno</name></author>
	</entry>
	<entry>
		<id>https://wiki.jon.geek.nz/index.php?title=File:7hc4jfka.svg&amp;diff=2477</id>
		<title>File:7hc4jfka.svg</title>
		<link rel="alternate" type="text/html" href="https://wiki.jon.geek.nz/index.php?title=File:7hc4jfka.svg&amp;diff=2477"/>
		<updated>2022-11-30T05:55:22Z</updated>

		<summary type="html">&lt;p&gt;Johnno: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Johnno</name></author>
	</entry>
	<entry>
		<id>https://wiki.jon.geek.nz/index.php?title=File:0og4sm0i.svg&amp;diff=2476</id>
		<title>File:0og4sm0i.svg</title>
		<link rel="alternate" type="text/html" href="https://wiki.jon.geek.nz/index.php?title=File:0og4sm0i.svg&amp;diff=2476"/>
		<updated>2022-11-30T05:46:59Z</updated>

		<summary type="html">&lt;p&gt;Johnno: ZZ&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Summary ==&lt;br /&gt;
ZZ&lt;br /&gt;
== Licensing ==&lt;br /&gt;
{{self|cc-zero}}&lt;/div&gt;</summary>
		<author><name>Johnno</name></author>
	</entry>
	<entry>
		<id>https://wiki.jon.geek.nz/index.php?title=File:Ru47w83v.svg&amp;diff=2475</id>
		<title>File:Ru47w83v.svg</title>
		<link rel="alternate" type="text/html" href="https://wiki.jon.geek.nz/index.php?title=File:Ru47w83v.svg&amp;diff=2475"/>
		<updated>2022-11-30T05:26:31Z</updated>

		<summary type="html">&lt;p&gt;Johnno: NA&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Summary ==&lt;br /&gt;
NA&lt;br /&gt;
== Licensing ==&lt;br /&gt;
{{self|cc-zero}}&lt;/div&gt;</summary>
		<author><name>Johnno</name></author>
	</entry>
</feed>