nextcloud-and-guix-system-server.html 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256
  1. <!DOCTYPE html><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" /><meta name="keywords" content="GNU, Emacs, Libre Software, Hurd, Guile, Guix" /><meta name="description" content="GNUcode.me is a website focusing on libre software projects, especially the GNU project." /><link type="application/atom+xml" rel="alternate" title="GNUcode.me -- Feed" href="/feed.xml" /><a rel="me" href="https://fosstodon.org/@thegnuguy"></a><link type="text/css" href="css/footer.min.css" rel="stylesheet"></link><link type="text/css" href="css/header.min.css" rel="stylesheet"></link><link type="text/css" href="css/main.min.css" rel="stylesheet"></link><title>Nextcloud and Guix System Server — GNUcode.me</title></head><body><header><nav><ul><li><a href="index.html">GNUcode.me</a></li><li><a href="services.html">Services</a></li><li><a href="business-ideas.html">Business-ideas</a></li><li><a href="about.html">About</a></li></ul></nav></header><h1>Nextcloud and Guix System Server</h1><main><section class="basic-section-padding"><article><h3>by Joshua Branson — February 22, 2023</h3><div><p>So I have wanted to run <a href="https://nextcloud.com/">nextcloud</a> for a while now. In my humble opinion, guix
  2. system makes maintaining websites super easy, so I would prefer to run nextcloud
  3. on guix system. Unfortunately, nextcloud will NOT be packaged in guix anytime
  4. soon for two reasons:</p><ol><li>Guix does not currently have a php build system or any php packages, though
  5. there is a 80% completed <a href="https://issues.guix.gnu.org/42338">work-in-progress issue.</a> So the php bits of nextcloud
  6. cannot be packaged properly.</li><li>Nextcloud has a lot of javascript dependencies, and javascript is <a href="https://dustycloud.org/blog/javascript-packaging-dystopia/">notoriously
  7. hard to package for guix.</a></li></ol><p>It seems like the easiest way to currently run nextcloud on guix system is by
  8. using the <a href="https://github.com/nextcloud/all-in-one">all in one docker image.</a> Please consider this a guide to set up
  9. running nextcloud on guix system via a linode, which currently costs me about $5
  10. per month.</p><p>Note, that while this is the easiest method to run nextcloud, apparently this
  11. all in one docker image has some security issues:</p><blockquote><p>The AIO image mounts the Docker socket, which is a security risk since it allows
  12. full access to other container as well as running any new container. It’s a bad
  13. idea and should be avoided.</p></blockquote><p>tl;dr Here are the 6 simple steps that you need to do:</p><ol><li><p>Set up a <a href="https://guix.gnu.org/en/cookbook/en/html_node/Running-Guix-on-a-Linode-Server.html#Running-Guix-on-a-Linode-Server">linode guix system server.</a> <code>info &quot;Guix Cookbook&quot; RET i linode RET</code>.</p></li><li><p>Buy a domain name. I use <a href="https://hover.com">hover.com</a>.</p></li><li><p>Point your domain name at your linode IP address.</p></li><li><p>Set up a basic nginx static website without encryption. This means that you
  14. don’t want to define <code>(service certbot-service-type)</code>.</p><pre><code>sudo mkdir -p /srv/www/html/yourdomainname.com
  15. # the command I did was this:
  16. sudo mkdir -p /srv/www/html/the-nx.com
  17. sudo chgrp -R users /srv
  18. sudo chmod -R g+rwx /srv</code></pre><p>Inside your newly created directory (<em>srv/www/html/yourdomainname.com</em>), put
  19. a simple HTML file and call it “index.html”. You could use this:</p><pre><code>&lt;!doctype html&gt;
  20. &lt;html class=&quot;no-js&quot; lang=&quot;&quot;&gt;
  21. &lt;head&gt;
  22. &lt;meta charset=&quot;utf-8&quot;&gt;
  23. &lt;meta http-equiv=&quot;x-ua-compatible&quot; content=&quot;ie=edge&quot;&gt;
  24. &lt;title&gt;the nx&lt;/title&gt;
  25. &lt;meta name=&quot;description&quot; content=&quot;&quot;&gt;
  26. &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1&quot;&gt;
  27. &lt;link rel=&quot;apple-touch-icon&quot; href=&quot;/apple-touch-icon.png&quot;&gt;
  28. &lt;/head&gt;
  29. &lt;body&gt;
  30. &lt;!--[if lt IE 8]&gt;
  31. &lt;p class=&quot;browserupgrade&quot;&gt;
  32. You are using an &lt;strong&gt;outdated&lt;/strong&gt; browser. Please
  33. &lt;a href=&quot;http://browsehappy.com/&quot;&gt;upgrade your browser&lt;/a&gt; to improve
  34. your experience.
  35. &lt;/p&gt;
  36. &lt;![endif]--&gt;
  37. &lt;p&gt;Hello!&lt;/p&gt;
  38. &lt;/body&gt;
  39. &lt;/html&gt;</code></pre><p>Now set up a basic nginx configuration for a static website without
  40. encryption. It will end up looking something like:</p><pre><code>(service nginx-service-type
  41. (nginx-configuration
  42. (server-blocks
  43. (list
  44. (nginx-server-configuration
  45. (server-name '(&quot;the-nx.com&quot;))
  46. (listen (list &quot;80&quot; &quot;[::]:80&quot;))
  47. (root &quot;/srv/www/html/the-nx.com&quot;))))))</code></pre><p>Now you need to reconfigure so that the <code>nginx</code> user is created:</p><p><code>sudo guix system reconfigure config.scm</code></p><p>Now, nginx is running, but you will probably need to give nginx access to
  48. read the files in your /srv directory.</p><pre><code>sudo chown -R nginx /srv
  49. sudo chmod -R u-rwx /srv</code></pre><p>Open up a web browser and go to <a href="http://yourdomainname.com">http://yourdomainname.com</a> and check to see
  50. that you see a basic website.</p></li><li><p>Now you need to turn your basic static website, into a site that has https
  51. support. Now you need to edit your nginx config and add in a certbot config:</p><p>Before your <code>(operating-system ...)</code> declartion, define this bit of code:</p><pre><code>(define %nginx-deploy-hook
  52. (program-file
  53. &quot;nginx-deploy-hook&quot;
  54. #~(let ((pid (call-with-input-file &quot;/var/run/nginx/pid&quot; read)))
  55. (kill pid SIGHUP))))</code></pre><p>Also make sure that you add in a <code>certbot</code> service and a modified <code>nginx</code>
  56. service that look like this:</p><pre><code>(service certbot-service-type
  57. (certbot-configuration
  58. (email &quot;mysubscriptions@member.fsf.org&quot;)
  59. (webroot &quot;/srv/www/&quot;)
  60. (certificates
  61. (list
  62. (certificate-configuration
  63. (name &quot;the-nx.com&quot;)
  64. (domains '(&quot;the-nx.com&quot; &quot;www.the-nx.com&quot;))
  65. (deploy-hook %nginx-deploy-hook))))))
  66. (service nginx-service-type
  67. (nginx-configuration
  68. (server-blocks
  69. (list
  70. (nginx-server-configuration
  71. (server-name '(&quot;the-nx.com&quot;))
  72. (listen (list &quot;80&quot;
  73. &quot;443 ssl http2&quot;
  74. &quot;[::]:80&quot;
  75. &quot;[::80]:443 ssl http2&quot;))
  76. (root &quot;/srv/www/html/the-nx.com&quot;)
  77. (ssl-certificate &quot;/etc/letsencrypt/live/the-nx.com/fullchain.pem&quot;)
  78. (ssl-certificate-key &quot;/etc/letsencrypt/live/the-nx.com/privkey.pem&quot;)
  79. (locations
  80. (list
  81. (nginx-location-configuration ;; for certbot
  82. (uri &quot;/.well-known&quot;)
  83. (body (list &quot;root /srv/www;&quot;))))))))))</code></pre><p>Now we will have to reconfigure again to set up certbot:</p><pre><code>sudo guix system reconfigure config.scm
  84. # tell certbot to set up our certificates
  85. sudo /var/lib/certbot/renew-certificates</code></pre><p>Now you should be able to go to <a href="https://yourdomainname.com">https://yourdomainname.com</a> and see your site
  86. in glorious encrypted mode!</p></li><li><p>Modify your guix config based on my <a href="https://notabug.org/jbranso/linode-guix-system-configuration/src/master/the-nx.com-current-config.scm">the-nx.com-current-config.scm</a>.
  87. You will need to enable these services <code>(dbus-service)</code>, <code>(service docker-service-type)</code>, <code>(elogind service)</code>, <code>(service certbot-service-type)</code>,
  88. and <code>(service nginx-service-type)</code>.</p></li></ol><p>I just ran this command, and my local nextcloud just started working.</p><pre><code>sudo docker run \
  89. --sig-proxy=false \
  90. --name nextcloud-aio-mastercontainer \
  91. --restart always \
  92. --publish 80:80 \
  93. --publish 8080:8080 \
  94. --publish 8443:8443 \
  95. --volume nextcloud_aio_mastercontainer:/mnt/docker-aio-config \
  96. --volume /var/run/docker.sock:/var/run/docker.sock:ro \
  97. nextcloud/all-in-one:latest</code></pre><p>The following is the same quick guide as above, but has more details:</p><p>I decided to create a new linode image following the linode cookbook guide, and
  98. I noticed a tiny error in the guide:</p><p><code>sudo apt-get install gpg</code> failed. It worked after I ran <code>sudo apt-get update</code>.</p><p>Also the basic config example needs to migrate to the new &lt;swap-space&gt; record.
  99. It gave me this warning message:</p><p>/root/config.scm:11:0: warning: List elements of the field ’swap-devices’ should
  100. now use the &lt;swap-space&gt; record, as the old method is deprecated. See “(guix)
  101. operating-system Reference” for more details.</p><p>The cookbook guide also should probably mention that you may need to login to
  102. the server for the first time using linode’s weblish, and set up the root passwd
  103. with <code>passwd</code>. Then set up your user password with <code>passwd &lt;username&gt;</code>.</p><p>Now that we have a basic site set up, let’s set up certbot and the nginx services:</p><pre><code>(service certbot-service-type
  104. (certbot-configuration
  105. (email &quot;mysubscriptions@member.fsf.org&quot;)
  106. (webroot &quot;/srv/www/&quot;)
  107. (certificates
  108. (list
  109. (certificate-configuration
  110. (name &quot;the-nx.com&quot;)
  111. (domains '(&quot;the-nx.com&quot; &quot;www.the-nx.com&quot;))
  112. (deploy-hook %nginx-deploy-hook))))))
  113. (nginx-configuration
  114. (server-blocks
  115. (list
  116. (nginx-server-configuration
  117. (server-name '(&quot;the-nx.com&quot;))
  118. (listen (list &quot;80&quot;
  119. &quot;443 ssl http2&quot;
  120. ;;&quot;[::]:80&quot;
  121. ;;&quot;[::80]:443 ssl http2&quot;
  122. ))
  123. (root &quot;/srv/www/html/the-nx.com&quot;)
  124. (ssl-certificate &quot;/etc/letsencrypt/live/the-nx.com/fullchain.pem&quot;)
  125. (ssl-certificate-key &quot;/etc/letsencrypt/live/the-nx.com/privkey.pem&quot;)
  126. (locations
  127. (list
  128. (nginx-location-configuration ;; for certbot
  129. (uri &quot;/.well-known&quot;)
  130. (body (list &quot;root /srv/www;&quot;)))))))))</code></pre><p>Now let’s reconfigure and get a certbot certificate. <code>ssh</code> into the-nx.com and
  131. run these commands:</p><pre><code>sudo guix system reconfigure the-nx.com-current-config.scm
  132. # tell certbot to set up our certificates
  133. sudo /var/lib/certbot/renew-certificates</code></pre><p>So now my server has a valid certificate. It is time change the nginx
  134. configuration to proxy incoming requests to the docker all in one image.</p><p>Ok, maybe I can use sexpressions to tell nginx to redirect all incoming traffic
  135. to <code>the-nx.com</code> to the docker nextcloud image:</p><pre><code>(nginx-location-configuration
  136. (uri &quot;/&quot;)
  137. (body
  138. (list
  139. &quot;proxy_pass http://127.0.0.1:9000;\n&quot;
  140. &quot;proxy_set_header X-Real-IP $remote_addr;\n&quot;
  141. &quot;proxy_set_header Host $host;\n&quot;
  142. &quot;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;\n&quot;
  143. &quot;client_max_body_size 0;\n&quot;
  144. &quot;# Websocket\n&quot;
  145. &quot;proxy_http_version 1.1;\n&quot;
  146. &quot;proxy_set_header Upgrade $http_upgrade;\n&quot;)))</code></pre><p>I am going to deploy this image, and take a look at the generated nginx
  147. configuration file. I ran this command on my T400 laptop:</p><p><code>guix deploy the-nx.com-current-config.scm</code></p><p>Well, that’s super annoying. I do not know which nginx.conf file is the right
  148. one:</p><pre><code>find /gnu/store -name '*nginx.conf'
  149. /gnu/store/7m1ygzqk6njn5mywqmhwbydbb2z4b9li-nginx.conf
  150. /gnu/store/0gcfj61q4943h94jdqq7i9y0a0v9jr9q-nginx.conf
  151. /gnu/store/4mzrp39w5i4v94kxf98gxc13ws79l88n-nginx.conf
  152. /gnu/store/0nia2iqfw63ziasibbgq321wr9b3152n-nginx.conf
  153. /gnu/store/pf8d0sj1yf9b2ndsbc61yj3h6rp4pck2-nginx.conf
  154. /gnu/store/9nra62v41wsk08xf3msw5a1z35gji2gx-nginx-1.23.2/share/nginx/conf/nginx.conf
  155. /gnu/store/4b1szfyn0snwzf3lm1snvaapk6diz3yq-nginx.conf
  156. /gnu/store/fv5rg3nf5999vyg6qvp4sbgjysnkn1fc-nginx.conf
  157. /gnu/store/vmjwj2zwblcz4wx2whsmxdfc7zxcgjh5-nginx.conf
  158. /gnu/store/n3m2lihq9cjm6mxdln57q5nrbjgz53s6-nginx.conf
  159. /gnu/store/jnl72hx0papzb42kbd1f19qx35w76lmg-nginx-1.23.2/share/nginx/conf/nginx.conf</code></pre><p>I guess I will reboot, run <code>guix system delete-generations</code> and <code>guix gc</code>, and
  160. run the above command again:</p><pre><code>find /gnu/store -name '*nginx.conf'
  161. /gnu/store/7m1ygzqk6njn5mywqmhwbydbb2z4b9li-nginx.conf
  162. /gnu/store/jnl72hx0papzb42kbd1f19qx35w76lmg-nginx-1.23.2/share/nginx/conf/nginx.conf</code></pre><p>Well that looks promising. Let's check out my nginx.conf file.</p><pre><code>cat /gnu/store/i2mzdhg8wlbxv7iza8y4qk5v0vmvp27q-nginx.conf
  163. user nginx nginx;
  164. pid /var/run/nginx/pid;
  165. error_log /var/log/nginx/error.log info;
  166. events { }
  167. http {
  168. client_body_temp_path /var/run/nginx/client_body_temp;
  169. proxy_temp_path /var/run/nginx/proxy_temp;
  170. fastcgi_temp_path /var/run/nginx/fastcgi_temp;
  171. uwsgi_temp_path /var/run/nginx/uwsgi_temp;
  172. scgi_temp_path /var/run/nginx/scgi_temp;
  173. access_log /var/log/nginx/access.log;
  174. include /gnu/store/jnl72hx0papzb42kbd1f19qx35w76lmg-nginx-1.23.2/share/nginx/conf/mime.types;
  175. server {
  176. listen 443 ssl http2;
  177. server_name the-nx.com ;
  178. ssl_certificate /etc/letsencrypt/live/the-nx.com/fullchain.pem;
  179. ssl_certificate_key /etc/letsencrypt/live/the-nx.com/privkey.pem;
  180. root /srv/www/html/the-nx.com;
  181. index index.html ;
  182. server_tokens off;
  183. location /.well-known {
  184. root /srv/www;
  185. }
  186. location / {
  187. proxy_pass http://127.0.0.1:9000;
  188. proxy_set_header X-Real-IP $remote_addr;
  189. proxy_set_header Host $host;
  190. proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  191. client_max_body_size 0;
  192. # Websocket
  193. proxy_http_version 1.1;
  194. proxy_set_header Upgrade $http_upgrade;
  195. }
  196. }
  197. server {
  198. listen 80;
  199. listen [::]:80;
  200. server_name the-nx.com www.the-nx.com ;
  201. root /srv/http;
  202. index index.html ;
  203. server_tokens off;
  204. location /.well-known {
  205. root /srv/www/;
  206. }
  207. location / {
  208. return 301 https://$host$request_uri;
  209. }
  210. }
  211. }</code></pre><p>The generated configuration seems pretty wonky, and I am suprised that nginx is
  212. still running, but it is still running. And I suppose that it should work.</p><p>I was able to get nextcloud to start with this command:</p><pre><code>sudo docker run --sig-proxy=false --name nextcloud-aio-mastercontainer \
  213. --restart always \
  214. --publish 8080:8080 \
  215. -e APACHE_PORT=9000 \
  216. --volume nextcloud_aio_mastercontainer:/mnt/docker-aio-config \
  217. --volume /var/run/docker.sock:/var/run/docker.sock:ro \
  218. nextcloud/all-in-one:latest</code></pre><p>So now I can login at the-nx.com:8080 and configure various stuff. Also I really
  219. need to set up a firewall. That’s probably a really good idea. Also what’s nice
  220. about this docker image is that it will start itself if you update the guix
  221. system server and reboot.</p><p>MORE BONUS CONTENT:</p><p>If you see this blog post, and you decide to set up your nextcloud on a guix
  222. system server, and if your nginx config doesn’t seem to be proxying requests to
  223. your docker container, then you may follow these steps to delete the docker
  224. image and start over:</p><p>This <a href="https://help.nextcloud.com/t/aio-this-site-can-t-provide-a-secure-connection/128478/5">page</a> has some good commands for deleting the docker image and starting
  225. over:</p><pre><code>sudo docker stop nextcloud-aio-mastercontainer &amp;&amp; \\
  226. sudo docker rm nextcloud-aio-mastercontainer &amp;&amp; \\
  227. sudo docker container prune -f &amp;&amp; \\
  228. sudo docker volume prune -f &amp;&amp; \\
  229. sudo docker pull nextcloud/all-in-one:latest</code></pre><p>Ok, so it looks like the nextcloud all in one documentation has a <a href="https://github.com/nextcloud/all-in-one/blob/main/reverse-proxy.md">page</a> for
  230. understanding the reverse proxy.</p><p>It would also be nice to get my nextcloud image to sync my contacts. I probably just need to add in another nginx
  231. location line for that. That will be a project for another day.</p></div></article></section></main><footer><p>© 2020 Joshua Branson. The text on this site is free culture under the Creative Commons Attribution Share-Alike 4.0 International license.</p><p>This website is build with Haunt, a static site generator written in Guile Scheme. Source code is <a href="https://notabug.org/jbranso/gnucode.me">available.</a></p><p>The color theme of this website is based off of the famous <a href="#3f3f3f" target="_blank">zenburn</a> theme.</p></footer></body>