<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>blog.gcn.sh Reader</title>
    <link>https://blog.gcn.sh</link>
    <description>Read the latest posts from blog.gcn.sh.</description>
    <pubDate>Sun, 19 Apr 2026 14:33:10 +0000</pubDate>
    <item>
      <title>Mounting MAC M1 VMWARE Fusion Share on Linux</title>
      <link>https://blog.gcn.sh/mindnotes/mounting-mac-m1-vmware-fusion-share-on-linux</link>
      <description>&lt;![CDATA[on VMWARE/Settings/Sharing&#xA;&#xA;Here I&#39;m creating a share &#34;gutocarvalho&#34; pointing to&#xA;&#xA;/Users/gutocarvalho&#xA;&#xA;on Guest (Ubuntu 22.04)&#xA;&#xA;install open-vm-tools&#xA;&#xA;apt update &amp;&amp; apt install open-vm-tools -y&#xA;reboot&#xA;&#xA;create a dir to mount the shared folder&#xA;&#xA;cd  ~/Desktop&#xA;mkdir MacOs&#xA;&#xA;now mount it&#xA;&#xA;vmhgfs-fuse .host:/gutocarvalho /home/gutocarvalho/Desktop/MacOs -o subtype=vmhgfs-fuse &#xA;&#xA;fstab config&#xA;&#xA;.host:/gutocarvalho    /home/gutocarvalho/Desktop/MacOs       fuse.vmhgfs-fuse    defaults   0    0&#xA;&#xA;It&#39;s done!&#xA;&#xA;references&#xA;&#xA;https://docs.vmware.com/en/VMware-Workstation-Pro/17/com.vmware.ws.using.doc/GUID-AB5C80FE-9B8A-4899-8186-3DB8201B1758.html]]&gt;</description>
      <content:encoded><![CDATA[<h2 id="on-vmware-settings-sharing" id="on-vmware-settings-sharing">on VMWARE/Settings/Sharing</h2>

<p>Here I&#39;m creating a share “gutocarvalho” pointing to</p>

<pre><code>/Users/gutocarvalho
</code></pre>

<h2 id="on-guest-ubuntu-22-04" id="on-guest-ubuntu-22-04">on Guest (Ubuntu 22.04)</h2>

<p>install open-vm-tools</p>

<pre><code>apt update &amp;&amp; apt install open-vm-tools -y
reboot
</code></pre>

<p>create a dir to mount the shared folder</p>

<pre><code>cd  ~/Desktop
mkdir MacOs
</code></pre>

<p>now mount it</p>

<pre><code>vmhgfs-fuse .host:/gutocarvalho /home/gutocarvalho/Desktop/MacOs -o subtype=vmhgfs-fuse 
</code></pre>

<h2 id="fstab-config" id="fstab-config">fstab config</h2>

<pre><code>.host:/gutocarvalho    /home/gutocarvalho/Desktop/MacOs       fuse.vmhgfs-fuse    defaults   0    0
</code></pre>

<p>It&#39;s done!</p>

<h2 id="references" id="references">references</h2>
<ul><li><a href="https://docs.vmware.com/en/VMware-Workstation-Pro/17/com.vmware.ws.using.doc/GUID-AB5C80FE-9B8A-4899-8186-3DB8201B1758.html" rel="nofollow">https://docs.vmware.com/en/VMware-Workstation-Pro/17/com.vmware.ws.using.doc/GUID-AB5C80FE-9B8A-4899-8186-3DB8201B1758.html</a></li></ul>
]]></content:encoded>
      <author>mindnotes</author>
      <guid>https://blog.gcn.sh/read/a/lecv1qo6q9</guid>
      <pubDate>Wed, 26 Jun 2024 13:57:11 +0000</pubDate>
    </item>
    <item>
      <title>MacOs Menubar Curated List</title>
      <link>https://blog.gcn.sh/mindnotes/macos-menubar-curated-list</link>
      <description>&lt;![CDATA[Another to remember&#xA;&#xA;https://macmenubar.com]]&gt;</description>
      <content:encoded><![CDATA[<p>Another to remember</p>

<p><a href="https://macmenubar.com" rel="nofollow">https://macmenubar.com</a></p>
]]></content:encoded>
      <author>mindnotes</author>
      <guid>https://blog.gcn.sh/read/a/34kehbcbqm</guid>
      <pubDate>Tue, 12 Mar 2024 23:45:05 +0000</pubDate>
    </item>
    <item>
      <title>Awesome MacOs Apps</title>
      <link>https://blog.gcn.sh/mindnotes/awesome-macos-apps</link>
      <description>&lt;![CDATA[Another post to remember&#xA;&#xA;Any type&#xA;&#xA;https://github.com/phmullins/awesome-macos&#xA;https://github.com/iCHAIT/awesome-macOS&#xA;https://github.com/jaywcjlove/awesome-mac&#xA;https://github.com/MilanAryal/awesome-macos&#xA;&#xA;Open Source Only&#xA;&#xA;https://github.com/serhii-londar/open-source-mac-os-apps]]&gt;</description>
      <content:encoded><![CDATA[<p>Another post to remember</p>

<p>Any type</p>
<ul><li><a href="https://github.com/phmullins/awesome-macos" rel="nofollow">https://github.com/phmullins/awesome-macos</a></li>
<li><a href="https://github.com/iCHAIT/awesome-macOS" rel="nofollow">https://github.com/iCHAIT/awesome-macOS</a></li>
<li><a href="https://github.com/jaywcjlove/awesome-mac" rel="nofollow">https://github.com/jaywcjlove/awesome-mac</a></li>
<li><a href="https://github.com/MilanAryal/awesome-macos" rel="nofollow">https://github.com/MilanAryal/awesome-macos</a></li></ul>

<p>Open Source Only</p>
<ul><li><a href="https://github.com/serhii-londar/open-source-mac-os-apps" rel="nofollow">https://github.com/serhii-londar/open-source-mac-os-apps</a></li></ul>
]]></content:encoded>
      <author>mindnotes</author>
      <guid>https://blog.gcn.sh/read/a/5di7ficjtc</guid>
      <pubDate>Tue, 12 Mar 2024 23:39:59 +0000</pubDate>
    </item>
    <item>
      <title>Awesome Open Source Self-Hosted</title>
      <link>https://blog.gcn.sh/mindnotes/awesome-open-source-self-hosted</link>
      <description>&lt;![CDATA[Incredible list&#xA;&#xA;https://github.com/awesome-selfhosted/awesome-selfhosted&#xA;&#xA;[s]]]&gt;</description>
      <content:encoded><![CDATA[<p>Incredible list</p>

<p><a href="https://github.com/awesome-selfhosted/awesome-selfhosted" rel="nofollow">https://github.com/awesome-selfhosted/awesome-selfhosted</a></p>

<p>[s]</p>
]]></content:encoded>
      <author>mindnotes</author>
      <guid>https://blog.gcn.sh/read/a/8ct639ijyk</guid>
      <pubDate>Tue, 12 Mar 2024 23:38:43 +0000</pubDate>
    </item>
    <item>
      <title>Resizing XFS on ProxMox KVM</title>
      <link>https://blog.gcn.sh/mindnotes/resizing-xfs-on-proxmox-kvm</link>
      <description>&lt;![CDATA[In this example we&#39;ll expand a partition sdb1 mounted on the /opt directory.&#xA;&#xA;on the proxmox side&#xA;&#xA;The first thing to do is expand the disk using the proxmox UI, for that you&#39;ll need to turn off the kvm instance, expand the disk and turn it on again.&#xA;&#xA;on the linux side&#xA;&#xA;now with the os running you can&#xA;&#xA;umount /opt&#xA;parted /dev/sdb&#xA;print&#xA;fix&#xA;resizepart sdb1 100%&#xA;quit&#xA;xfsrepair /dev/sdb1&#xA;mount /opt&#xA;xfsgrowfs /dev/sdb1&#xA;&#xA;that&#39;s it!]]&gt;</description>
      <content:encoded><![CDATA[<p>In this example we&#39;ll expand a partition <strong>sdb1</strong> mounted on the <strong>/opt</strong> directory.</p>

<h2 id="on-the-proxmox-side" id="on-the-proxmox-side">on the proxmox side</h2>

<p>The first thing to do is expand the disk using the proxmox UI, for that you&#39;ll need to turn off the kvm instance, expand the disk and turn it on again.</p>

<h2 id="on-the-linux-side" id="on-the-linux-side">on the linux side</h2>

<p>now with the os running you can</p>

<pre><code>umount /opt
parted /dev/sdb
print
fix
resizepart sdb1 100%
quit
xfs_repair /dev/sdb1
mount /opt
xfs_growfs /dev/sdb1
</code></pre>

<p>that&#39;s it!</p>
]]></content:encoded>
      <author>mindnotes</author>
      <guid>https://blog.gcn.sh/read/a/ouqewucxxn</guid>
      <pubDate>Mon, 30 Oct 2023 23:37:47 +0000</pubDate>
    </item>
    <item>
      <title>Installing Minio using docker</title>
      <link>https://blog.gcn.sh/howtos/installing-minio-uising-docker</link>
      <description>&lt;![CDATA[Why&#xA;&#xA;Because we want to use our own object storage system, on-premisses.&#xA;&#xA;What do I need to install?&#xA;&#xA;You need a Linux Server with Docker, and Docker-compose installed.&#xA;&#xA;What&#39;s my setup?&#xA;&#xA;ProxMox&#xA;  KVM&#xA;    Ubuntu 20.04&#xA;      Docker&#xA;      Docker-compose&#xA;External Nginx&#xA;  Reverse Proxy Configuration&#xA;  LetsEncrypt Certificate&#xA;CloudFlare&#xA;   DNS Manager &#xA;&#xA;Where I can find out more about the project?&#xA;&#xA;Project&#xA;&#xA;https://min.io&#xA;https://min.io/docs&#xA;&#xA;Docker installation&#xA;&#xA;https://min.io/docs/minio/container/operations/installation.html&#xA;&#xA;Single Node Multi Drive Arch&#xA;&#xA;https://min.io/docs/minio/container/operations/install-deploy-manage/deploy-minio-single-node-multi-drive.html&#xA;&#xA;Hardware Requirements&#xA;&#xA;Virtual Machine&#xA;&#xA;vpcu: 8&#xA;memory: 8 gb ram&#xA;network: 1 gbit&#xA;disk: 350 gb&#xA;&#xA;Disk layout&#xA;&#xA;root (30g)&#xA;/var/lib/docker (30g)&#xA;/opt/minio (300g)&#xA;&#xA;Network requirements&#xA;&#xA;These are all the necessary ports to open&#xA;&#xA;22 TCP (ssh)&#xA;80 (minio api)&#xA;8080 (minio console)&#xA;&#xA;Any other port should be closed.&#xA;&#xA;DNS requirements&#xA;&#xA;We&#39;ll use 2 DNS Records&#xA;&#xA;minio-admin.domain.tld (console)&#xA;minio.domain.tld (api)&#xA;&#xA;How to install it?&#xA;&#xA;updating your node&#xA;&#xA;apt-get update&#xA;apt-get upgrade -y&#xA;&#xA;installing utilities&#xA;&#xA;apt install screen htop net-tools ccze git&#xA;&#xA;Docker &#xA;&#xA;Docker Install&#xA;&#xA;curl https://get.docker.com|bash&#xA;&#xA;Docker Configuration&#xA;&#xA;Let&#39;s create the configuration file.&#xA;&#xA;vim /etc/docker/daemon.json&#xA;&#xA;Content&#xA;&#xA;{&#xA;  &#34;default-address-pools&#34;: [&#xA;    {&#xA;      &#34;base&#34;: &#34;10.20.30.0/24&#34;,&#xA;      &#34;size&#34;: 24&#xA;    },&#xA;    {&#xA;      &#34;base&#34;: &#34;10.20.31.0/24&#34;,&#xA;      &#34;size&#34;: 24&#xA;    }&#xA;  ]&#xA;}&#xA;&#xA;Here we&#39;re defining uncommon networks to avoid conflicts with your provider or organization networks. You need to restart docker after it. &#xA;&#xA;systemclt restart docker&#xA;systemclt enable docker&#xA;&#xA;Docker-compose &#xA;&#xA;Docker-compose install&#xA;&#xA;Download&#xA;&#xA;curl -s https://api.github.com/repos/docker/compose/releases/latest | grep browserdownloadurl  | grep docker-compose-linux-x8664 | cut -d &#39;&#34;&#39; -f 4 | wget -qi -&#xA;&#xA;Adjusting permissions&#xA;&#xA;chmod +x docker-compose-linux-x8664&#xA;&#xA;Moving the binary to the usr/local directory&#xA;&#xA;mv docker-compose-linux-x8664 /usr/local/bin/docker-compose&#xA;&#xA;Minio&#xA;&#xA;Creating directories&#xA;&#xA;mkdir -p /opt/minio/{docker,storage}&#xA;&#xA;Creating docker-compose config&#xA;&#xA;vim /opt/minio/docker/docker-compose.yaml&#xA;&#xA;Content&#xA;&#xA;version: &#39;3.7&#39;&#xA;&#xA;Settings and configurations that are common for all containers&#xA;x-minio-common: &amp;minio-common&#xA;  image: quay.io/minio/minio:RELEASE.2023-08-04T17-40-21Z&#xA;  command: server --console-address &#34;:9001&#34; http://minio{1...4}/data{1...2}&#xA;  expose:&#xA;    &#34;9000&#34;&#xA;    &#34;9001&#34;&#xA;  environment:&#xA;    MINIOROOTUSER: minio&#xA;    MINIOROOTPASSWORD: yourpasswordhere&#xA;    MINIOSERVERURL: https://minio.domain.ltd&#xA;    MINIODOMAIN: minio.domain.ltd&#xA;  healthcheck:&#xA;    test: [&#34;CMD&#34;, &#34;curl&#34;, &#34;-f&#34;, &#34;http://localhost:9000/minio/health/live&#34;]&#xA;    interval: 30s&#xA;    timeout: 20s&#xA;    retries: 3&#xA;&#xA;starts 4 docker containers running minio server instances.&#xA;using nginx reverse proxy, load balancing, you can access&#xA;it through port 9000.&#xA;services:&#xA;  minio1:&#xA;    &lt;&lt;: minio-common&#xA;    hostname: minio1&#xA;    restart: always&#xA;    volumes:&#xA;      /MinIO/storage/data1-1:/data1&#xA;      /MinIO/storage/data1-2:/data2&#xA;&#xA;  minio2:&#xA;    &lt;&lt;: minio-common&#xA;    hostname: minio2&#xA;    restart: always&#xA;    volumes:&#xA;      /MinIO/storage/data2-1:/data1&#xA;      /MinIO/storage/data2-2:/data2&#xA;&#xA;  minio3:&#xA;    &lt;&lt;: minio-common&#xA;    hostname: minio3&#xA;    restart: always&#xA;    volumes:&#xA;      /MinIO/storage/data3-1:/data1&#xA;      /MinIO/storage/data3-2:/data2&#xA;&#xA;  minio4:&#xA;    &lt;&lt;: minio-common&#xA;    hostname: minio4&#xA;    restart: always&#xA;    volumes:&#xA;      /MinIO/storage/data4-1:/data1&#xA;      /MinIO/storage/data4-2:/data2&#xA;&#xA;  nginx:&#xA;    image: nginx:1.19.2-alpine&#xA;    hostname: nginx&#xA;    restart: always&#xA;    volumes:&#xA;      /MinIO/docker/nginx.conf:/etc/nginx/nginx.conf&#xA;    ports:&#xA;      &#34;80:80&#34;&#xA;      &#34;8080:8080&#34;&#xA;    dependson:&#xA;      minio1&#xA;      minio2&#xA;      minio3&#xA;      minio4&#xA;&#xA;By default this config uses default local driver,&#xA;For custom volumes replace with volume driver configuration.&#xA;volumes:&#xA;  data1-1:&#xA;  data1-2:&#xA;  data2-1:&#xA;  data2-2:&#xA;  data3-1:&#xA;  data3-2:&#xA;  data4-1:&#xA;  data4-2:&#xA;&#xA;Creating nginx config&#xA;&#xA;vim /opt/minio/docker/nginx.conf &#xA;&#xA;Content&#xA;&#xA;user  nginx;&#xA;workerprocesses  auto;&#xA;&#xA;errorlog  /var/log/nginx/error.log warn;&#xA;pid        /var/run/nginx.pid;&#xA;&#xA;events {&#xA;    workerconnections  4096;&#xA;}&#xA;&#xA;http {&#xA;    include       /etc/nginx/mime.types;&#xA;    defaulttype  application/octet-stream;&#xA;&#xA;    logformat  main  &#39;$remoteaddr - $remoteuser [$timelocal] &#34;$request&#34; &#39;&#xA;                      &#39;$status $bodybytessent &#34;$httpreferer&#34; &#39;&#xA;                      &#39;&#34;$httpuseragent&#34; &#34;$httpxforwardedfor&#34;&#39;;&#xA;&#xA;    sendfile        on;&#xA;    keepalivetimeout  65;&#xA;&#xA;    upstream minio {&#xA;        server minio1:9000;&#xA;        server minio2:9000;&#xA;        server minio3:9000;&#xA;        server minio4:9000;&#xA;    }&#xA;&#xA;    upstream console {&#xA;        iphash;&#xA;        server minio1:9001;&#xA;        server minio2:9001;&#xA;        server minio3:9001;&#xA;        server minio4:9001;&#xA;    }&#xA;&#xA;    server {&#xA;        listen 80;&#xA;        ignoreinvalidheaders off;&#xA;        clientmaxbodysize 0;&#xA;        proxybuffering off;&#xA;        proxyrequestbuffering off;&#xA;&#xA;        location / {&#xA;            proxysetheader Host $httphost;&#xA;            proxysetheader X-Real-IP $remoteaddr;&#xA;            proxysetheader X-Forwarded-For $proxyaddxforwardedfor;&#xA;            proxysetheader X-Forwarded-Proto $scheme;&#xA;            proxyconnecttimeout 300;&#xA;            proxyhttpversion 1.1;&#xA;            proxysetheader Connection &#34;&#34;;&#xA;            chunkedtransferencoding off;&#xA;            proxypass http://minio;&#xA;        }&#xA;    }&#xA;&#xA;    server {&#xA;        listen       8080;&#xA;        ignoreinvalidheaders off;&#xA;        clientmaxbodysize 0;&#xA;        proxybuffering off;&#xA;        proxyrequestbuffering off;&#xA;&#xA;        location / {&#xA;            proxysetheader Host $httphost;&#xA;            proxysetheader X-Real-IP $remoteaddr;&#xA;            proxysetheader X-Forwarded-For $proxyaddxforwardedfor;&#xA;            proxysetheader X-Forwarded-Proto $scheme;&#xA;            proxysetheader X-NginX-Proxy true;&#xA;            realipheader X-Real-IP;&#xA;            proxyconnecttimeout 300;&#xA;            proxyhttpversion 1.1;&#xA;            proxysetheader Upgrade $httpupgrade;&#xA;            proxysetheader Connection &#34;upgrade&#34;;&#xA;            chunkedtransferencoding off;&#xA;&#xA;            proxypass http://console;&#xA;        }&#xA;    }&#xA;}&#xA;&#xA;starting containers&#xA;&#xA;cd /opt/minio/docker&#xA;docker-compose up -d&#xA;&#xA;checking services&#xA;&#xA;docker-compose ps&#xA;&#xA;Expected output&#xA;&#xA;NAME                IMAGE                                              COMMAND                  SERVICE             CREATED             STATUS                   PORTS&#xA;docker-minio1-1     quay.io/minio/minio:RELEASE.2023-08-04T17-40-21Z   &#34;/usr/bin/docker-ent…&#34;   minio1              11 minutes ago      Up 9 minutes (healthy)   9000-9001/tcp&#xA;docker-minio2-1     quay.io/minio/minio:RELEASE.2023-08-04T17-40-21Z   &#34;/usr/bin/docker-ent…&#34;   minio2              11 minutes ago      Up 9 minutes (healthy)   9000-9001/tcp&#xA;docker-minio3-1     quay.io/minio/minio:RELEASE.2023-08-04T17-40-21Z   &#34;/usr/bin/docker-ent…&#34;   minio3              11 minutes ago      Up 9 minutes (healthy)   9000-9001/tcp&#xA;docker-minio4-1     quay.io/minio/minio:RELEASE.2023-08-04T17-40-21Z   &#34;/usr/bin/docker-ent…&#34;   minio4              11 minutes ago      Up 9 minutes (healthy)   9000-9001/tcp&#xA;docker-nginx-1      nginx:1.19.2-alpine                                &#34;/docker-entrypoint.…&#34;   nginx               11 minutes ago      Up 9 minutes             0.0.0.0:80-  80/tcp, :::80-  80/tcp, 0.0.0.0:8080-  8080/tcp, :::8080-  8080/tcp&#xA;&#xA;Check it the ports 9001 and 9001&#xA;&#xA;netstat -ntpl|grep docker&#xA;&#xA;Expected Ouput&#xA;&#xA;tcp        0      0 0.0.0.0:80              0.0.0.0:               LISTEN      2116141/docker-prox&#xA;tcp        0      0 0.0.0.0:8080            0.0.0.0:               LISTEN      2116110/docker-prox&#xA;tcp6       0      0 :::80                   :::                    LISTEN      2116149/docker-prox&#xA;tcp6       0      0 :::8080                 :::                    LISTEN      2116123/docker-prox&#xA;&#xA;You can now validate the console&#xA;&#xA;curl http://localhost:80&#xA;&#xA;Expected Output&#xA;&#xA;!doctype htmlhtml lang=&#34;en&#34;headmeta charset=&#34;utf-8&#34;/base href=&#34;/&#34;/meta content=&#34;width=device-width,initial-scale=1&#34; name=&#34;viewport&#34;/meta content=&#34;#081C42&#34; media=&#34;(prefers-color-scheme: light)&#34; name=&#34;theme-color&#34;/meta content=&#34;#081C42&#34; media=&#34;(prefers-color-scheme: dark)&#34; name=&#34;theme-color&#34;/meta content=&#34;MinIO Console&#34; name=&#34;description&#34;/meta name=&#34;minio-license&#34; content=&#34;agpl&#34; /link href=&#34;./styles/root-styles.css&#34; rel=&#34;stylesheet&#34;/link href=&#34;./apple-icon-180x180.png&#34; rel=&#34;apple-touch-icon&#34; sizes=&#34;180x180&#34;/link href=&#34;./favicon-32x32.png&#34; rel=&#34;icon&#34; sizes=&#34;32x32&#34; type=&#34;image/png&#34;/link href=&#34;./favicon-96x96.png&#34; rel=&#34;icon&#34; sizes=&#34;96x96&#34; type=&#34;image/png&#34;/link href=&#34;./favicon-16x16.png&#34; rel=&#34;icon&#34; sizes=&#34;16x16&#34; type=&#34;image/png&#34;/link href=&#34;./manifest.json&#34; rel=&#34;manifest&#34;/link color=&#34;#3a4e54&#34; href=&#34;./safari-pinned-tab.svg&#34; rel=&#34;mask-icon&#34;/titleMinIO Console/titlescript defer=&#34;defer&#34; src=&#34;./static/js/main.92fa0385.js&#34;/scriptlink href=&#34;./static/css/main.02c1b6fd.css&#34; rel=&#34;stylesheet&#34;/headbodynoscriptYou need to enable JavaScript to run this app./noscriptdiv id=&#34;root&#34;div id=&#34;preload&#34;img src=&#34;./images/background.svg&#34;/ img src=&#34;./images/background-wave-orig2.svg&#34;//divdiv id=&#34;loader-block&#34;img src=&#34;./Loader.svg&#34;//div/div/body/html&#xA;&#xA;You can now validate if the API is running&#xA;&#xA;curl http://localhost:80&#xA;&#xA;Expected output&#xA;&#xA;?xml version=&#34;1.0&#34; encoding=&#34;UTF-8&#34;?&#xA;ErrorCodeAccessDenied/CodeMessageAccess Denied./MessageResource//ResourceRequestId177E5BC14618C529/RequestIdHostIde0c385c033c4356721cc9121d3109c9b9bfdefb22fd2747078acd22328799e36/HostId/Errorroot@bolha.io:/MinIO/docker#&#xA;&#xA;Validate if the API is Healthly&#xA;&#xA;curl -si http:///localhost/minio/health/live&#xA;&#xA;Expected output&#xA;&#xA;HTTP/1.1 200 OK&#xA;Server: nginx/1.19.2&#xA;Date: Thu, 24 Aug 2023 15:38:38 GMT&#xA;Content-Length: 0&#xA;Connection: keep-alive&#xA;Accept-Ranges: bytes&#xA;Strict-Transport-Security: max-age=31536000; includeSubDomains&#xA;Vary: Origin&#xA;X-Amz-Id-2: 46efbbb7efbd81c7d995bde03cc6fabf60c12f80d4e074c1c972dbc4d583c3d4&#xA;X-Amz-Request-Id: 177E5BDDF79EDEF8&#xA;X-Content-Type-Options: nosniff&#xA;X-Xss-Protection: 1; mode=block&#xA;&#xA;Reverse Proxy&#xA;&#xA;You can now configure your reverse proxy&#xA;&#xA;minio-admin.domain.tld =  the ip-of-the-vm port 8080.&#xA;minio.domain.tlds =  ip-of-the-vm port 80.&#xA;&#xA;We&#39;ll not cover the reverse proxy config yet, maybe in the future.&#xA;&#xA;Accessing Minio&#xA;&#xA;After the configuration you can visite the admin console&#xA;&#xA;https://minio-admin.domain.tld&#xA;&#xA;Viewing logs&#xA;&#xA;You can follow the containers logs during the minio usage.&#xA;&#xA;cd /opt/minio/docker&#xA;docker-compose logs -f --tail=10&#xA;&#xA;Cheers&#xA;[s]&#xA;&#xA;]]&gt;</description>
      <content:encoded><![CDATA[<h2 id="why" id="why">Why</h2>

<p>Because we want to use our own object storage system, on-premisses.</p>

<h2 id="what-do-i-need-to-install" id="what-do-i-need-to-install">What do I need to install?</h2>

<p>You need a Linux Server with Docker, and Docker-compose installed.</p>

<h2 id="what-s-my-setup" id="what-s-my-setup">What&#39;s my setup?</h2>
<ul><li>ProxMox
<ul><li>KVM</li>
<li>Ubuntu 20.04
<ul><li>Docker</li>
<li>Docker-compose</li></ul></li></ul></li>
<li>External Nginx
<ul><li>Reverse Proxy Configuration</li>
<li>LetsEncrypt Certificate</li></ul></li>
<li>CloudFlare
<ul><li>DNS Manager</li></ul></li></ul>

<h2 id="where-i-can-find-out-more-about-the-project" id="where-i-can-find-out-more-about-the-project">Where I can find out more about the project?</h2>

<p>Project</p>
<ul><li><a href="https://min.io" rel="nofollow">https://min.io</a></li>
<li><a href="https://min.io/docs" rel="nofollow">https://min.io/docs</a></li></ul>

<p>Docker installation</p>
<ul><li><a href="https://min.io/docs/minio/container/operations/installation.html" rel="nofollow">https://min.io/docs/minio/container/operations/installation.html</a></li></ul>

<p>Single Node Multi Drive Arch</p>
<ul><li><a href="https://min.io/docs/minio/container/operations/install-deploy-manage/deploy-minio-single-node-multi-drive.html" rel="nofollow">https://min.io/docs/minio/container/operations/install-deploy-manage/deploy-minio-single-node-multi-drive.html</a></li></ul>

<h2 id="hardware-requirements" id="hardware-requirements">Hardware Requirements</h2>

<p>Virtual Machine</p>

<pre><code>vpcu: 8
memory: 8 gb ram
network: 1 gbit
disk: 350 gb
</code></pre>

<p>Disk layout</p>

<pre><code>root (30g)
/var/lib/docker (30g)
/opt/minio (300g)
</code></pre>

<h2 id="network-requirements" id="network-requirements">Network requirements</h2>

<p>These are all the necessary ports to open</p>

<pre><code>22 TCP (ssh)
80 (minio api)
8080 (minio console)
</code></pre>

<p>Any other port should be closed.</p>

<h3 id="dns-requirements" id="dns-requirements">DNS requirements</h3>

<p>We&#39;ll use 2 DNS Records</p>

<pre><code>minio-admin.domain.tld (console)
minio.domain.tld (api)
</code></pre>

<h2 id="how-to-install-it" id="how-to-install-it">How to install it?</h2>

<h3 id="updating-your-node" id="updating-your-node">updating your node</h3>

<pre><code>apt-get update
apt-get upgrade -y
</code></pre>

<h3 id="installing-utilities" id="installing-utilities">installing utilities</h3>

<pre><code>apt install screen htop net-tools ccze git
</code></pre>

<h2 id="docker" id="docker">Docker</h2>

<h3 id="docker-install" id="docker-install">Docker Install</h3>

<pre><code>curl https://get.docker.com|bash
</code></pre>

<h3 id="docker-configuration" id="docker-configuration">Docker Configuration</h3>

<p>Let&#39;s create the configuration file.</p>

<pre><code>vim /etc/docker/daemon.json
</code></pre>

<p>Content</p>

<pre><code>{
  &#34;default-address-pools&#34;: [
    {
      &#34;base&#34;: &#34;10.20.30.0/24&#34;,
      &#34;size&#34;: 24
    },
    {
      &#34;base&#34;: &#34;10.20.31.0/24&#34;,
      &#34;size&#34;: 24
    }
  ]
}
</code></pre>

<p>Here we&#39;re defining uncommon networks to avoid conflicts with your provider or organization networks. You need to restart docker after it.</p>

<pre><code>systemclt restart docker
systemclt enable docker
</code></pre>

<h2 id="docker-compose" id="docker-compose">Docker-compose</h2>

<h3 id="docker-compose-install" id="docker-compose-install">Docker-compose install</h3>

<p>Download</p>

<pre><code>curl -s https://api.github.com/repos/docker/compose/releases/latest | grep browser_download_url  | grep docker-compose-linux-x86_64 | cut -d &#39;&#34;&#39; -f 4 | wget -qi -
</code></pre>

<p>Adjusting permissions</p>

<pre><code>chmod +x docker-compose-linux-x86_64
</code></pre>

<p>Moving the binary to the usr/local directory</p>

<pre><code>mv docker-compose-linux-x86_64 /usr/local/bin/docker-compose
</code></pre>

<h2 id="minio" id="minio">Minio</h2>

<h3 id="creating-directories" id="creating-directories">Creating directories</h3>

<pre><code>mkdir -p /opt/minio/{docker,storage}
</code></pre>

<h3 id="creating-docker-compose-config" id="creating-docker-compose-config">Creating docker-compose config</h3>

<pre><code>vim /opt/minio/docker/docker-compose.yaml
</code></pre>

<p>Content</p>

<pre><code>version: &#39;3.7&#39;

# Settings and configurations that are common for all containers
x-minio-common: &amp;minio-common
  image: quay.io/minio/minio:RELEASE.2023-08-04T17-40-21Z
  command: server --console-address &#34;:9001&#34; http://minio{1...4}/data{1...2}
  expose:
    - &#34;9000&#34;
    - &#34;9001&#34;
  environment:
    MINIO_ROOT_USER: minio
    MINIO_ROOT_PASSWORD: your_password_here
    MINIO_SERVER_URL: https://minio.domain.ltd
    MINIO_DOMAIN: minio.domain.ltd
  healthcheck:
    test: [&#34;CMD&#34;, &#34;curl&#34;, &#34;-f&#34;, &#34;http://localhost:9000/minio/health/live&#34;]
    interval: 30s
    timeout: 20s
    retries: 3

# starts 4 docker containers running minio server instances.
# using nginx reverse proxy, load balancing, you can access
# it through port 9000.
services:
  minio1:
    &lt;&lt;: *minio-common
    hostname: minio1
    restart: always
    volumes:
      - /MinIO/storage/data1-1:/data1
      - /MinIO/storage/data1-2:/data2

  minio2:
    &lt;&lt;: *minio-common
    hostname: minio2
    restart: always
    volumes:
      - /MinIO/storage/data2-1:/data1
      - /MinIO/storage/data2-2:/data2

  minio3:
    &lt;&lt;: *minio-common
    hostname: minio3
    restart: always
    volumes:
      - /MinIO/storage/data3-1:/data1
      - /MinIO/storage/data3-2:/data2

  minio4:
    &lt;&lt;: *minio-common
    hostname: minio4
    restart: always
    volumes:
      - /MinIO/storage/data4-1:/data1
      - /MinIO/storage/data4-2:/data2

  nginx:
    image: nginx:1.19.2-alpine
    hostname: nginx
    restart: always
    volumes:
      - /MinIO/docker/nginx.conf:/etc/nginx/nginx.conf
    ports:
      - &#34;80:80&#34;
      - &#34;8080:8080&#34;
    depends_on:
      - minio1
      - minio2
      - minio3
      - minio4

## By default this config uses default local driver,
## For custom volumes replace with volume driver configuration.
volumes:
  data1-1:
  data1-2:
  data2-1:
  data2-2:
  data3-1:
  data3-2:
  data4-1:
  data4-2:
</code></pre>

<h3 id="creating-nginx-config" id="creating-nginx-config">Creating nginx config</h3>

<pre><code>vim /opt/minio/docker/nginx.conf 
</code></pre>

<p>Content</p>

<pre><code>user  nginx;
worker_processes  auto;

error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;

events {
    worker_connections  4096;
}

http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  &#39;$remote_addr - $remote_user [$time_local] &#34;$request&#34; &#39;
                      &#39;$status $body_bytes_sent &#34;$http_referer&#34; &#39;
                      &#39;&#34;$http_user_agent&#34; &#34;$http_x_forwarded_for&#34;&#39;;

    sendfile        on;
    keepalive_timeout  65;

    upstream minio {
        server minio1:9000;
        server minio2:9000;
        server minio3:9000;
        server minio4:9000;
    }

    upstream console {
        ip_hash;
        server minio1:9001;
        server minio2:9001;
        server minio3:9001;
        server minio4:9001;
    }

    server {
        listen 80;
        ignore_invalid_headers off;
        client_max_body_size 0;
        proxy_buffering off;
        proxy_request_buffering off;

        location / {
            proxy_set_header Host $http_host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Forwarded-Proto $scheme;
            proxy_connect_timeout 300;
            proxy_http_version 1.1;
            proxy_set_header Connection &#34;&#34;;
            chunked_transfer_encoding off;
            proxy_pass http://minio;
        }
    }

    server {
        listen       8080;
        ignore_invalid_headers off;
        client_max_body_size 0;
        proxy_buffering off;
        proxy_request_buffering off;

        location / {
            proxy_set_header Host $http_host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Forwarded-Proto $scheme;
            proxy_set_header X-NginX-Proxy true;
            real_ip_header X-Real-IP;
            proxy_connect_timeout 300;
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection &#34;upgrade&#34;;
            chunked_transfer_encoding off;

            proxy_pass http://console;
        }
    }
}
</code></pre>

<h3 id="starting-containers" id="starting-containers">starting containers</h3>

<pre><code>cd /opt/minio/docker
docker-compose up -d
</code></pre>

<h3 id="checking-services" id="checking-services">checking services</h3>

<pre><code>docker-compose ps
</code></pre>

<p>Expected output</p>

<pre><code>NAME                IMAGE                                              COMMAND                  SERVICE             CREATED             STATUS                   PORTS
docker-minio1-1     quay.io/minio/minio:RELEASE.2023-08-04T17-40-21Z   &#34;/usr/bin/docker-ent…&#34;   minio1              11 minutes ago      Up 9 minutes (healthy)   9000-9001/tcp
docker-minio2-1     quay.io/minio/minio:RELEASE.2023-08-04T17-40-21Z   &#34;/usr/bin/docker-ent…&#34;   minio2              11 minutes ago      Up 9 minutes (healthy)   9000-9001/tcp
docker-minio3-1     quay.io/minio/minio:RELEASE.2023-08-04T17-40-21Z   &#34;/usr/bin/docker-ent…&#34;   minio3              11 minutes ago      Up 9 minutes (healthy)   9000-9001/tcp
docker-minio4-1     quay.io/minio/minio:RELEASE.2023-08-04T17-40-21Z   &#34;/usr/bin/docker-ent…&#34;   minio4              11 minutes ago      Up 9 minutes (healthy)   9000-9001/tcp
docker-nginx-1      nginx:1.19.2-alpine                                &#34;/docker-entrypoint.…&#34;   nginx               11 minutes ago      Up 9 minutes             0.0.0.0:80-&gt;80/tcp, :::80-&gt;80/tcp, 0.0.0.0:8080-&gt;8080/tcp, :::8080-&gt;8080/tcp
</code></pre>

<p>Check it the ports 9001 and 9001</p>

<pre><code>netstat -ntpl|grep docker
</code></pre>

<p>Expected Ouput</p>

<pre><code>tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      2116141/docker-prox
tcp        0      0 0.0.0.0:8080            0.0.0.0:*               LISTEN      2116110/docker-prox
tcp6       0      0 :::80                   :::*                    LISTEN      2116149/docker-prox
tcp6       0      0 :::8080                 :::*                    LISTEN      2116123/docker-prox
</code></pre>

<p>You can now validate the console</p>

<pre><code>curl http://localhost:80
</code></pre>

<p>Expected Output</p>

<pre><code>&lt;!doctype html&gt;&lt;html lang=&#34;en&#34;&gt;&lt;head&gt;&lt;meta charset=&#34;utf-8&#34;/&gt;&lt;base href=&#34;/&#34;/&gt;&lt;meta content=&#34;width=device-width,initial-scale=1&#34; name=&#34;viewport&#34;/&gt;&lt;meta content=&#34;#081C42&#34; media=&#34;(prefers-color-scheme: light)&#34; name=&#34;theme-color&#34;/&gt;&lt;meta content=&#34;#081C42&#34; media=&#34;(prefers-color-scheme: dark)&#34; name=&#34;theme-color&#34;/&gt;&lt;meta content=&#34;MinIO Console&#34; name=&#34;description&#34;/&gt;&lt;meta name=&#34;minio-license&#34; content=&#34;agpl&#34; /&gt;&lt;link href=&#34;./styles/root-styles.css&#34; rel=&#34;stylesheet&#34;/&gt;&lt;link href=&#34;./apple-icon-180x180.png&#34; rel=&#34;apple-touch-icon&#34; sizes=&#34;180x180&#34;/&gt;&lt;link href=&#34;./favicon-32x32.png&#34; rel=&#34;icon&#34; sizes=&#34;32x32&#34; type=&#34;image/png&#34;/&gt;&lt;link href=&#34;./favicon-96x96.png&#34; rel=&#34;icon&#34; sizes=&#34;96x96&#34; type=&#34;image/png&#34;/&gt;&lt;link href=&#34;./favicon-16x16.png&#34; rel=&#34;icon&#34; sizes=&#34;16x16&#34; type=&#34;image/png&#34;/&gt;&lt;link href=&#34;./manifest.json&#34; rel=&#34;manifest&#34;/&gt;&lt;link color=&#34;#3a4e54&#34; href=&#34;./safari-pinned-tab.svg&#34; rel=&#34;mask-icon&#34;/&gt;&lt;title&gt;MinIO Console&lt;/title&gt;&lt;script defer=&#34;defer&#34; src=&#34;./static/js/main.92fa0385.js&#34;&gt;&lt;/script&gt;&lt;link href=&#34;./static/css/main.02c1b6fd.css&#34; rel=&#34;stylesheet&#34;&gt;&lt;/head&gt;&lt;body&gt;&lt;noscript&gt;You need to enable JavaScript to run this app.&lt;/noscript&gt;&lt;div id=&#34;root&#34;&gt;&lt;div id=&#34;preload&#34;&gt;&lt;img src=&#34;./images/background.svg&#34;/&gt; &lt;img src=&#34;./images/background-wave-orig2.svg&#34;/&gt;&lt;/div&gt;&lt;div id=&#34;loader-block&#34;&gt;&lt;img src=&#34;./Loader.svg&#34;/&gt;&lt;/div&gt;&lt;/div&gt;&lt;/body&gt;&lt;/html&gt;
</code></pre>

<p>You can now validate if the API is running</p>

<pre><code>curl http://localhost:80
</code></pre>

<p>Expected output</p>

<pre><code>&lt;?xml version=&#34;1.0&#34; encoding=&#34;UTF-8&#34;?&gt;
&lt;Error&gt;&lt;Code&gt;AccessDenied&lt;/Code&gt;&lt;Message&gt;Access Denied.&lt;/Message&gt;&lt;Resource&gt;/&lt;/Resource&gt;&lt;RequestId&gt;177E5BC14618C529&lt;/RequestId&gt;&lt;HostId&gt;e0c385c033c4356721cc9121d3109c9b9bfdefb22fd2747078acd22328799e36&lt;/HostId&gt;&lt;/Error&gt;root@bolha.io:/MinIO/docker#
</code></pre>

<p>Validate if the API is Healthly</p>

<pre><code>curl -si http:///localhost/minio/health/live
</code></pre>

<p>Expected output</p>

<pre><code>HTTP/1.1 200 OK
Server: nginx/1.19.2
Date: Thu, 24 Aug 2023 15:38:38 GMT
Content-Length: 0
Connection: keep-alive
Accept-Ranges: bytes
Strict-Transport-Security: max-age=31536000; includeSubDomains
Vary: Origin
X-Amz-Id-2: 46efbbb7efbd81c7d995bde03cc6fabf60c12f80d4e074c1c972dbc4d583c3d4
X-Amz-Request-Id: 177E5BDDF79EDEF8
X-Content-Type-Options: nosniff
X-Xss-Protection: 1; mode=block
</code></pre>

<h2 id="reverse-proxy" id="reverse-proxy">Reverse Proxy</h2>

<p>You can now configure your reverse proxy</p>

<pre><code>minio-admin.domain.tld =&gt; the ip-of-the-vm port 8080.
minio.domain.tlds =&gt; ip-of-the-vm port 80.
</code></pre>

<p>We&#39;ll not cover the reverse proxy config yet, maybe in the future.</p>

<h2 id="accessing-minio" id="accessing-minio">Accessing Minio</h2>

<p>After the configuration you can visite the admin console</p>

<pre><code>https://minio-admin.domain.tld
</code></pre>

<h2 id="viewing-logs" id="viewing-logs">Viewing logs</h2>

<p>You can follow the containers logs during the minio usage.</p>

<pre><code>cd /opt/minio/docker
docker-compose logs -f --tail=10
</code></pre>

<p>Cheers
[s]</p>
]]></content:encoded>
      <author>howtos</author>
      <guid>https://blog.gcn.sh/read/a/ozwsef0hg5</guid>
      <pubDate>Sun, 27 Aug 2023 00:30:58 +0000</pubDate>
    </item>
    <item>
      <title>Updating Mastodon to the version 4.1.4</title>
      <link>https://blog.gcn.sh/howtos/updating-mastodon-to-the-version-4-1-4</link>
      <description>&lt;![CDATA[Why?&#xA;&#xA;Because it&#39;s important to use the last version with the latest bug fixes and features.&#xA;&#xA;What do I need to update?&#xA;&#xA;You need a working mastodon, and we&#39;re expecting that you had followed our howto&#xA;&#xA;https://blog.gcn.sh/howtos/installing-mastodon-4-1-2-using-docker-on-ubuntu&#xA;&#xA;How to upgrade&#xA;&#xA;The Docker side&#xA;&#xA;stop the containers&#xA;&#xA;cd /opt/mastodon/docker&#xA;docker-compose down&#xA;&#xA;edit the versions.env file&#xA;&#xA;vim /opt/mastodon/docker/versions.env&#xA;&#xA;and change the version to the latest&#xA;&#xA;MASTODONVERSION=v4.1.2&#xA;&#xA;to&#xA;&#xA;MASTODONVERSION=v4.1.4&#xA;&#xA;clear the web directories&#xA;&#xA;rm -rf /opt/mastodon/data/web/public/&#xA;rm -rf /opt/mastodon/data/web/config/&#xA;rm -rf /opt/mastodon/data/web/app/&#xA;rm -rf /opt/mastodon/data/web/system/&#xA;&#xA;and start all containers again&#xA;&#xA;cd /opt/mastodon/docker&#xA;docker-compose up -d&#xA;&#xA;and run the migration&#xA;&#xA;cd /opt/mastodon/docker&#xA;docker-compose run --rm shell bundle exec rake db:migrate&#xA;&#xA;customizations&#xA;&#xA;you need to apply any customization to these directory files again if you had modified anything before.&#xA;&#xA;/opt/mastodon/data/web/public/&#xA;/opt/mastodon/data/web/config/&#xA;/opt/mastodon/data/web/app/&#xA;/opt/mastodon/data/web/system/&#xA;&#xA;The External Nginx side&#xA;&#xA;Now we need to update the static files cache on our nginx reverse proxy.&#xA;&#xA;nginx cache config&#xA;&#xA;Edit your mastodon vhost filer&#xA;&#xA;vim /etc/nginx/conf.d/mastodon.conf&#xA;&#xA;fine the cache line&#xA;&#xA;proxycachepath /var/cache/mastodon/public/4.1.2 levels=1:2 keyszone=MASTODONCACHEv412:10m inactive=7d maxsize=3g;&#xA;&#xA;change the cache directory&#xA;&#xA;proxycachepath /var/cache/mastodon/public/4.1.4 levels=1:2 keyszone=MASTODONCACHEv412:10m inactive=7d maxsize=3g;&#xA;&#xA;create the new directory&#xA;&#xA;mkdir -p /var/cache/mastodon/public/4.1.4&#xA;&#xA;root directory&#xA;&#xA;find the root directory line&#xA;&#xA;  root /var/www/mastodon/dev.bolha.us/public/4.1.2;&#xA;&#xA;change it&#xA;&#xA;  root /var/www/mastodon/dev.bolha.us/public/4.1.4;&#xA;&#xA;create the new directory&#xA;&#xA;mkdir -p /var/www/mastodon/dev.bolha.us/public/4.1.4;&#xA;&#xA;creating a docker volume to copy the new static files&#xA;&#xA;docker volume create --opt type=none --opt device=/opt/www/mastodon/dev.bolha.us/public/4.1.4 --opt o=bind mastodonpublic4.1.4&#xA;&#xA;copying the new static files from the new version to the volume&#xA;&#xA;docker run --rm -v &#34;mastodonpublic4.1.4:/static&#34; tootsuite/mastodon:v4.1.4 bash -c &#34;cp -r /opt/mastodon/public/* /static/&#34;&#xA;&#xA;checking the files&#xA;&#xA;ls /opt/www/mastodon/dev.bolha.us/public/4.1.4&#xA;&#xA;remove the temporary volume&#xA;&#xA;docker volume rm mastodonpublic4.1.4&#xA;&#xA;now verify your nginx config&#xA;&#xA;nginx -t&#xA;&#xA;nginx: the configuration file /etc/nginx/nginx.conf syntax is ok&#xA;nginx: configuration file /etc/nginx/nginx.conf test is successful&#xA;&#xA;now reload your nginx&#xA;&#xA;systemctl restart nginx &amp;&amp; systemctl status nginx&#xA;&#xA;That&#39;s it!]]&gt;</description>
      <content:encoded><![CDATA[<h2 id="why" id="why">Why?</h2>

<p>Because it&#39;s important to use the last version with the latest bug fixes and features.</p>

<h2 id="what-do-i-need-to-update" id="what-do-i-need-to-update">What do I need to update?</h2>

<p>You need a working mastodon, and we&#39;re expecting that you had followed our howto</p>
<ul><li><a href="https://blog.gcn.sh/howtos/installing-mastodon-4-1-2-using-docker-on-ubuntu" rel="nofollow">https://blog.gcn.sh/howtos/installing-mastodon-4-1-2-using-docker-on-ubuntu</a></li></ul>

<h2 id="how-to-upgrade" id="how-to-upgrade">How to upgrade</h2>

<h3 id="the-docker-side" id="the-docker-side">The Docker side</h3>

<p>stop the containers</p>

<pre><code>cd /opt/mastodon/docker
docker-compose down
</code></pre>

<p>edit the versions.env file</p>

<pre><code>vim /opt/mastodon/docker/versions.env
</code></pre>

<p>and change the version to the latest</p>

<pre><code>MASTODON_VERSION=v4.1.2
</code></pre>

<p>to</p>

<pre><code>MASTODON_VERSION=v4.1.4
</code></pre>

<p>clear the web directories</p>

<pre><code>rm -rf /opt/mastodon/data/web/public/*
rm -rf /opt/mastodon/data/web/config/*
rm -rf /opt/mastodon/data/web/app/*
rm -rf /opt/mastodon/data/web/system/*
</code></pre>

<p>and start all containers again</p>

<pre><code>cd /opt/mastodon/docker
docker-compose up -d
</code></pre>

<p>and run the migration</p>

<pre><code>cd /opt/mastodon/docker
docker-compose run --rm shell bundle exec rake db:migrate
</code></pre>

<h3 id="customizations" id="customizations">customizations</h3>

<p>you need to apply any customization to these directory files again if you had modified anything before.</p>

<pre><code>/opt/mastodon/data/web/public/*
/opt/mastodon/data/web/config/*
/opt/mastodon/data/web/app/*
/opt/mastodon/data/web/system/*
</code></pre>

<h3 id="the-external-nginx-side" id="the-external-nginx-side">The External Nginx side</h3>

<p>Now we need to update the static files cache on our nginx reverse proxy.</p>

<h3 id="nginx-cache-config" id="nginx-cache-config">nginx cache config</h3>

<p>Edit your mastodon vhost filer</p>

<pre><code>vim /etc/nginx/conf.d/mastodon.conf
</code></pre>

<p>fine the cache line</p>

<pre><code>proxy_cache_path /var/cache/mastodon/public/4.1.2 levels=1:2 keys_zone=MASTODON_CACHE_v412:10m inactive=7d max_size=3g;
</code></pre>

<p>change the cache directory</p>

<pre><code>proxy_cache_path /var/cache/mastodon/public/4.1.4 levels=1:2 keys_zone=MASTODON_CACHE_v412:10m inactive=7d max_size=3g;
</code></pre>

<p>create the new directory</p>

<pre><code>mkdir -p /var/cache/mastodon/public/4.1.4
</code></pre>

<h3 id="root-directory" id="root-directory">root directory</h3>

<p>find the root directory line</p>

<pre><code>  root /var/www/mastodon/dev.bolha.us/public/4.1.2;
</code></pre>

<p>change it</p>

<pre><code>  root /var/www/mastodon/dev.bolha.us/public/4.1.4;
</code></pre>

<p>create the new directory</p>

<pre><code>mkdir -p /var/www/mastodon/dev.bolha.us/public/4.1.4;
</code></pre>

<p>creating a docker volume to copy the new static files</p>

<pre><code>docker volume create --opt type=none --opt device=/opt/www/mastodon/dev.bolha.us/public/4.1.4 --opt o=bind mastodon_public_4.1.4
</code></pre>

<p>copying the new static files from the new version to the volume</p>

<pre><code>docker run --rm -v &#34;mastodon_public_4.1.4:/static&#34; tootsuite/mastodon:v4.1.4 bash -c &#34;cp -r /opt/mastodon/public/* /static/&#34;
</code></pre>

<p>checking the files</p>

<pre><code>ls /opt/www/mastodon/dev.bolha.us/public/4.1.4
</code></pre>

<p>remove the temporary volume</p>

<pre><code>docker volume rm mastodon_public_4.1.4
</code></pre>

<p>now verify your nginx config</p>

<pre><code># nginx -t

nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
</code></pre>

<p>now reload your nginx</p>

<pre><code>systemctl restart nginx &amp;&amp; systemctl status nginx
</code></pre>

<p>That&#39;s it!</p>
]]></content:encoded>
      <author>howtos</author>
      <guid>https://blog.gcn.sh/read/a/titnmlh5le</guid>
      <pubDate>Fri, 07 Jul 2023 18:31:45 +0000</pubDate>
    </item>
    <item>
      <title>Installing Lemmy 0.18.1 with Docker on Ubuntu</title>
      <link>https://blog.gcn.sh/howtos/installing-lemmy-0-18-1-with-docker-on-ubuntu</link>
      <description>&lt;![CDATA[Last update: 2023-07-07&#xA;&#xA;Why?&#xA;&#xA;Because we want to use a federated forum and link aggregator :)&#xA;&#xA;What do I need to install?&#xA;&#xA;You need a Linux Server with Docker, and Docker-compose installed.&#xA;creating directories&#xA;&#xA;What&#39;s my setup?&#xA;&#xA;ProxMox&#xA;  KVM&#xA;    Ubuntu 20.04&#xA;      Docker&#xA;      Docker-compose&#xA;External Nginx&#xA;  Reverse Proxy Configuration&#xA;  LetsEncrypt Certificate&#xA;&#xA;Where I can find out more about the project?&#xA;&#xA;https://join-lemmy.org&#xA;https://join-lemmy.org/docs&#xA;https://join-lemmy.org/docs/administration/installdocker.html&#xA;&#xA;How I can install it?&#xA;&#xA;creating directories&#xA;&#xA;mkdir -p /opt/lemmy&#xA;mkdir -p /opt/lemmy/{docker,data,config}&#xA;mkdir -p /opt/lemmy/data/{postgresql,pictrs,themes}&#xA;mkdir -p /opt/lemmy/config/{lemmy,postgresql,nginx}&#xA;&#xA;defining permissions&#xA;&#xA;chown -R 991:991 /opt/lemmy/data/pictrs&#xA;&#xA;nginx config&#xA;&#xA;creating the nginx.conf file&#xA;&#xA;vim /opt/lemmy/config/nginx/nginx.conf&#xA;&#xA;content&#xA;&#xA;workerprocesses auto;&#xA;&#xA;events {&#xA;    workerconnections 1024;&#xA;}&#xA;&#xA;http {&#xA;&#xA;    map &#34;$requestmethod:$httpaccept&#34; $proxpass {&#xA;        default &#34;http://lemmy-ui&#34;;&#xA;        &#34;~^(?:GET|HEAD):.?application\/(?:activity|ld)\+json&#34; &#34;http://lemmy&#34;;&#xA;        &#34;~^(?!(GET|HEAD)).:&#34; &#34;http://lemmy&#34;;&#xA;    }&#xA;&#xA;    upstream lemmy {&#xA;        server &#34;lemmy:8536&#34;;&#xA;    }&#xA;&#xA;    upstream lemmy-ui {&#xA;        server &#34;lemmy-ui:1234&#34;;&#xA;    }&#xA;&#xA;    server {&#xA;        listen 1236;&#xA;        listen 8536;&#xA;&#xA;        servername localhost;&#xA;        servertokens off;&#xA;&#xA;        gzip on;&#xA;        gziptypes text/css application/javascript image/svg+xml;&#xA;        gzipvary on;&#xA;&#xA;        clientmaxbodysize 20M;&#xA;&#xA;        addheader X-Frame-Options SAMEORIGIN;&#xA;        addheader X-Content-Type-Options nosniff;&#xA;        addheader X-XSS-Protection &#34;1; mode=block&#34;;&#xA;&#xA;        location / {&#xA;            proxypass $proxpass;&#xA;            rewrite ^(.+)/+$ $1 permanent;&#xA;            proxysetheader X-Real-IP $remoteaddr;&#xA;            proxysetheader Host $host;&#xA;            proxysetheader X-Forwarded-For $proxyaddxforwardedfor;&#xA;        }&#xA;&#xA;        location ~ ^/(api|pictrs|feeds|nodeinfo|.well-known) {&#xA;            proxypass &#34;http://lemmy&#34;;&#xA;            proxyhttpversion 1.1;&#xA;            proxysetheader Upgrade $httpupgrade;&#xA;            proxysetheader Connection &#34;upgrade&#34;;&#xA;            proxysetheader X-Real-IP $remoteaddr;&#xA;            proxysetheader Host $host;&#xA;            proxysetheader X-Forwarded-For $proxyaddxforwardedfor;&#xA;        }&#xA;    }&#xA;}&#xA;&#xA;lemmy backend config&#xA;&#xA;creating the lemmy config file&#xA;&#xA;vim /opt/lemmy/config/config.hjson&#xA;&#xA;content&#xA;&#xA;{&#xA;  database: {&#xA;    host: postgres&#xA;    password: &#34;yourpostgresqlpasswordhere&#34;&#xA;  }&#xA;  hostname: &#34;bolha.forum&#34;&#xA;  pictrs: {&#xA;    url: &#34;http://pictrs:8080/&#34;&#xA;    apikey: &#34;yourpostgresqlpasswordhere&#34;&#xA;  }&#xA;  email: {&#xA;    smtpserver: &#34;postfix:25&#34;&#xA;    smtpfromaddress: &#34;noreply@bolha.forum&#34;&#xA;    tlstype: &#34;none&#34;&#xA;  }&#xA;}&#xA;&#xA;docker config&#xA;&#xA;creating the docker-compose.yaml&#xA;&#xA;vim /opt/lemmy/docker/docker-compose.yml&#xA;&#xA;content&#xA;&#xA;version: &#34;3.7&#34;&#xA;&#xA;services:&#xA;&#xA;  proxy:&#xA;    image: nginx:1-alpine&#xA;    containername: lemmyproxy&#xA;    ports:&#xA;      &#34;8000:8536&#34;&#xA;    volumes:&#xA;      /opt/lemmy/config/nginx/nginx.conf:/etc/nginx/nginx.conf:ro,Z&#xA;    restart: always&#xA;    dependson:&#xA;      pictrs&#xA;      lemmy-ui&#xA;&#xA;  lemmy:&#xA;    image: dessalines/lemmy:0.18.1&#xA;    containername: lemmybackend&#xA;    hostname: lemmy&#xA;    restart: always&#xA;    environment:&#xA;      RUSTLOG=&#34;warn&#34;&#xA;    volumes:&#xA;      lemmyconfig:/config&#xA;    dependson:&#xA;      postgres&#xA;      pictrs&#xA;&#xA;  lemmy-ui:&#xA;    image: dessalines/lemmy-ui:0.18.1&#xA;    containername: lemmyfrontend&#xA;    environment:&#xA;      LEMMYUILEMMYINTERNALHOST=lemmy:8536&#xA;      LEMMYUILEMMYEXTERNALHOST=bolha.forum&#xA;      LEMMYUIHTTPS=true&#xA;    volumes:&#xA;      extrathemes:/app/extrathemes&#xA;    dependson:&#xA;      lemmy&#xA;    restart: always&#xA;&#xA;  pictrs:&#xA;    image: asonix/pictrs:0.4.0-rc.7&#xA;    containername: lemmyimagesbackend&#xA;    hostname: pictrs&#xA;    environment:&#xA;      PICTRSAPIKEY=yourpostgresqlpasswordhere&#xA;      RUSTLOG=debug&#xA;      RUSTBACKTRACE=full&#xA;      PICTRSMEDIAVIDEOCODEC=vp9&#xA;      PICTRSMEDIAGIF_MAXWIDTH=256&#xA;      PICTRSMEDIAGIF_MAXHEIGHT=256&#xA;      PICTRSMEDIAGIF_MAXAREA=65536&#xA;      PICTRSMEDIAGIF_MAXFRAMECOUNT=400&#xA;    user: 991:991&#xA;    volumes:&#xA;      pictrs:/mnt:Z&#xA;    restart: always&#xA;    deploy:&#xA;      resources:&#xA;        limits:&#xA;          memory: 690m&#xA;&#xA;  postgres:&#xA;    image: postgres:15-alpine&#xA;    containername: lemmydatabase&#xA;    hostname: postgres&#xA;    environment:&#xA;      POSTGRESUSER=lemmy&#xA;      POSTGRESPASSWORD=yourpostgresqlpasswordhere&#xA;      POSTGRESDB=lemmy&#xA;    volumes:&#xA;      postgresql:/var/lib/postgresql/data:Z&#xA;      /opt/lemmy/config/postgresql/postgresql.conf:/etc/postgresql.conf&#xA;    restart: always&#xA;&#xA;  postfix:&#xA;    image: mwader/postfix-relay&#xA;    containername: lemmysmtprelay&#xA;    environment:&#xA;      POSTFIXmyhostname=bolha.forum&#xA;      POSTFIXsmtpsaslauthenable= yes&#xA;      POSTFIXsmtpsaslpasswordmaps=static:user@domain.tld:userpasswordhere&#xA;      POSTFIXsmtpsaslsecurityoptions=noanonymous&#xA;      POSTFIXrelayhost=smtp.domain.tld:587&#xA;    restart: &#34;always&#34;&#xA;&#xA;volumes:&#xA;  lemmyconfig:&#xA;    driveropts:&#xA;      type: none&#xA;      device: /opt/lemmy/config/lemmy&#xA;      o: bind&#xA;  extrathemes:&#xA;    driveropts:&#xA;      type: none&#xA;      device: /opt/lemmy/data/themes&#xA;      o: bind&#xA;  pictrs:&#xA;    driveropts:&#xA;      type: none&#xA;      device: /opt/lemmy/data/pictrs&#xA;      o: bind&#xA;  postgresql:&#xA;    driveropts:&#xA;      type: none&#xA;      device: /opt/lemmy/data/postgresql&#xA;      o: bind&#xA;&#xA;spinning up the lemmy instance&#xA;&#xA;$ cd /opt/lemmy/docker&#xA;$ docker-compose up -d&#xA;&#xA;checking&#xA;&#xA;$ docker-compose ps&#xA;&#xA;NAME                   IMAGE                        COMMAND                  SERVICE             CREATED             STATUS              PORTS&#xA;lemmybackend          dessalines/lemmy:0.18.1      &#34;/app/lemmy&#34;             lemmy               34 minutes ago      Up 34 minutes&#xA;lemmydatabase         postgres:15-alpine           &#34;docker-entrypoint.s…&#34;   postgres            34 minutes ago      Up 34 minutes       5432/tcp&#xA;lemmyfrontend         dessalines/lemmy-ui:0.18.1   &#34;docker-entrypoint.s…&#34;   lemmy-ui            34 minutes ago      Up 34 minutes       1234/tcp&#xA;lemmyimagesbackend   asonix/pictrs:0.4.0-rc.7     &#34;/sbin/tini -- /usr/…&#34;   pictrs              34 minutes ago      Up 34 minutes       6669/tcp, 8080/tcp&#xA;lemmyproxy            nginx:1-alpine               &#34;/docker-entrypoint.…&#34;   proxy               34 minutes ago      Up 34 minutes       80/tcp, 0.0.0.0:8000-  8536/tcp, :::8000-  8536/tcp&#xA;lemmysmtprelay       mwader/postfix-relay         &#34;/root/run&#34;              postfix             34 minutes ago      Up 34 minutes       25/tcp&#xA;&#xA;You can see that our lemmyproxy (nginx) is running on the port 8000.&#xA;&#xA;Now let&#39;s configure the external reverse proxy.&#xA;&#xA;external reverse-proxy config&#xA;&#xA;certbot + letsencrypt&#xA;&#xA;we&#39;re using cloudflare plugin with certbot, you need to have the configuration ready, like this example&#xA;&#xA;cat /etc/letsencrypt/cloudflare/bolha-forum.conf&#xA;dnscloudflareemail = dns@bolha.forum&#xA;dnscloudflareapikey = yourtokenhere&#xA;&#xA;then you can generate the certificate&#xA;&#xA;certbot certonly --dns-cloudflare --dns-cloudflare-credential /etc/letsencrypt/cloudflare/bolha-forum.conf -d &#34;*.bolha.forum,bolha.forum&#34;&#xA;&#xA;now we can configure our nginx!&#xA;&#xA;nginx config&#xA;&#xA;external reverse proxy&#xA;&#xA;server {&#xA;    listen yourlisteniphere:80;&#xA;    servername bolha.forum;&#xA;    location / {&#xA;        return 301 https://bolha.forum$requesturi;&#xA;    }&#xA;}&#xA;&#xA;server {&#xA;    listen yourlisteniphere:443 ssl http2;&#xA;    servername bolha.forum;&#xA;&#xA;    sslcertificate /etc/letsencrypt/live/bolha.forum/fullchain.pem;&#xA;    sslcertificatekey /etc/letsencrypt/live/bolha.forum/privkey.pem;&#xA;&#xA;    sslprotocols TLSv1.2 TLSv1.3;&#xA;&#xA;    ssldhparam /etc/letsencrypt/dh-param.pem;&#xA;&#xA;    sslciphers &#39;ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256&#39;;&#xA;&#xA;    # Specifies a curve for ECDHE ciphers.&#xA;    sslecdhcurve prime256v1;&#xA;&#xA;    # Server should determine the ciphers, not the client&#xA;    sslpreferserverciphers on;&#xA;&#xA;    sslsessioncache shared:SSL:10m;&#xA;    sslsessiontickets off;&#xA;&#xA;    # Enable compression for JS/CSS/HTML bundle, for improved client load times.&#xA;    # It might be nice to compress JSON, but leaving that out to protect against potential&#xA;    # compression+encryption information leak attacks like BREACH.&#xA;    gzip on;&#xA;    gziptypes text/css application/javascript image/svg+xml;&#xA;    gzipvary on;&#xA;&#xA;    # Only connect to this site via HTTPS for the two years&#xA;    addheader Strict-Transport-Security &#34;max-age=63072000&#34;;&#xA;&#xA;    # Various content security headers&#xA;    addheader Referrer-Policy &#34;same-origin&#34;;&#xA;    addheader X-Content-Type-Options &#34;nosniff&#34;;&#xA;    addheader X-Frame-Options &#34;DENY&#34;;&#xA;    addheader X-XSS-Protection &#34;1; mode=block&#34;;&#xA;&#xA;    # Upload limit for pictrs&#xA;    clientmaxbodysize 25M;&#xA;&#xA;    location / {&#xA;      proxypass http://yourdockerhostiphere:yourporthere;&#xA;      proxyhttpversion 1.1;&#xA;      proxysetheader Upgrade $httpupgrade;&#xA;      proxysetheader Connection &#34;upgrade&#34;;&#xA;      proxysetheader X-Real-IP $remoteaddr;&#xA;      proxysetheader Host $host;&#xA;      proxysetheader X-Forwarded-For $proxyaddxforwarded_for;&#xA;    }&#xA;}&#xA;&#xA;check the config&#xA;&#xA;nginx -t&#xA;&#xA;expected output&#xA;&#xA;nginx: the configuration file /etc/nginx/nginx.conf syntax is ok&#xA;nginx: configuration file /etc/nginx/nginx.conf test is successful&#xA;&#xA;and reload the configuration&#xA;&#xA;nginx -s reload&#xA;&#xA;that&#39;s it!&#xA;&#xA;Go to your lemmy!&#xA;&#xA;Now you can access your lemmy instance&#xA;&#xA;https://bolha.forum&#xA;&#xA;Enjoy!]]&gt;</description>
      <content:encoded><![CDATA[<p>Last update: 2023-07-07</p>

<h2 id="why" id="why">Why?</h2>

<p>Because we want to use a federated forum and link aggregator :)</p>

<h2 id="what-do-i-need-to-install" id="what-do-i-need-to-install">What do I need to install?</h2>

<p>You need a Linux Server with Docker, and Docker-compose installed.
creating directories</p>

<h2 id="what-s-my-setup" id="what-s-my-setup">What&#39;s my setup?</h2>
<ul><li>ProxMox
<ul><li>KVM</li>
<li>Ubuntu 20.04
<ul><li>Docker</li>
<li>Docker-compose</li></ul></li></ul></li>
<li>External Nginx
<ul><li>Reverse Proxy Configuration</li>
<li>LetsEncrypt Certificate</li></ul></li></ul>

<h2 id="where-i-can-find-out-more-about-the-project" id="where-i-can-find-out-more-about-the-project">Where I can find out more about the project?</h2>
<ul><li><a href="https://join-lemmy.org" rel="nofollow">https://join-lemmy.org</a></li>
<li><a href="https://join-lemmy.org/docs" rel="nofollow">https://join-lemmy.org/docs</a></li>
<li><a href="https://join-lemmy.org/docs/administration/install_docker.html" rel="nofollow">https://join-lemmy.org/docs/administration/install_docker.html</a></li></ul>

<h2 id="how-i-can-install-it" id="how-i-can-install-it">How I can install it?</h2>

<p>creating directories</p>

<pre><code>mkdir -p /opt/lemmy
mkdir -p /opt/lemmy/{docker,data,config}
mkdir -p /opt/lemmy/data/{postgresql,pictrs,themes}
mkdir -p /opt/lemmy/config/{lemmy,postgresql,nginx}
</code></pre>

<p>defining permissions</p>

<pre><code>chown -R 991:991 /opt/lemmy/data/pictrs
</code></pre>

<h3 id="nginx-config" id="nginx-config">nginx config</h3>

<p>creating the nginx.conf file</p>

<pre><code>vim /opt/lemmy/config/nginx/nginx.conf
</code></pre>

<p>content</p>

<pre><code>worker_processes auto;

events {
    worker_connections 1024;
}

http {

    map &#34;$request_method:$http_accept&#34; $proxpass {
        default &#34;http://lemmy-ui&#34;;
        &#34;~^(?:GET|HEAD):.*?application\/(?:activity|ld)\+json&#34; &#34;http://lemmy&#34;;
        &#34;~^(?!(GET|HEAD)).*:&#34; &#34;http://lemmy&#34;;
    }

    upstream lemmy {
        server &#34;lemmy:8536&#34;;
    }

    upstream lemmy-ui {
        server &#34;lemmy-ui:1234&#34;;
    }

    server {
        listen 1236;
        listen 8536;

        server_name localhost;
        server_tokens off;

        gzip on;
        gzip_types text/css application/javascript image/svg+xml;
        gzip_vary on;

        client_max_body_size 20M;

        add_header X-Frame-Options SAMEORIGIN;
        add_header X-Content-Type-Options nosniff;
        add_header X-XSS-Protection &#34;1; mode=block&#34;;

        location / {
            proxy_pass $proxpass;
            rewrite ^(.+)/+$ $1 permanent;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header Host $host;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        }

        location ~ ^/(api|pictrs|feeds|nodeinfo|.well-known) {
            proxy_pass &#34;http://lemmy&#34;;
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection &#34;upgrade&#34;;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header Host $host;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        }
    }
}
</code></pre>

<h3 id="lemmy-backend-config" id="lemmy-backend-config">lemmy backend config</h3>

<p>creating the lemmy config file</p>

<pre><code>vim /opt/lemmy/config/config.hjson
</code></pre>

<p>content</p>

<pre><code>{
  database: {
    host: postgres
    password: &#34;your_postgresql_password_here&#34;
  }
  hostname: &#34;bolha.forum&#34;
  pictrs: {
    url: &#34;http://pictrs:8080/&#34;
    api_key: &#34;your_postgresql_password_here&#34;
  }
  email: {
    smtp_server: &#34;postfix:25&#34;
    smtp_from_address: &#34;noreply@bolha.forum&#34;
    tls_type: &#34;none&#34;
  }
}
</code></pre>

<h3 id="docker-config" id="docker-config">docker config</h3>

<p>creating the docker-compose.yaml</p>

<pre><code>vim /opt/lemmy/docker/docker-compose.yml
</code></pre>

<p>content</p>

<pre><code>version: &#34;3.7&#34;

services:

  proxy:
    image: nginx:1-alpine
    container_name: lemmy_proxy
    ports:
      - &#34;8000:8536&#34;
    volumes:
      - /opt/lemmy/config/nginx/nginx.conf:/etc/nginx/nginx.conf:ro,Z
    restart: always
    depends_on:
      - pictrs
      - lemmy-ui

  lemmy:
    image: dessalines/lemmy:0.18.1
    container_name: lemmy_backend
    hostname: lemmy
    restart: always
    environment:
      - RUST_LOG=&#34;warn&#34;
    volumes:
      - lemmy_config:/config
    depends_on:
      - postgres
      - pictrs

  lemmy-ui:
    image: dessalines/lemmy-ui:0.18.1
    container_name: lemmy_frontend
    environment:
      - LEMMY_UI_LEMMY_INTERNAL_HOST=lemmy:8536
      - LEMMY_UI_LEMMY_EXTERNAL_HOST=bolha.forum
      - LEMMY_UI_HTTPS=true
    volumes:
      - extra_themes:/app/extra_themes
    depends_on:
      - lemmy
    restart: always

  pictrs:
    image: asonix/pictrs:0.4.0-rc.7
    container_name: lemmy_images_backend
    hostname: pictrs
    environment:
      - PICTRS__API_KEY=your_postgresql_password_here
      - RUST_LOG=debug
      - RUST_BACKTRACE=full
      - PICTRS__MEDIA__VIDEO_CODEC=vp9
      - PICTRS__MEDIA__GIF__MAX_WIDTH=256
      - PICTRS__MEDIA__GIF__MAX_HEIGHT=256
      - PICTRS__MEDIA__GIF__MAX_AREA=65536
      - PICTRS__MEDIA__GIF__MAX_FRAME_COUNT=400
    user: 991:991
    volumes:
      - pictrs:/mnt:Z
    restart: always
    deploy:
      resources:
        limits:
          memory: 690m

  postgres:
    image: postgres:15-alpine
    container_name: lemmy_database
    hostname: postgres
    environment:
      - POSTGRES_USER=lemmy
      - POSTGRES_PASSWORD=your_postgresql_password_here
      - POSTGRES_DB=lemmy
    volumes:
      - postgresql:/var/lib/postgresql/data:Z
      - /opt/lemmy/config/postgresql/postgresql.conf:/etc/postgresql.conf
    restart: always

  postfix:
    image: mwader/postfix-relay
    container_name: lemmy_smtp_relay
    environment:
      - POSTFIX_myhostname=bolha.forum
      - POSTFIX_smtp_sasl_auth_enable= yes
      - POSTFIX_smtp_sasl_password_maps=static:user@domain.tld:user_password_here
      - POSTFIX_smtp_sasl_security_options=noanonymous
      - POSTFIX_relayhost=smtp.domain.tld:587
    restart: &#34;always&#34;

volumes:
  lemmy_config:
    driver_opts:
      type: none
      device: /opt/lemmy/config/lemmy
      o: bind
  extra_themes:
    driver_opts:
      type: none
      device: /opt/lemmy/data/themes
      o: bind
  pictrs:
    driver_opts:
      type: none
      device: /opt/lemmy/data/pictrs
      o: bind
  postgresql:
    driver_opts:
      type: none
      device: /opt/lemmy/data/postgresql
      o: bind
</code></pre>

<h3 id="spinning-up-the-lemmy-instance" id="spinning-up-the-lemmy-instance">spinning up the lemmy instance</h3>

<pre><code>$ cd /opt/lemmy/docker
$ docker-compose up -d
</code></pre>

<h3 id="checking" id="checking">checking</h3>

<pre><code>$ docker-compose ps

NAME                   IMAGE                        COMMAND                  SERVICE             CREATED             STATUS              PORTS
lemmy_backend          dessalines/lemmy:0.18.1      &#34;/app/lemmy&#34;             lemmy               34 minutes ago      Up 34 minutes
lemmy_database         postgres:15-alpine           &#34;docker-entrypoint.s…&#34;   postgres            34 minutes ago      Up 34 minutes       5432/tcp
lemmy_frontend         dessalines/lemmy-ui:0.18.1   &#34;docker-entrypoint.s…&#34;   lemmy-ui            34 minutes ago      Up 34 minutes       1234/tcp
lemmy_images_backend   asonix/pictrs:0.4.0-rc.7     &#34;/sbin/tini -- /usr/…&#34;   pictrs              34 minutes ago      Up 34 minutes       6669/tcp, 8080/tcp
lemmy_proxy            nginx:1-alpine               &#34;/docker-entrypoint.…&#34;   proxy               34 minutes ago      Up 34 minutes       80/tcp, 0.0.0.0:8000-&gt;8536/tcp, :::8000-&gt;8536/tcp
lemmy_smtp_relay       mwader/postfix-relay         &#34;/root/run&#34;              postfix             34 minutes ago      Up 34 minutes       25/tcp
</code></pre>

<p>You can see that our lemmy_proxy (nginx) is running on the port 8000.</p>

<p>Now let&#39;s configure the external reverse proxy.</p>

<h2 id="external-reverse-proxy-config" id="external-reverse-proxy-config">external reverse-proxy config</h2>

<h3 id="certbot-letsencrypt" id="certbot-letsencrypt">certbot + letsencrypt</h3>

<p>we&#39;re using cloudflare plugin with certbot, you need to have the configuration ready, like this example</p>

<pre><code># cat /etc/letsencrypt/cloudflare/bolha-forum.conf
dns_cloudflare_email = dns@bolha.forum
dns_cloudflare_api_key = your_token_here
</code></pre>

<p>then you can generate the certificate</p>

<pre><code># certbot certonly --dns-cloudflare --dns-cloudflare-credential /etc/letsencrypt/cloudflare/bolha-forum.conf -d &#34;*.bolha.forum,bolha.forum&#34;
</code></pre>

<p>now we can configure our nginx!</p>

<h3 id="nginx-config-1" id="nginx-config-1">nginx config</h3>

<p>external reverse proxy</p>

<pre><code>server {
    listen your_listen_ip_here:80;
    server_name bolha.forum;
    location / {
        return 301 https://bolha.forum$request_uri;
    }
}

server {
    listen your_listen_ip_here:443 ssl http2;
    server_name bolha.forum;

    ssl_certificate /etc/letsencrypt/live/bolha.forum/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/bolha.forum/privkey.pem;

    ssl_protocols TLSv1.2 TLSv1.3;

    ssl_dhparam /etc/letsencrypt/dh-param.pem;

    ssl_ciphers &#39;ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256&#39;;

    # Specifies a curve for ECDHE ciphers.
    ssl_ecdh_curve prime256v1;

    # Server should determine the ciphers, not the client
    ssl_prefer_server_ciphers on;

    ssl_session_cache shared:SSL:10m;
    ssl_session_tickets off;

    # Enable compression for JS/CSS/HTML bundle, for improved client load times.
    # It might be nice to compress JSON, but leaving that out to protect against potential
    # compression+encryption information leak attacks like BREACH.
    gzip on;
    gzip_types text/css application/javascript image/svg+xml;
    gzip_vary on;

    # Only connect to this site via HTTPS for the two years
    add_header Strict-Transport-Security &#34;max-age=63072000&#34;;

    # Various content security headers
    add_header Referrer-Policy &#34;same-origin&#34;;
    add_header X-Content-Type-Options &#34;nosniff&#34;;
    add_header X-Frame-Options &#34;DENY&#34;;
    add_header X-XSS-Protection &#34;1; mode=block&#34;;

    # Upload limit for pictrs
    client_max_body_size 25M;


    location / {
      proxy_pass http://your_docker_host_ip_here:your_port_here;
      proxy_http_version 1.1;
      proxy_set_header Upgrade $http_upgrade;
      proxy_set_header Connection &#34;upgrade&#34;;
      proxy_set_header X-Real-IP $remote_addr;
      proxy_set_header Host $host;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}
</code></pre>

<p>check the config</p>

<pre><code>nginx -t
</code></pre>

<p>expected output</p>

<pre><code>nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
</code></pre>

<p>and reload the configuration</p>

<pre><code># nginx -s reload
</code></pre>

<p>that&#39;s it!</p>

<h2 id="go-to-your-lemmy" id="go-to-your-lemmy">Go to your lemmy!</h2>

<p>Now you can access your lemmy instance</p>
<ul><li><a href="https://bolha.forum" rel="nofollow">https://bolha.forum</a></li></ul>

<p>Enjoy!</p>
]]></content:encoded>
      <author>howtos</author>
      <guid>https://blog.gcn.sh/read/a/qwv109q9rr</guid>
      <pubDate>Fri, 07 Jul 2023 15:05:07 +0000</pubDate>
    </item>
    <item>
      <title>Integrating Mastodon and Libretranslate</title>
      <link>https://blog.gcn.sh/howtos/integrating-mastodon-and-libretranslate</link>
      <description>&lt;![CDATA[Why?&#xA;&#xA;We want to offer translations inside Mastodon using libretranslate as our backend.&#xA;&#xA;What do I need to install?&#xA;&#xA;Your need a working mastodon, we recommend this howto&#xA;&#xA;https://blog.gcn.sh/howtos/installing-mastodon-4-1-2-using-docker-on-ubuntu&#xA;&#xA;Your need a working libretranslate, we recommend this howto&#xA;&#xA;https://blog.gcn.sh/howtos/installing-libretranslate-using-docker-and-ubuntu&#xA;&#xA;How to integrate them?&#xA;&#xA;You need to add these two variables on the application.env file if you are following our mastodon howto.&#xA;&#xA;LIBRETRANSLATEENDPOINT=https://libretranslate.bolha.tools&#xA;LIBRETRANSLATEAPI_KEY=ecae7db0-bolha-us-is-cool-c84c14d2117a&#xA;&#xA;Then restart it&#xA;&#xA;cd /opt/mastodon/docker&#xA;docker-compose restart&#xA;&#xA;After that you can check the logs&#xA;&#xA;docker-compose logs -f|grep TranslationsController&#xA;&#xA;Expected output with status code 200&#xA;&#xA;website            | [01fa1ece-5ab3-411d-bd6b-4b5131096735] method=POST path=/api/v1/statuses/110658724777490930/translate format=html controller=Api::V1::Statuses::TranslationsController action=create status=200 duration=2988.25 view=0.77 db=2.32&#xA;&#xA;Sometimes you can get a status code 503, yes, it will happen, it&#39;s not perfect but works well most of the time.&#xA;&#xA;website            | [752a45c9-a94a-408a-8262-7b71cc1528e9] method=POST path=/api/v1/statuses/110658727361133356/translate format=html controller=Api::V1::Statuses::TranslationsController action=create status=503 duration=10117.47 view=0.49 db=2.19&#xA;&#xA;Enjoy it!&#xA;&#xA;:)]]&gt;</description>
      <content:encoded><![CDATA[<h2 id="why" id="why">Why?</h2>

<p>We want to offer translations inside Mastodon using libretranslate as our backend.</p>

<h2 id="what-do-i-need-to-install" id="what-do-i-need-to-install">What do I need to install?</h2>

<p>Your need a working mastodon, we recommend this howto</p>
<ul><li><a href="https://blog.gcn.sh/howtos/installing-mastodon-4-1-2-using-docker-on-ubuntu" rel="nofollow">https://blog.gcn.sh/howtos/installing-mastodon-4-1-2-using-docker-on-ubuntu</a></li></ul>

<p>Your need a working libretranslate, we recommend this howto</p>
<ul><li><a href="https://blog.gcn.sh/howtos/installing-libretranslate-using-docker-and-ubuntu" rel="nofollow">https://blog.gcn.sh/howtos/installing-libretranslate-using-docker-and-ubuntu</a></li></ul>

<h2 id="how-to-integrate-them" id="how-to-integrate-them">How to integrate them?</h2>

<p>You need to add these two variables on the application.env file if you are following our mastodon howto.</p>

<pre><code>LIBRE_TRANSLATE_ENDPOINT=https://libretranslate.bolha.tools
LIBRE_TRANSLATE_API_KEY=ecae7db0-bolha-us-is-cool-c84c14d2117a
</code></pre>

<p>Then restart it</p>

<pre><code>cd /opt/mastodon/docker
docker-compose restart
</code></pre>

<p>After that you can check the logs</p>

<pre><code>docker-compose logs -f|grep TranslationsController
</code></pre>

<p>Expected output with status code 200</p>

<pre><code>website            | [01fa1ece-5ab3-411d-bd6b-4b5131096735] method=POST path=/api/v1/statuses/110658724777490930/translate format=html controller=Api::V1::Statuses::TranslationsController action=create status=200 duration=2988.25 view=0.77 db=2.32
</code></pre>

<p>Sometimes you can get a status code 503, yes, it will happen, it&#39;s not perfect but works well most of the time.</p>

<pre><code>website            | [752a45c9-a94a-408a-8262-7b71cc1528e9] method=POST path=/api/v1/statuses/110658727361133356/translate format=html controller=Api::V1::Statuses::TranslationsController action=create status=503 duration=10117.47 view=0.49 db=2.19
</code></pre>

<p>Enjoy it!</p>

<p>:)</p>
]]></content:encoded>
      <author>howtos</author>
      <guid>https://blog.gcn.sh/read/a/rtea9qr1p3</guid>
      <pubDate>Wed, 05 Jul 2023 00:59:17 +0000</pubDate>
    </item>
    <item>
      <title>Installing libretranslate using Docker</title>
      <link>https://blog.gcn.sh/howtos/installing-libretranslate-using-docker-and-ubuntu</link>
      <description>&lt;![CDATA[Why?&#xA;&#xA;The main use of this Libretranslate is to translate mastodon toots.&#xA;&#xA;What do I need to install?&#xA;&#xA;You need a Linux Server with Docker, and Docker-compose installed.&#xA;&#xA;What&#39;s my setup?&#xA;&#xA;ProxMox&#xA;  KVM&#xA;    Ubuntu 20.04&#xA;      Docker&#xA;      Docker-compose&#xA;External Nginx&#xA;  Reverse Proxy Configuration&#xA;  LetsEncrypt Certificate&#xA;&#xA;Where I can find more about the project?&#xA;&#xA;https://libretranslate.com&#xA;https://github.com/LibreTranslate/LibreTranslate&#xA;&#xA;How I can install it?&#xA;&#xA;first, let&#39;s create the directories&#xA;&#xA;mkdir -p /opt/libretranslate/docker&#xA;mkdir -p /opt/libretransalte/data/{key,local}&#xA;&#xA;now let&#39;s configure the permissions&#xA;&#xA;chown 1032:1032 /opt/libretransalte/data&#xA;chown 1032:1032 /opt/libretransalte/data/key&#xA;chown 1032:1032 /opt/libretransalte/data/local&#xA;&#xA;then, let&#39;s create the docker-compose file&#xA;&#xA;cd /opt/libretranslate/docker&#xA;vim docker-compose.yaml&#xA;&#xA;here follows the content, change the parameters for you setup&#xA;&#xA;version: &#34;3&#34;&#xA;&#xA;services:&#xA;  libretranslate:&#xA;    containername: libretranslate&#xA;    image: libretranslate/libretranslate:v1.3.11&#xA;    restart: unless-stopped&#xA;    dns:&#xA;      1.1.1.1&#xA;      8.8.8.8&#xA;    ports:&#xA;      &#34;5000:5000&#34;&#xA;    healthcheck:&#xA;      test: [&#39;CMD-SHELL&#39;, &#39;./venv/bin/python scripts/healthcheck.py&#39;]&#xA;    envfile:&#xA;      libretranslate.env&#xA;    volumes:&#xA;     libretranslateapikeys:/app/db&#xA;     libretranslatelocal:/home/libretranslate/.local&#xA;&#xA;volumes:&#xA;  libretranslateapikeys:&#xA;    driveropts:&#xA;      type: none&#xA;      device: /opt/libretranslate/data/keys&#xA;      o: bind&#xA;  libretranslatelocal:&#xA;    driveropts:&#xA;      type: none&#xA;      device: /opt/libretranslate/data/local&#xA;      o: bind&#xA;&#xA;then, let&#39;s create the libetranslate env file&#xA;&#xA;vim libretranslate.env&#xA;&#xA;here follows the content, change the parameters for you setup&#xA;&#xA;LTDEBUG=true&#xA;LTUPDATEMODELS=true&#xA;LTSSL=true&#xA;LTSUGGESTIONS=false&#xA;LTMETRICS=true&#xA;&#xA;LTAPIKEYS=true&#xA;&#xA;LTTHREADS=12&#xA;LTFRONTENDTIMEOUT=2000&#xA;&#xA;LTREQLIMIT=400&#xA;LTCHARLIMIT=1200&#xA;&#xA;LTAPIKEYSDBPATH=/app/db/apikeys.db&#xA;&#xA;all right, let&#39;s spin up the libretranslate&#xA;&#xA;docker-compose up -d&#xA;&#xA;installing the model files&#xA;&#xA;you should enter the container&#xA;&#xA;docker exec -it libretranslate bash&#xA;&#xA;and run the command to install all languages&#xA;&#xA;for i in /app/venv/bin/argospm list;do /app/venv/bin/argospm install $i;done&#xA;&#xA;it will took some time to install, go drink a coffee, then check the directory in your host&#xA;&#xA;$ exit&#xA;$ ls -1 /opt/libretranslate/data/local/share/argos-translate/packages/&#xA;&#xA;aren&#xA;deen&#xA;enar&#xA;ende&#xA;enes&#xA;enfi&#xA;enfr&#xA;enga&#xA;enhi&#xA;enhu&#xA;enid&#xA;enit&#xA;enja&#xA;enko&#xA;ennl&#xA;enpl&#xA;enpt&#xA;ensv&#xA;enuk&#xA;esen&#xA;fien&#xA;fren&#xA;gaen&#xA;hien&#xA;huen&#xA;iden&#xA;iten&#xA;jaen&#xA;koen&#xA;nlen&#xA;plen&#xA;pten&#xA;ruen&#xA;sven&#xA;translate-azen-15&#xA;translate-caen-17&#xA;translate-csen-15&#xA;translate-daen-13&#xA;translate-elen-15&#xA;translate-enaz-15&#xA;translate-enca-17&#xA;translate-encs-15&#xA;translate-enda-13&#xA;translate-enel-15&#xA;translate-eneo-15&#xA;translate-enfa-15&#xA;translate-enhe-15&#xA;translate-enru-17&#xA;translate-ensk-15&#xA;translate-enth-10&#xA;translate-entr-15&#xA;translate-enzh-17&#xA;translate-eoen-15&#xA;translate-faen-15&#xA;translate-heen-15&#xA;translate-sken-15&#xA;translate-then-10&#xA;translate-tren-15&#xA;translate-zhen-17&#xA;uken&#xA;&#xA;Awesome it&#39;s all there.&#xA;&#xA;creating the api key&#xA;&#xA;Since we&#39;re using &#34;LTAPIKEYS=true&#34; we need to create an API KEY to be able to use libretranslate via API. Let&#39;s go to the container again&#xA;&#xA;docker exec -it libretranslate bash&#xA;&#xA;let&#39;s create a key with permission to run 120 requests per minute.&#xA;&#xA;/app/venv/bin/ltmanage keys add 120&#xA;&#xA;example of the expected output&#xA;&#xA;libretranslate@ba7f705d97b9:/app$ /app/venv/bin/ltmanage keys&#xA;ecae7db0-bolha-us-is-cool-c84c14d2117a: 1200&#xA;&#xA;nice, everything is ready to be used, now let&#39;s configure your nginx!&#xA;&#xA;testing the api&#xA;&#xA;curl -XPOST -H &#34;Content-type: application/json&#34; -d &#39;{&#xA;&#34;q&#34;: &#34;Bolha.io is the most cool project in the fediverso&#34;,&#xA;&#34;source&#34;: &#34;en&#34;,&#xA;&#34;target&#34;: &#34;pt&#34;&#xA;}&#39; &#39;http://localhost:5000/translate&#39;&#xA;&#xA;expected output&#xA;&#xA;{&#34;translatedText&#34;:&#34;Bolha.io é o projeto mais legal no fediverso&#34;}&#xA;&#xA;external nginx&#xA;&#xA;In our case, libretranslate is behind an External NGINX Reverse Proxy.&#xA;&#xA;Here follows the config snippet used&#xA;&#xA;upstream libretranslate {&#xA;    server yourdockerhostip:yourlibretranslateport failtimeout=0;&#xA;}&#xA;&#xA;server {&#xA;  listen 144.217.95.91:80;&#xA;  servername libretranslate.domain.tld;&#xA;  return 301 https://libretranslate.domain.tld$requesturi;&#xA;}&#xA;&#xA;server {&#xA;&#xA;  listen 144.217.95.91:443 ssl http2;&#xA;  servername libretranslate;&#xA;&#xA;  accesslog /var/log/nginx/libretranslate-domain-tld.log;&#xA;  errorlog /var/log/nginx/libretranslate-domain-tld.log;&#xA;&#xA;  sslcertificate /etc/letsencrypt/live/domain.tld/fullchain.pem;&#xA;  sslcertificatekey /etc/letsencrypt/live/domain.tld/privkey.pem;&#xA;&#xA;  sslprotocols TLSv1.2 TLSv1.3;&#xA;  sslpreferserverciphers on;&#xA;  ssldhparam /etc/letsencrypt/dh-param.pem;&#xA;&#xA;  sslciphers &#39;ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256&#39;;&#xA;&#xA;  sslsessioncache shared:SSL:10m;&#xA;  sslsessiontickets off;&#xA;&#xA;  location / {&#xA;    proxypass http://libretranslate;&#xA;  }&#xA;&#xA;}&#xA;&#xA;Now you can access your libretranstale via web&#xA;&#xA;https://libretranslate.domain.tld&#xA;&#xA;That&#39;s it :)&#xA;&#xA;[s]&#xA;&#xA;]]&gt;</description>
      <content:encoded><![CDATA[<h2 id="why" id="why">Why?</h2>

<p>The main use of this Libretranslate is to translate mastodon toots.</p>

<h2 id="what-do-i-need-to-install" id="what-do-i-need-to-install">What do I need to install?</h2>

<p>You need a Linux Server with Docker, and Docker-compose installed.</p>

<h2 id="what-s-my-setup" id="what-s-my-setup">What&#39;s my setup?</h2>
<ul><li>ProxMox
<ul><li>KVM</li>
<li>Ubuntu 20.04
<ul><li>Docker</li>
<li>Docker-compose</li></ul></li></ul></li>
<li>External Nginx
<ul><li>Reverse Proxy Configuration</li>
<li>LetsEncrypt Certificate</li></ul></li></ul>

<h2 id="where-i-can-find-more-about-the-project" id="where-i-can-find-more-about-the-project">Where I can find more about the project?</h2>
<ul><li><a href="https://libretranslate.com" rel="nofollow">https://libretranslate.com</a></li>
<li><a href="https://github.com/LibreTranslate/LibreTranslate" rel="nofollow">https://github.com/LibreTranslate/LibreTranslate</a></li></ul>

<h2 id="how-i-can-install-it" id="how-i-can-install-it">How I can install it?</h2>

<p>first, let&#39;s create the directories</p>

<pre><code>mkdir -p /opt/libretranslate/docker
mkdir -p /opt/libretransalte/data/{key,local}
</code></pre>

<p>now let&#39;s configure the permissions</p>

<pre><code>chown 1032:1032 /opt/libretransalte/data
chown 1032:1032 /opt/libretransalte/data/key
chown 1032:1032 /opt/libretransalte/data/local
</code></pre>

<p>then, let&#39;s create the docker-compose file</p>

<pre><code>cd /opt/libretranslate/docker
vim docker-compose.yaml
</code></pre>

<p>here follows the content, change the parameters for you setup</p>

<pre><code>version: &#34;3&#34;

services:
  libretranslate:
    container_name: libretranslate
    image: libretranslate/libretranslate:v1.3.11
    restart: unless-stopped
    dns:
      - 1.1.1.1
      - 8.8.8.8
    ports:
      - &#34;5000:5000&#34;
    healthcheck:
      test: [&#39;CMD-SHELL&#39;, &#39;./venv/bin/python scripts/healthcheck.py&#39;]
    env_file:
      - libretranslate.env
    volumes:
     - libretranslate_api_keys:/app/db
     - libretranslate_local:/home/libretranslate/.local

volumes:
  libretranslate_api_keys:
    driver_opts:
      type: none
      device: /opt/libretranslate/data/keys
      o: bind
  libretranslate_local:
    driver_opts:
      type: none
      device: /opt/libretranslate/data/local
      o: bind
</code></pre>

<p>then, let&#39;s create the libetranslate env file</p>

<pre><code>vim libretranslate.env
</code></pre>

<p>here follows the content, change the parameters for you setup</p>

<pre><code>LT_DEBUG=true
LT_UPDATE_MODELS=true
LT_SSL=true
LT_SUGGESTIONS=false
LT_METRICS=true

LT_API_KEYS=true

LT_THREADS=12
LT_FRONTEND_TIMEOUT=2000

#LT_REQ_LIMIT=400
#LT_CHAR_LIMIT=1200

LT_API_KEYS_DB_PATH=/app/db/api_keys.db
</code></pre>

<p>all right, let&#39;s spin up the libretranslate</p>

<pre><code>docker-compose up -d
</code></pre>

<h3 id="installing-the-model-files" id="installing-the-model-files">installing the model files</h3>

<p>you should enter the container</p>

<pre><code>docker exec -it libretranslate bash
</code></pre>

<p>and run the command to install all languages</p>

<pre><code>for i in `/app/venv/bin/argospm list`;do /app/venv/bin/argospm install $i;done
</code></pre>

<p>it will took some time to install, go drink a coffee, then check the directory in your host</p>

<pre><code>$ exit
$ ls -1 /opt/libretranslate/data/local/share/argos-translate/packages/

ar_en
de_en
en_ar
en_de
en_es
en_fi
en_fr
en_ga
en_hi
en_hu
en_id
en_it
en_ja
en_ko
en_nl
en_pl
en_pt
en_sv
en_uk
es_en
fi_en
fr_en
ga_en
hi_en
hu_en
id_en
it_en
ja_en
ko_en
nl_en
pl_en
pt_en
ru_en
sv_en
translate-az_en-1_5
translate-ca_en-1_7
translate-cs_en-1_5
translate-da_en-1_3
translate-el_en-1_5
translate-en_az-1_5
translate-en_ca-1_7
translate-en_cs-1_5
translate-en_da-1_3
translate-en_el-1_5
translate-en_eo-1_5
translate-en_fa-1_5
translate-en_he-1_5
translate-en_ru-1_7
translate-en_sk-1_5
translate-en_th-1_0
translate-en_tr-1_5
translate-en_zh-1_7
translate-eo_en-1_5
translate-fa_en-1_5
translate-he_en-1_5
translate-sk_en-1_5
translate-th_en-1_0
translate-tr_en-1_5
translate-zh_en-1_7
uk_en
</code></pre>

<p>Awesome it&#39;s all there.</p>

<h3 id="creating-the-api-key" id="creating-the-api-key">creating the api key</h3>

<p>Since we&#39;re using “LT<em>API</em>KEYS=true” we need to create an API KEY to be able to use libretranslate via API. Let&#39;s go to the container again</p>

<pre><code>docker exec -it libretranslate bash
</code></pre>

<p>let&#39;s create a key with permission to run 120 requests per minute.</p>

<pre><code>/app/venv/bin/ltmanage keys add 120
</code></pre>

<p>example of the expected output</p>

<pre><code>libretranslate@ba7f705d97b9:/app$ /app/venv/bin/ltmanage keys
ecae7db0-bolha-us-is-cool-c84c14d2117a: 1200
</code></pre>

<p>nice, everything is ready to be used, now let&#39;s configure your nginx!</p>

<h3 id="testing-the-api" id="testing-the-api">testing the api</h3>

<pre><code>curl -XPOST -H &#34;Content-type: application/json&#34; -d &#39;{
&#34;q&#34;: &#34;Bolha.io is the most cool project in the fediverso&#34;,
&#34;source&#34;: &#34;en&#34;,
&#34;target&#34;: &#34;pt&#34;
}&#39; &#39;http://localhost:5000/translate&#39;
</code></pre>

<p>expected output</p>

<pre><code>{&#34;translatedText&#34;:&#34;Bolha.io é o projeto mais legal no fediverso&#34;}
</code></pre>

<h2 id="external-nginx" id="external-nginx">external nginx</h2>

<p>In our case, libretranslate is behind an External NGINX Reverse Proxy.</p>

<p>Here follows the config snippet used</p>

<pre><code>upstream libretranslate {
    server your_docker_host_ip:your_libretranslate_port fail_timeout=0;
}

server {
  listen 144.217.95.91:80;
  server_name libretranslate.domain.tld;
  return 301 https://libretranslate.domain.tld$request_uri;
}

server {

  listen 144.217.95.91:443 ssl http2;
  server_name libretranslate;

  access_log /var/log/nginx/libretranslate-domain-tld.log;
  error_log /var/log/nginx/libretranslate-domain-tld.log;

  ssl_certificate /etc/letsencrypt/live/domain.tld/fullchain.pem;
  ssl_certificate_key /etc/letsencrypt/live/domain.tld/privkey.pem;

  ssl_protocols TLSv1.2 TLSv1.3;
  ssl_prefer_server_ciphers on;
  ssl_dhparam /etc/letsencrypt/dh-param.pem;

  ssl_ciphers &#39;ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256&#39;;

  ssl_session_cache shared:SSL:10m;
  ssl_session_tickets off;

  location / {
    proxy_pass http://libretranslate;
  }

}
</code></pre>

<p>Now you can access your libretranstale via web</p>
<ul><li><a href="https://libretranslate.domain.tld" rel="nofollow">https://libretranslate.domain.tld</a></li></ul>

<p>That&#39;s it :)</p>

<p>[s]</p>
]]></content:encoded>
      <author>howtos</author>
      <guid>https://blog.gcn.sh/read/a/xc2mlslid0</guid>
      <pubDate>Wed, 05 Jul 2023 00:39:07 +0000</pubDate>
    </item>
    <item>
      <title>Matrix projects list</title>
      <link>https://blog.gcn.sh/fediverse/matrix-projects-list</link>
      <description>&lt;![CDATA[Official&#xA;&#xA;https://matrix.org&#xA;https://matrix.org/about/&#xA;https://matrix.org/blog/&#xA;&#xA;Spec&#xA;&#xA;https://spec.matrix.org/v1.7/&#xA;&#xA;Projects&#xA;&#xA;https://matrix.org/ecosystem/clients/&#xA;https://matrix.org/ecosystem/servers/&#xA;https://matrix.org/ecosystem/bridges/&#xA;&#xA;Server&#xA;&#xA;https://github.com/matrix-org/synapse/&#xA;&#xA;Web Clients&#xA;&#xA;https://matrix.org/ecosystem/clients/element/&#xA;https://matrix.org/ecosystem/clients/cinny/&#xA;https://matrix.org/ecosystem/clients/hydrogen/&#xA;https://matrix.org/ecosystem/clients/fluffychat/&#xA;&#xA;Desktop Clients&#xA;&#xA;https://matrix.org/ecosystem/clients/element/&#xA;&#xA;Mobile Clients&#xA;&#xA;https://matrix.org/ecosystem/clients/element/&#xA;https://matrix.org/ecosystem/clients/cinny/&#xA;https://matrix.org/ecosystem/clients/hydrogen/&#xA;https://matrix.org/ecosystem/clients/fluffychat/&#xA;&#xA;Element project&#xA;&#xA;https://element.io&#xA;https://matrix.org/ecosystem/clients/element/&#xA;&#xA;Other&#xA;&#xA;https://uhoreg.gitlab.io/matrix-tutorial/]]&gt;</description>
      <content:encoded><![CDATA[<h1 id="official" id="official">Official</h1>
<ul><li><a href="https://matrix.org" rel="nofollow">https://matrix.org</a></li>
<li><a href="https://matrix.org/about/" rel="nofollow">https://matrix.org/about/</a></li>
<li><a href="https://matrix.org/blog/" rel="nofollow">https://matrix.org/blog/</a></li></ul>

<h2 id="spec" id="spec">Spec</h2>
<ul><li><a href="https://spec.matrix.org/v1.7/" rel="nofollow">https://spec.matrix.org/v1.7/</a></li></ul>

<h2 id="projects" id="projects">Projects</h2>
<ul><li><a href="https://matrix.org/ecosystem/clients/" rel="nofollow">https://matrix.org/ecosystem/clients/</a></li>
<li><a href="https://matrix.org/ecosystem/servers/" rel="nofollow">https://matrix.org/ecosystem/servers/</a></li>
<li><a href="https://matrix.org/ecosystem/bridges/" rel="nofollow">https://matrix.org/ecosystem/bridges/</a></li></ul>

<h2 id="server" id="server">Server</h2>
<ul><li><a href="https://github.com/matrix-org/synapse/" rel="nofollow">https://github.com/matrix-org/synapse/</a></li></ul>

<h2 id="web-clients" id="web-clients">Web Clients</h2>
<ul><li><a href="https://matrix.org/ecosystem/clients/element/" rel="nofollow">https://matrix.org/ecosystem/clients/element/</a></li>
<li><a href="https://matrix.org/ecosystem/clients/cinny/" rel="nofollow">https://matrix.org/ecosystem/clients/cinny/</a></li>
<li><a href="https://matrix.org/ecosystem/clients/hydrogen/" rel="nofollow">https://matrix.org/ecosystem/clients/hydrogen/</a></li>
<li><a href="https://matrix.org/ecosystem/clients/fluffychat/" rel="nofollow">https://matrix.org/ecosystem/clients/fluffychat/</a></li></ul>

<h2 id="desktop-clients" id="desktop-clients">Desktop Clients</h2>
<ul><li><a href="https://matrix.org/ecosystem/clients/element/" rel="nofollow">https://matrix.org/ecosystem/clients/element/</a></li></ul>

<h2 id="mobile-clients" id="mobile-clients">Mobile Clients</h2>
<ul><li><a href="https://matrix.org/ecosystem/clients/element/" rel="nofollow">https://matrix.org/ecosystem/clients/element/</a></li>
<li><a href="https://matrix.org/ecosystem/clients/cinny/" rel="nofollow">https://matrix.org/ecosystem/clients/cinny/</a></li>
<li><a href="https://matrix.org/ecosystem/clients/hydrogen/" rel="nofollow">https://matrix.org/ecosystem/clients/hydrogen/</a></li>
<li><a href="https://matrix.org/ecosystem/clients/fluffychat/" rel="nofollow">https://matrix.org/ecosystem/clients/fluffychat/</a></li></ul>

<h2 id="element-project" id="element-project">Element project</h2>
<ul><li><a href="https://element.io" rel="nofollow">https://element.io</a></li>
<li><a href="https://matrix.org/ecosystem/clients/element/" rel="nofollow">https://matrix.org/ecosystem/clients/element/</a></li></ul>

<h2 id="other" id="other">Other</h2>
<ul><li><a href="https://uhoreg.gitlab.io/matrix-tutorial/" rel="nofollow">https://uhoreg.gitlab.io/matrix-tutorial/</a></li></ul>
]]></content:encoded>
      <author>fediverse</author>
      <guid>https://blog.gcn.sh/read/a/1qxj0i4b7t</guid>
      <pubDate>Fri, 30 Jun 2023 20:13:03 +0000</pubDate>
    </item>
    <item>
      <title>Mastodon Project List</title>
      <link>https://blog.gcn.sh/fediverse/mastodon-project-list</link>
      <description>&lt;![CDATA[This is a list of mastodon-related projects and apps.&#xA;&#xA;Last update: 22/Jun/23&#xA;&#xA;official project site&#xA;&#xA;https://joinmastodon.org&#xA;&#xA;official git repo&#xA;&#xA;https://github.com/mastodon/mastodon&#xA;https://github.com/mastodon/mastodon/issues&#xA;https://github.com/mastodon/mastodon/releases&#xA;&#xA;oficial docker repo&#xA;&#xA;https://hub.docker.com/r/tootsuite/mastodon&#xA;&#xA;official instances&#xA;&#xA;https://mastodon.social&#xA;https://mastodon.online&#xA;&#xA;recommend instances&#xA;&#xA;Brazil&#xA;&#xA;https://bolha.us&#xA;https://ursal.zone&#xA;&#xA;mastodon relevant forks&#xA;&#xA;glitch-soc&#xA;hometown&#xA;fedibird&#xA;ecko&#xA;&#xA;mastodon web-clients&#xA;&#xA;https://elk.zone&#xA;https://pinafore.social&#xA;https://brutaldon.org&#xA;&#xA;mastodon frontends?&#xA;&#xA;https://soapbox.pub&#xA;    https://docs.soapbox.pub/frontend/administration/mastodon&#xA;&#xA;mastodon desktop clients&#xA;&#xA;Ivory &#xA;    #GutoRecomends&#xA;whalebird&#xA;&#xA;beta&#xA;&#xA;wolly&#xA;trunks&#xA;&#xA;mastodon ios clients&#xA;&#xA;offical app&#xA;&#xA;Mastodon &#xA;    #GutoRecomends&#xA;&#xA;tapbots&#xA;&#xA;Ivory &#xA;    #GutoRecomends&#xA;&#xA;others&#xA;&#xA;Metatext&#xA;Toot! &#xA;Ice Cubes&#xA;Trunks&#xA;&#xA;beta&#xA;&#xA;Mammoth&#xA;Trunks&#xA;&#xA;mastodon android clients&#xA;&#xA;oficial client&#xA;&#xA;Mastodon&#xA;    #GutoRecomenda &#xA;&#xA;others&#xA;&#xA;https://fedilab.app&#xA;https://sk22.github.io/megalodon&#xA;https://tooot.app/&#xA;https://tusky.app/&#xA;https://github.com/LucasGGamerM/moshidon&#xA;    #GutoRecomends&#xA;&#xA;mastodon terminal clients&#xA;&#xA;https://toot.bezdomni.net&#xA;&#xA;mastodon utils&#xA;&#xA;https://github.com/muesli/mastotool&#xA;https://github.com/McKael/madonctl&#xA;https://github.com/schochastics/rtoot&#xA;&#xA;do you want to help with this list?&#xA;&#xA;Please send your suggestions to:&#xA;&#xA;mastodon&#xA;@gutocarvalho@gcn.sh&#xA;&#xA;matrix &#xA;@gutocarvalho@bolha.chat&#xA;&#xA;]]&gt;</description>
      <content:encoded><![CDATA[<p>This is a list of mastodon-related projects and apps.</p>

<p>Last update: 22/Jun/23</p>

<h2 id="official-project-site" id="official-project-site">official project site</h2>
<ul><li><a href="https://joinmastodon.org" rel="nofollow">https://joinmastodon.org</a></li></ul>

<h2 id="official-git-repo" id="official-git-repo">official git repo</h2>
<ul><li><a href="https://github.com/mastodon/mastodon" rel="nofollow">https://github.com/mastodon/mastodon</a></li>
<li><a href="https://github.com/mastodon/mastodon/issues" rel="nofollow">https://github.com/mastodon/mastodon/issues</a></li>
<li><a href="https://github.com/mastodon/mastodon/releases" rel="nofollow">https://github.com/mastodon/mastodon/releases</a></li></ul>

<h2 id="oficial-docker-repo" id="oficial-docker-repo">oficial docker repo</h2>
<ul><li><a href="https://hub.docker.com/r/tootsuite/mastodon" rel="nofollow">https://hub.docker.com/r/tootsuite/mastodon</a></li></ul>

<h2 id="official-instances" id="official-instances">official instances</h2>
<ul><li><a href="https://mastodon.social" rel="nofollow">https://mastodon.social</a></li>
<li><a href="https://mastodon.online" rel="nofollow">https://mastodon.online</a></li></ul>

<h2 id="recommend-instances" id="recommend-instances">recommend instances</h2>

<h3 id="brazil" id="brazil">Brazil</h3>
<ul><li><a href="https://bolha.us" rel="nofollow">https://bolha.us</a></li>
<li><a href="https://ursal.zone" rel="nofollow">https://ursal.zone</a></li></ul>

<h2 id="mastodon-relevant-forks" id="mastodon-relevant-forks">mastodon relevant forks</h2>
<ul><li><a href="https://github.com/glitch-soc/mastodon" rel="nofollow">glitch-soc</a></li>
<li><a href="https://github.com/hometown-fork/hometown" rel="nofollow">hometown</a></li>
<li><a href="https://github.com/fedibird/mastodon" rel="nofollow">fedibird</a></li>
<li><a href="https://github.com/magicstone-dev/ecko" rel="nofollow">ecko</a></li></ul>

<h2 id="mastodon-web-clients" id="mastodon-web-clients">mastodon web-clients</h2>
<ul><li><a href="https://elk.zone" rel="nofollow">https://elk.zone</a></li>
<li><a href="https://pinafore.social" rel="nofollow">https://pinafore.social</a></li>
<li><a href="https://brutaldon.org" rel="nofollow">https://brutaldon.org</a></li></ul>

<h2 id="mastodon-frontends" id="mastodon-frontends">mastodon frontends?</h2>
<ul><li><a href="https://soapbox.pub" rel="nofollow">https://soapbox.pub</a>
<ul><li><a href="https://docs.soapbox.pub/frontend/administration/mastodon" rel="nofollow">https://docs.soapbox.pub/frontend/administration/mastodon</a></li></ul></li></ul>

<h2 id="mastodon-desktop-clients" id="mastodon-desktop-clients">mastodon desktop clients</h2>
<ul><li><a href="https://tapbots.com/ivory" rel="nofollow">Ivory</a>
<ul><li>#GutoRecomends</li></ul></li>
<li><a href="https://whalebird.social" rel="nofollow">whalebird</a></li></ul>

<h3 id="beta" id="beta">beta</h3>
<ul><li><a href="https://github.com/outadoc/woolly-app" rel="nofollow">wolly</a></li>
<li><a href="https://trunks.social" rel="nofollow">trunks</a></li></ul>

<h2 id="mastodon-ios-clients" id="mastodon-ios-clients">mastodon ios clients</h2>

<p>offical app</p>
<ul><li><a href="https://apps.apple.com/us/app/mastodon-for-iphone-and-ipad/id1571998974?platform=iphone" rel="nofollow">Mastodon</a>
<ul><li>#GutoRecomends</li></ul></li></ul>

<p>tapbots</p>
<ul><li><a href="https://tapbots.com/ivory" rel="nofollow">Ivory</a>
<ul><li>#GutoRecomends</li></ul></li></ul>

<p>others</p>
<ul><li><a href="https://apps.apple.com/us/app/metatext/id1523996615?platform=iphone" rel="nofollow">Metatext</a></li>
<li><a href="https://apps.apple.com/us/app/toot-for-mastodon/id1229021451" rel="nofollow">Toot!</a></li>
<li><a href="https://apps.apple.com/us/app/ice-cubes-for-mastodon/id6444915884?platform=iphone" rel="nofollow">Ice Cubes</a></li>
<li><a href="https://trunks.social" rel="nofollow">Trunks</a></li></ul>

<h3 id="beta-1" id="beta-1">beta</h3>
<ul><li><a href="https://testflight.apple.com/join/66c1wW8y" rel="nofollow">Mammoth</a></li>
<li><a href="https://trunks.social" rel="nofollow">Trunks</a></li></ul>

<h2 id="mastodon-android-clients" id="mastodon-android-clients">mastodon android clients</h2>

<p>oficial client</p>
<ul><li><a href="https://www.androidpolice.com/mastodon-officially-comes-to-the-play-store" rel="nofollow">Mastodon</a>
<ul><li>#GutoRecomenda</li></ul></li></ul>

<p>others</p>
<ul><li><a href="https://fedilab.app" rel="nofollow">https://fedilab.app</a></li>
<li><a href="https://sk22.github.io/megalodon" rel="nofollow">https://sk22.github.io/megalodon</a></li>
<li><a href="https://tooot.app/" rel="nofollow">https://tooot.app/</a></li>
<li><a href="https://tusky.app/" rel="nofollow">https://tusky.app/</a></li>
<li><a href="https://github.com/LucasGGamerM/moshidon" rel="nofollow">https://github.com/LucasGGamerM/moshidon</a>
<ul><li>#GutoRecomends</li></ul></li></ul>

<h2 id="mastodon-terminal-clients" id="mastodon-terminal-clients">mastodon terminal clients</h2>
<ul><li><a href="https://toot.bezdomni.net" rel="nofollow">https://toot.bezdomni.net</a></li></ul>

<h2 id="mastodon-utils" id="mastodon-utils">mastodon utils</h2>
<ul><li><a href="https://github.com/muesli/mastotool" rel="nofollow">https://github.com/muesli/mastotool</a></li>
<li><a href="https://github.com/McKael/madonctl" rel="nofollow">https://github.com/McKael/madonctl</a></li>
<li><a href="https://github.com/schochastics/rtoot" rel="nofollow">https://github.com/schochastics/rtoot</a></li></ul>

<h2 id="do-you-want-to-help-with-this-list" id="do-you-want-to-help-with-this-list">do you want to help with this list?</h2>

<p>Please send your suggestions to:</p>

<p>mastodon
– @gutocarvalho@gcn.sh</p>

<p>matrix
– @gutocarvalho@bolha.chat</p>
]]></content:encoded>
      <author>fediverse</author>
      <guid>https://blog.gcn.sh/read/a/3cpf46e94c</guid>
      <pubDate>Thu, 22 Jun 2023 09:26:00 +0000</pubDate>
    </item>
    <item>
      <title>Fediverse Projects List</title>
      <link>https://blog.gcn.sh/fediverse/fediverse-projects-list</link>
      <description>&lt;![CDATA[full-feature social networks&#xA;&#xA;https://friendi.ca&#xA;https://diasporafoundation.org&#xA;&#xA;strange social network projects&#xA;&#xA;https://hubzilla.org&#xA;https://gnusocial.network&#xA;&#xA;microblogs&#xA;&#xA;https://joinmastodon.org&#xA;https://pleroma.social&#xA;https://join.misskey.page&#xA;&#xA;beta&#xA;&#xA;https://bonfirenetworks.org&#xA;https://github.com/jointakahe/takahe&#xA;&#xA;mastodon Forks&#xA;&#xA;https://github.com/glitch-soc/mastodon&#xA;https://github.com/hometown-fork/hometown&#xA;https://github.com/fedibird/mastodon&#xA;https://github.com/magicstone-dev/ecko&#xA;&#xA;mastodon frontends &amp; webclients&#xA;&#xA;https://elk.zone&#xA;https://pinafore.social&#xA;https://brutaldon.org&#xA;https://docs.soapbox.pub/frontend/administration/mastodon&#xA;&#xA;chat&#xA;&#xA;https://matrix.org&#xA;&#xA;blogs&#xA;&#xA;https://writefreely.org&#xA;https://joinplu.me&#xA;&#xA;social reading and reviewing&#xA;&#xA;https://joinbookwyrm.com&#xA;&#xA;photos&#xA;&#xA;https://pixelfed.org&#xA;&#xA;link aggregator&#xA;&#xA;https://join-lemmy.org&#xA;https://kbin.pub&#xA;&#xA;music&#xA;&#xA;https://funkwhale.audio&#xA;&#xA;video&#xA;&#xA;https://joinpeertube.org&#xA;&#xA;streaming&#xA;&#xA;https://owncast.online&#xA;&#xA;podcast&#xA;&#xA;https://castopod.org&#xA;&#xA;event organization&#xA;&#xA;https://joinmobilizon.org&#xA;https://gancio.org&#xA;https://gath.io&#xA;&#xA;image board&#xA;&#xA;https://codeberg.org/pinetta/pinetta]]&gt;</description>
      <content:encoded><![CDATA[<h3 id="full-feature-social-networks" id="full-feature-social-networks">full-feature social networks</h3>
<ul><li><a href="https://friendi.ca" rel="nofollow">https://friendi.ca</a></li>
<li><a href="https://diasporafoundation.org" rel="nofollow">https://diasporafoundation.org</a></li></ul>

<h3 id="strange-social-network-projects" id="strange-social-network-projects">strange social network projects</h3>
<ul><li><a href="https://hubzilla.org" rel="nofollow">https://hubzilla.org</a></li>
<li><a href="https://gnusocial.network" rel="nofollow">https://gnusocial.network</a></li></ul>

<h3 id="microblogs" id="microblogs">microblogs</h3>
<ul><li><a href="https://joinmastodon.org" rel="nofollow">https://joinmastodon.org</a></li>
<li><a href="https://pleroma.social" rel="nofollow">https://pleroma.social</a></li>
<li><a href="https://join.misskey.page" rel="nofollow">https://join.misskey.page</a></li></ul>

<p>beta</p>
<ul><li><a href="https://bonfirenetworks.org" rel="nofollow">https://bonfirenetworks.org</a></li>
<li><a href="https://github.com/jointakahe/takahe" rel="nofollow">https://github.com/jointakahe/takahe</a></li></ul>

<p>mastodon Forks</p>
<ul><li><a href="https://github.com/glitch-soc/mastodon" rel="nofollow">https://github.com/glitch-soc/mastodon</a></li>
<li><a href="https://github.com/hometown-fork/hometown" rel="nofollow">https://github.com/hometown-fork/hometown</a></li>
<li><a href="https://github.com/fedibird/mastodon" rel="nofollow">https://github.com/fedibird/mastodon</a></li>
<li><a href="https://github.com/magicstone-dev/ecko" rel="nofollow">https://github.com/magicstone-dev/ecko</a></li></ul>

<p>mastodon frontends &amp; webclients</p>
<ul><li><a href="https://elk.zone" rel="nofollow">https://elk.zone</a></li>
<li><a href="https://pinafore.social" rel="nofollow">https://pinafore.social</a></li>
<li><a href="https://brutaldon.org" rel="nofollow">https://brutaldon.org</a></li>
<li><a href="https://docs.soapbox.pub/frontend/administration/mastodon" rel="nofollow">https://docs.soapbox.pub/frontend/administration/mastodon</a></li></ul>

<h3 id="chat" id="chat">chat</h3>
<ul><li><a href="https://matrix.org" rel="nofollow">https://matrix.org</a></li></ul>

<h3 id="blogs" id="blogs">blogs</h3>
<ul><li><a href="https://writefreely.org" rel="nofollow">https://writefreely.org</a></li>
<li><a href="https://joinplu.me" rel="nofollow">https://joinplu.me</a></li></ul>

<h3 id="social-reading-and-reviewing" id="social-reading-and-reviewing">social reading and reviewing</h3>
<ul><li><a href="https://joinbookwyrm.com" rel="nofollow">https://joinbookwyrm.com</a></li></ul>

<h3 id="photos" id="photos">photos</h3>
<ul><li><a href="https://pixelfed.org" rel="nofollow">https://pixelfed.org</a></li></ul>

<h3 id="link-aggregator" id="link-aggregator">link aggregator</h3>
<ul><li><a href="https://join-lemmy.org" rel="nofollow">https://join-lemmy.org</a></li>
<li><a href="https://kbin.pub" rel="nofollow">https://kbin.pub</a></li></ul>

<h3 id="music" id="music">music</h3>
<ul><li><a href="https://funkwhale.audio" rel="nofollow">https://funkwhale.audio</a></li></ul>

<h3 id="video" id="video">video</h3>
<ul><li><a href="https://joinpeertube.org" rel="nofollow">https://joinpeertube.org</a></li></ul>

<h3 id="streaming" id="streaming">streaming</h3>
<ul><li><a href="https://owncast.online" rel="nofollow">https://owncast.online</a></li></ul>

<h3 id="podcast" id="podcast">podcast</h3>
<ul><li><a href="https://castopod.org" rel="nofollow">https://castopod.org</a></li></ul>

<h3 id="event-organization" id="event-organization">event organization</h3>
<ul><li><a href="https://joinmobilizon.org" rel="nofollow">https://joinmobilizon.org</a></li>
<li><a href="https://gancio.org" rel="nofollow">https://gancio.org</a></li>
<li><a href="https://gath.io" rel="nofollow">https://gath.io</a></li></ul>

<h3 id="image-board" id="image-board">image board</h3>
<ul><li><a href="https://codeberg.org/pinetta/pinetta" rel="nofollow">https://codeberg.org/pinetta/pinetta</a></li></ul>
]]></content:encoded>
      <author>fediverse</author>
      <guid>https://blog.gcn.sh/read/a/a1arirk78x</guid>
      <pubDate>Wed, 21 Jun 2023 23:55:49 +0000</pubDate>
    </item>
    <item>
      <title>Fediverse Sites List</title>
      <link>https://blog.gcn.sh/fediverse/fediverse-sites-list</link>
      <description>&lt;![CDATA[fediverse.info&#xA;&#xA;https://fediverse.info/explore/projects&#xA;https://fediverse.info/explore/people&#xA;&#xA;fedidb.org&#xA;&#xA;https://fedidb.org&#xA;https://fedidb.org/network&#xA;https://fedidb.org/software&#xA;&#xA;Bolha Data!&#xA;&#xA;https://fedidb.org/network/instance/bolha.us&#xA;https://fedidb.org/network/instance/bolha.photos&#xA;https://fedidb.org/network/instance/bolha.social&#xA;https://fedidb.org/network/instance/bolha.blog&#xA;&#xA;others&#xA;&#xA;https://instances.social&#xA;https://the-federation.info&#xA;https://fediverse.observer&#xA;https://fediverse.party&#xA;https://fedi.tips&#xA;&#xA;new sites to check&#xA;&#xA;https://joinfediverse.wiki&#xA;https://github.com/ineffyble/mastodon-block-tools]]&gt;</description>
      <content:encoded><![CDATA[<h2 id="fediverse-info" id="fediverse-info">fediverse.info</h2>
<ul><li><a href="https://fediverse.info/explore/projects" rel="nofollow">https://fediverse.info/explore/projects</a></li>
<li><a href="https://fediverse.info/explore/people" rel="nofollow">https://fediverse.info/explore/people</a></li></ul>

<h2 id="fedidb-org" id="fedidb-org">fedidb.org</h2>
<ul><li><a href="https://fedidb.org" rel="nofollow">https://fedidb.org</a></li>
<li><a href="https://fedidb.org/network" rel="nofollow">https://fedidb.org/network</a></li>
<li><a href="https://fedidb.org/software" rel="nofollow">https://fedidb.org/software</a></li></ul>

<p>Bolha Data!</p>
<ul><li><a href="https://fedidb.org/network/instance/bolha.us" rel="nofollow">https://fedidb.org/network/instance/bolha.us</a></li>
<li><a href="https://fedidb.org/network/instance/bolha.photos" rel="nofollow">https://fedidb.org/network/instance/bolha.photos</a></li>
<li><a href="https://fedidb.org/network/instance/bolha.social" rel="nofollow">https://fedidb.org/network/instance/bolha.social</a></li>
<li><a href="https://fedidb.org/network/instance/bolha.blog" rel="nofollow">https://fedidb.org/network/instance/bolha.blog</a></li></ul>

<h2 id="others" id="others">others</h2>
<ul><li><a href="https://instances.social" rel="nofollow">https://instances.social</a></li>
<li><a href="https://the-federation.info" rel="nofollow">https://the-federation.info</a></li>
<li><a href="https://fediverse.observer" rel="nofollow">https://fediverse.observer</a></li>
<li><a href="https://fediverse.party" rel="nofollow">https://fediverse.party</a></li>
<li><a href="https://fedi.tips" rel="nofollow">https://fedi.tips</a></li></ul>

<h2 id="new-sites-to-check" id="new-sites-to-check">new sites to check</h2>
<ul><li><a href="https://joinfediverse.wiki" rel="nofollow">https://joinfediverse.wiki</a></li>
<li><a href="https://github.com/ineffyble/mastodon-block-tools" rel="nofollow">https://github.com/ineffyble/mastodon-block-tools</a></li></ul>
]]></content:encoded>
      <author>fediverse</author>
      <guid>https://blog.gcn.sh/read/a/l544i0052u</guid>
      <pubDate>Thu, 15 Jun 2023 04:09:33 +0000</pubDate>
    </item>
  </channel>
</rss>