<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>howtos</title>
    <link>https://blog.gcn.sh/howtos/</link>
    <description>To help me to remember, and perhaps to help you :)</description>
    <pubDate>Thu, 09 Apr 2026 01:23:04 +0000</pubDate>
    <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;hr&#xD;&#xA;Did you like our content?&#xD;&#xA;&#xD;&#xA;We have a lot to share; visit our site!&#xD;&#xA;&#xD;&#xA;https://bolha.io&#xD;&#xA;&#xD;&#xA;Our fediverse services ;)&#xD;&#xA;&#xD;&#xA;mastodon =  https://bolha.us&#xD;&#xA;    mastopoet =  https://poet.bolha.us&#xD;&#xA;    elk =  https://elk.bolha.us&#xD;&#xA;    pinafore =  https://pinafore.bolha.us&#xD;&#xA;pixelfed =  https://bolha.photos&#xD;&#xA;lemmy =  https://bolha.social&#xD;&#xA;writefreely =  https://bolha.blog&#xD;&#xA;bookwyrm =  https://bolha.review&#xD;&#xA;funkwhale =  https://bolha.studio&#xD;&#xA;friendica =  https://bolha.network&#xD;&#xA;&#xD;&#xA;Chat and video? We have it!&#xD;&#xA;    &#xD;&#xA;matrix =  https://bolha.chat&#xD;&#xA;jitsi =  https://bolha.video&#xD;&#xA;&#xD;&#xA;Translation tools&#xD;&#xA;&#xD;&#xA; libretranslate =  https://libretranslate.bolha.tools&#xD;&#xA; lingva =  https://translate.bolha.tools&#xD;&#xA;&#xD;&#xA;Video Platform Frontends&#xD;&#xA;&#xD;&#xA; invidious =  https://bolha.in&#xD;&#xA;&#xD;&#xA;Text Editors&#xD;&#xA;&#xD;&#xA; hedgeDoc =  https://notes.bolha.tools&#xD;&#xA; wise Mapping =  https://mindmap.bolha.tools&#xD;&#xA; overleaf =  https://overleaf.bolha.tools&#xD;&#xA; mermaid =  https://mermaid.bolha.tools&#xD;&#xA;&#xD;&#xA;You can also visit our hacking space!&#xD;&#xA;&#xD;&#xA;https://gcn.sh&#xD;&#xA;https://blog.gcn.sh&#xD;&#xA;&#xD;&#xA;Follow our founder!&#xD;&#xA;&#xD;&#xA;https://bolha.us/@gutocarvalho&#xD;&#xA;https://bolha.photos/@gutocarvalho&#xD;&#xA;https://bolha.forum@gutocarvalho&#xD;&#xA;https://bolha.blog/@gutocarvalho&#xD;&#xA;https://bolha.review/@gutocarvalho&#xD;&#xA;https://bolha.studio/@gutocarvalho&#xD;&#xA;https://bolha.network/@gutocarvalho&#xD;&#xA;matrix =  @bolha.chat@gutocarvalho&#xD;&#xA;&#xD;&#xA;Follow the status of our tools&#xD;&#xA;&#xD;&#xA;https://status.bolha.us&#xD;&#xA;&#xD;&#xA;Do you want to support us? You can!&#xD;&#xA;&#xD;&#xA;https://www.patreon.com/bolha&#xD;&#xA;https://apoia.se/bolha&#xD;&#xA;pix@bolha.us (local brazilian wire transfer)&#xD;&#xA;&#xD;&#xA;See you!&#xD;&#xA;&#xD;&#xA;[s]]]&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>

<hr>

<h3 id="did-you-like-our-content" id="did-you-like-our-content">Did you like our content?</h3>

<p>We have a lot to share; visit our site!</p>
<ul><li><a href="https://bolha.io" rel="nofollow">https://bolha.io</a></li></ul>

<p>Our fediverse services ;)</p>
<ul><li>mastodon =&gt; <a href="https://bolha.us" rel="nofollow">https://bolha.us</a>
<ul><li>mastopoet =&gt; <a href="https://poet.bolha.us" rel="nofollow">https://poet.bolha.us</a></li>
<li>elk =&gt; <a href="https://elk.bolha.us" rel="nofollow">https://elk.bolha.us</a></li>
<li>pinafore =&gt; <a href="https://pinafore.bolha.us" rel="nofollow">https://pinafore.bolha.us</a></li></ul></li>
<li>pixelfed =&gt; <a href="https://bolha.photos" rel="nofollow">https://bolha.photos</a></li>
<li>lemmy =&gt; <a href="https://bolha.social" rel="nofollow">https://bolha.social</a></li>
<li>writefreely =&gt; <a href="https://bolha.blog" rel="nofollow">https://bolha.blog</a></li>
<li>bookwyrm =&gt; <a href="https://bolha.review" rel="nofollow">https://bolha.review</a></li>
<li>funkwhale =&gt; <a href="https://bolha.studio" rel="nofollow">https://bolha.studio</a></li>
<li>friendica =&gt; <a href="https://bolha.network" rel="nofollow">https://bolha.network</a></li></ul>

<p>Chat and video? We have it!</p>
<ul><li>matrix =&gt; <a href="https://bolha.chat" rel="nofollow">https://bolha.chat</a></li>
<li>jitsi =&gt; <a href="https://bolha.video" rel="nofollow">https://bolha.video</a></li></ul>

<p>Translation tools</p>
<ul><li>libretranslate =&gt; <a href="https://libretranslate.bolha.tools" rel="nofollow">https://libretranslate.bolha.tools</a></li>
<li>lingva =&gt; <a href="https://translate.bolha.tools" rel="nofollow">https://translate.bolha.tools</a></li></ul>

<p>Video Platform Frontends</p>
<ul><li>invidious =&gt; <a href="https://bolha.in" rel="nofollow">https://bolha.in</a></li></ul>

<p>Text Editors</p>
<ul><li>hedgeDoc =&gt; <a href="https://notes.bolha.tools" rel="nofollow">https://notes.bolha.tools</a></li>
<li>wise Mapping =&gt; <a href="https://mindmap.bolha.tools" rel="nofollow">https://mindmap.bolha.tools</a></li>
<li>overleaf =&gt; <a href="https://overleaf.bolha.tools" rel="nofollow">https://overleaf.bolha.tools</a></li>
<li>mermaid =&gt; <a href="https://mermaid.bolha.tools" rel="nofollow">https://mermaid.bolha.tools</a></li></ul>

<p>You can also visit our hacking space!</p>
<ul><li><a href="https://gcn.sh" rel="nofollow">https://gcn.sh</a></li>
<li><a href="https://blog.gcn.sh" rel="nofollow">https://blog.gcn.sh</a></li></ul>

<p>Follow our founder!</p>
<ul><li><a href="https://bolha.us/@gutocarvalho" rel="nofollow">https://bolha.us/@gutocarvalho</a></li>
<li><a href="https://bolha.photos/@gutocarvalho" rel="nofollow">https://bolha.photos/@gutocarvalho</a></li>
<li><a href="https://bolha.forum@gutocarvalho" rel="nofollow">https://bolha.forum@gutocarvalho</a></li>
<li><a href="https://bolha.blog/@gutocarvalho" rel="nofollow">https://bolha.blog/@gutocarvalho</a></li>
<li><a href="https://bolha.review/@gutocarvalho" rel="nofollow">https://bolha.review/@gutocarvalho</a></li>
<li><a href="https://bolha.studio/@gutocarvalho" rel="nofollow">https://bolha.studio/@gutocarvalho</a></li>
<li><a href="https://bolha.network/@gutocarvalho" rel="nofollow">https://bolha.network/@gutocarvalho</a></li>
<li>matrix =&gt; @bolha.chat@gutocarvalho</li></ul>

<p>Follow the status of our tools</p>
<ul><li><a href="https://status.bolha.us" rel="nofollow">https://status.bolha.us</a></li></ul>

<p>Do you want to support us? You can!</p>
<ul><li><a href="https://www.patreon.com/bolha" rel="nofollow">https://www.patreon.com/bolha</a></li>
<li><a href="https://apoia.se/bolha" rel="nofollow">https://apoia.se/bolha</a></li>
<li>pix@bolha.us (local brazilian wire transfer)</li></ul>

<p>See you!</p>

<p>[s]</p>
]]></content:encoded>
      <guid>https://blog.gcn.sh/howtos/installing-minio-uising-docker</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!&#xA;&#xA;hr&#xD;&#xA;Did you like our content?&#xD;&#xA;&#xD;&#xA;We have a lot to share; visit our site!&#xD;&#xA;&#xD;&#xA;https://bolha.io&#xD;&#xA;&#xD;&#xA;Our fediverse services ;)&#xD;&#xA;&#xD;&#xA;mastodon =  https://bolha.us&#xD;&#xA;    mastopoet =  https://poet.bolha.us&#xD;&#xA;    elk =  https://elk.bolha.us&#xD;&#xA;    pinafore =  https://pinafore.bolha.us&#xD;&#xA;pixelfed =  https://bolha.photos&#xD;&#xA;lemmy =  https://bolha.social&#xD;&#xA;writefreely =  https://bolha.blog&#xD;&#xA;bookwyrm =  https://bolha.review&#xD;&#xA;funkwhale =  https://bolha.studio&#xD;&#xA;friendica =  https://bolha.network&#xD;&#xA;&#xD;&#xA;Chat and video? We have it!&#xD;&#xA;    &#xD;&#xA;matrix =  https://bolha.chat&#xD;&#xA;jitsi =  https://bolha.video&#xD;&#xA;&#xD;&#xA;Translation tools&#xD;&#xA;&#xD;&#xA; libretranslate =  https://libretranslate.bolha.tools&#xD;&#xA; lingva =  https://translate.bolha.tools&#xD;&#xA;&#xD;&#xA;Video Platform Frontends&#xD;&#xA;&#xD;&#xA; invidious =  https://bolha.in&#xD;&#xA;&#xD;&#xA;Text Editors&#xD;&#xA;&#xD;&#xA; hedgeDoc =  https://notes.bolha.tools&#xD;&#xA; wise Mapping =  https://mindmap.bolha.tools&#xD;&#xA; overleaf =  https://overleaf.bolha.tools&#xD;&#xA; mermaid =  https://mermaid.bolha.tools&#xD;&#xA;&#xD;&#xA;You can also visit our hacking space!&#xD;&#xA;&#xD;&#xA;https://gcn.sh&#xD;&#xA;https://blog.gcn.sh&#xD;&#xA;&#xD;&#xA;Follow our founder!&#xD;&#xA;&#xD;&#xA;https://bolha.us/@gutocarvalho&#xD;&#xA;https://bolha.photos/@gutocarvalho&#xD;&#xA;https://bolha.forum@gutocarvalho&#xD;&#xA;https://bolha.blog/@gutocarvalho&#xD;&#xA;https://bolha.review/@gutocarvalho&#xD;&#xA;https://bolha.studio/@gutocarvalho&#xD;&#xA;https://bolha.network/@gutocarvalho&#xD;&#xA;matrix =  @bolha.chat@gutocarvalho&#xD;&#xA;&#xD;&#xA;Follow the status of our tools&#xD;&#xA;&#xD;&#xA;https://status.bolha.us&#xD;&#xA;&#xD;&#xA;Do you want to support us? You can!&#xD;&#xA;&#xD;&#xA;https://www.patreon.com/bolha&#xD;&#xA;https://apoia.se/bolha&#xD;&#xA;pix@bolha.us (local brazilian wire transfer)&#xD;&#xA;&#xD;&#xA;See you!&#xD;&#xA;&#xD;&#xA;[s]]]&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>

<hr>

<h3 id="did-you-like-our-content" id="did-you-like-our-content">Did you like our content?</h3>

<p>We have a lot to share; visit our site!</p>
<ul><li><a href="https://bolha.io" rel="nofollow">https://bolha.io</a></li></ul>

<p>Our fediverse services ;)</p>
<ul><li>mastodon =&gt; <a href="https://bolha.us" rel="nofollow">https://bolha.us</a>
<ul><li>mastopoet =&gt; <a href="https://poet.bolha.us" rel="nofollow">https://poet.bolha.us</a></li>
<li>elk =&gt; <a href="https://elk.bolha.us" rel="nofollow">https://elk.bolha.us</a></li>
<li>pinafore =&gt; <a href="https://pinafore.bolha.us" rel="nofollow">https://pinafore.bolha.us</a></li></ul></li>
<li>pixelfed =&gt; <a href="https://bolha.photos" rel="nofollow">https://bolha.photos</a></li>
<li>lemmy =&gt; <a href="https://bolha.social" rel="nofollow">https://bolha.social</a></li>
<li>writefreely =&gt; <a href="https://bolha.blog" rel="nofollow">https://bolha.blog</a></li>
<li>bookwyrm =&gt; <a href="https://bolha.review" rel="nofollow">https://bolha.review</a></li>
<li>funkwhale =&gt; <a href="https://bolha.studio" rel="nofollow">https://bolha.studio</a></li>
<li>friendica =&gt; <a href="https://bolha.network" rel="nofollow">https://bolha.network</a></li></ul>

<p>Chat and video? We have it!</p>
<ul><li>matrix =&gt; <a href="https://bolha.chat" rel="nofollow">https://bolha.chat</a></li>
<li>jitsi =&gt; <a href="https://bolha.video" rel="nofollow">https://bolha.video</a></li></ul>

<p>Translation tools</p>
<ul><li>libretranslate =&gt; <a href="https://libretranslate.bolha.tools" rel="nofollow">https://libretranslate.bolha.tools</a></li>
<li>lingva =&gt; <a href="https://translate.bolha.tools" rel="nofollow">https://translate.bolha.tools</a></li></ul>

<p>Video Platform Frontends</p>
<ul><li>invidious =&gt; <a href="https://bolha.in" rel="nofollow">https://bolha.in</a></li></ul>

<p>Text Editors</p>
<ul><li>hedgeDoc =&gt; <a href="https://notes.bolha.tools" rel="nofollow">https://notes.bolha.tools</a></li>
<li>wise Mapping =&gt; <a href="https://mindmap.bolha.tools" rel="nofollow">https://mindmap.bolha.tools</a></li>
<li>overleaf =&gt; <a href="https://overleaf.bolha.tools" rel="nofollow">https://overleaf.bolha.tools</a></li>
<li>mermaid =&gt; <a href="https://mermaid.bolha.tools" rel="nofollow">https://mermaid.bolha.tools</a></li></ul>

<p>You can also visit our hacking space!</p>
<ul><li><a href="https://gcn.sh" rel="nofollow">https://gcn.sh</a></li>
<li><a href="https://blog.gcn.sh" rel="nofollow">https://blog.gcn.sh</a></li></ul>

<p>Follow our founder!</p>
<ul><li><a href="https://bolha.us/@gutocarvalho" rel="nofollow">https://bolha.us/@gutocarvalho</a></li>
<li><a href="https://bolha.photos/@gutocarvalho" rel="nofollow">https://bolha.photos/@gutocarvalho</a></li>
<li><a href="https://bolha.forum@gutocarvalho" rel="nofollow">https://bolha.forum@gutocarvalho</a></li>
<li><a href="https://bolha.blog/@gutocarvalho" rel="nofollow">https://bolha.blog/@gutocarvalho</a></li>
<li><a href="https://bolha.review/@gutocarvalho" rel="nofollow">https://bolha.review/@gutocarvalho</a></li>
<li><a href="https://bolha.studio/@gutocarvalho" rel="nofollow">https://bolha.studio/@gutocarvalho</a></li>
<li><a href="https://bolha.network/@gutocarvalho" rel="nofollow">https://bolha.network/@gutocarvalho</a></li>
<li>matrix =&gt; @bolha.chat@gutocarvalho</li></ul>

<p>Follow the status of our tools</p>
<ul><li><a href="https://status.bolha.us" rel="nofollow">https://status.bolha.us</a></li></ul>

<p>Do you want to support us? You can!</p>
<ul><li><a href="https://www.patreon.com/bolha" rel="nofollow">https://www.patreon.com/bolha</a></li>
<li><a href="https://apoia.se/bolha" rel="nofollow">https://apoia.se/bolha</a></li>
<li>pix@bolha.us (local brazilian wire transfer)</li></ul>

<p>See you!</p>

<p>[s]</p>
]]></content:encoded>
      <guid>https://blog.gcn.sh/howtos/updating-mastodon-to-the-version-4-1-4</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!&#xA;&#xA;hr&#xD;&#xA;Did you like our content?&#xD;&#xA;&#xD;&#xA;We have a lot to share; visit our site!&#xD;&#xA;&#xD;&#xA;https://bolha.io&#xD;&#xA;&#xD;&#xA;Our fediverse services ;)&#xD;&#xA;&#xD;&#xA;mastodon =  https://bolha.us&#xD;&#xA;    mastopoet =  https://poet.bolha.us&#xD;&#xA;    elk =  https://elk.bolha.us&#xD;&#xA;    pinafore =  https://pinafore.bolha.us&#xD;&#xA;pixelfed =  https://bolha.photos&#xD;&#xA;lemmy =  https://bolha.social&#xD;&#xA;writefreely =  https://bolha.blog&#xD;&#xA;bookwyrm =  https://bolha.review&#xD;&#xA;funkwhale =  https://bolha.studio&#xD;&#xA;friendica =  https://bolha.network&#xD;&#xA;&#xD;&#xA;Chat and video? We have it!&#xD;&#xA;    &#xD;&#xA;matrix =  https://bolha.chat&#xD;&#xA;jitsi =  https://bolha.video&#xD;&#xA;&#xD;&#xA;Translation tools&#xD;&#xA;&#xD;&#xA; libretranslate =  https://libretranslate.bolha.tools&#xD;&#xA; lingva =  https://translate.bolha.tools&#xD;&#xA;&#xD;&#xA;Video Platform Frontends&#xD;&#xA;&#xD;&#xA; invidious =  https://bolha.in&#xD;&#xA;&#xD;&#xA;Text Editors&#xD;&#xA;&#xD;&#xA; hedgeDoc =  https://notes.bolha.tools&#xD;&#xA; wise Mapping =  https://mindmap.bolha.tools&#xD;&#xA; overleaf =  https://overleaf.bolha.tools&#xD;&#xA; mermaid =  https://mermaid.bolha.tools&#xD;&#xA;&#xD;&#xA;You can also visit our hacking space!&#xD;&#xA;&#xD;&#xA;https://gcn.sh&#xD;&#xA;https://blog.gcn.sh&#xD;&#xA;&#xD;&#xA;Follow our founder!&#xD;&#xA;&#xD;&#xA;https://bolha.us/@gutocarvalho&#xD;&#xA;https://bolha.photos/@gutocarvalho&#xD;&#xA;https://bolha.forum@gutocarvalho&#xD;&#xA;https://bolha.blog/@gutocarvalho&#xD;&#xA;https://bolha.review/@gutocarvalho&#xD;&#xA;https://bolha.studio/@gutocarvalho&#xD;&#xA;https://bolha.network/@gutocarvalho&#xD;&#xA;matrix =  @bolha.chat@gutocarvalho&#xD;&#xA;&#xD;&#xA;Follow the status of our tools&#xD;&#xA;&#xD;&#xA;https://status.bolha.us&#xD;&#xA;&#xD;&#xA;Do you want to support us? You can!&#xD;&#xA;&#xD;&#xA;https://www.patreon.com/bolha&#xD;&#xA;https://apoia.se/bolha&#xD;&#xA;pix@bolha.us (local brazilian wire transfer)&#xD;&#xA;&#xD;&#xA;See you!&#xD;&#xA;&#xD;&#xA;[s]]]&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>

<hr>

<h3 id="did-you-like-our-content" id="did-you-like-our-content">Did you like our content?</h3>

<p>We have a lot to share; visit our site!</p>
<ul><li><a href="https://bolha.io" rel="nofollow">https://bolha.io</a></li></ul>

<p>Our fediverse services ;)</p>
<ul><li>mastodon =&gt; <a href="https://bolha.us" rel="nofollow">https://bolha.us</a>
<ul><li>mastopoet =&gt; <a href="https://poet.bolha.us" rel="nofollow">https://poet.bolha.us</a></li>
<li>elk =&gt; <a href="https://elk.bolha.us" rel="nofollow">https://elk.bolha.us</a></li>
<li>pinafore =&gt; <a href="https://pinafore.bolha.us" rel="nofollow">https://pinafore.bolha.us</a></li></ul></li>
<li>pixelfed =&gt; <a href="https://bolha.photos" rel="nofollow">https://bolha.photos</a></li>
<li>lemmy =&gt; <a href="https://bolha.social" rel="nofollow">https://bolha.social</a></li>
<li>writefreely =&gt; <a href="https://bolha.blog" rel="nofollow">https://bolha.blog</a></li>
<li>bookwyrm =&gt; <a href="https://bolha.review" rel="nofollow">https://bolha.review</a></li>
<li>funkwhale =&gt; <a href="https://bolha.studio" rel="nofollow">https://bolha.studio</a></li>
<li>friendica =&gt; <a href="https://bolha.network" rel="nofollow">https://bolha.network</a></li></ul>

<p>Chat and video? We have it!</p>
<ul><li>matrix =&gt; <a href="https://bolha.chat" rel="nofollow">https://bolha.chat</a></li>
<li>jitsi =&gt; <a href="https://bolha.video" rel="nofollow">https://bolha.video</a></li></ul>

<p>Translation tools</p>
<ul><li>libretranslate =&gt; <a href="https://libretranslate.bolha.tools" rel="nofollow">https://libretranslate.bolha.tools</a></li>
<li>lingva =&gt; <a href="https://translate.bolha.tools" rel="nofollow">https://translate.bolha.tools</a></li></ul>

<p>Video Platform Frontends</p>
<ul><li>invidious =&gt; <a href="https://bolha.in" rel="nofollow">https://bolha.in</a></li></ul>

<p>Text Editors</p>
<ul><li>hedgeDoc =&gt; <a href="https://notes.bolha.tools" rel="nofollow">https://notes.bolha.tools</a></li>
<li>wise Mapping =&gt; <a href="https://mindmap.bolha.tools" rel="nofollow">https://mindmap.bolha.tools</a></li>
<li>overleaf =&gt; <a href="https://overleaf.bolha.tools" rel="nofollow">https://overleaf.bolha.tools</a></li>
<li>mermaid =&gt; <a href="https://mermaid.bolha.tools" rel="nofollow">https://mermaid.bolha.tools</a></li></ul>

<p>You can also visit our hacking space!</p>
<ul><li><a href="https://gcn.sh" rel="nofollow">https://gcn.sh</a></li>
<li><a href="https://blog.gcn.sh" rel="nofollow">https://blog.gcn.sh</a></li></ul>

<p>Follow our founder!</p>
<ul><li><a href="https://bolha.us/@gutocarvalho" rel="nofollow">https://bolha.us/@gutocarvalho</a></li>
<li><a href="https://bolha.photos/@gutocarvalho" rel="nofollow">https://bolha.photos/@gutocarvalho</a></li>
<li><a href="https://bolha.forum@gutocarvalho" rel="nofollow">https://bolha.forum@gutocarvalho</a></li>
<li><a href="https://bolha.blog/@gutocarvalho" rel="nofollow">https://bolha.blog/@gutocarvalho</a></li>
<li><a href="https://bolha.review/@gutocarvalho" rel="nofollow">https://bolha.review/@gutocarvalho</a></li>
<li><a href="https://bolha.studio/@gutocarvalho" rel="nofollow">https://bolha.studio/@gutocarvalho</a></li>
<li><a href="https://bolha.network/@gutocarvalho" rel="nofollow">https://bolha.network/@gutocarvalho</a></li>
<li>matrix =&gt; @bolha.chat@gutocarvalho</li></ul>

<p>Follow the status of our tools</p>
<ul><li><a href="https://status.bolha.us" rel="nofollow">https://status.bolha.us</a></li></ul>

<p>Do you want to support us? You can!</p>
<ul><li><a href="https://www.patreon.com/bolha" rel="nofollow">https://www.patreon.com/bolha</a></li>
<li><a href="https://apoia.se/bolha" rel="nofollow">https://apoia.se/bolha</a></li>
<li>pix@bolha.us (local brazilian wire transfer)</li></ul>

<p>See you!</p>

<p>[s]</p>
]]></content:encoded>
      <guid>https://blog.gcn.sh/howtos/installing-lemmy-0-18-1-with-docker-on-ubuntu</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;:)&#xA;&#xA;hr&#xD;&#xA;Did you like our content?&#xD;&#xA;&#xD;&#xA;We have a lot to share; visit our site!&#xD;&#xA;&#xD;&#xA;https://bolha.io&#xD;&#xA;&#xD;&#xA;Our fediverse services ;)&#xD;&#xA;&#xD;&#xA;mastodon =  https://bolha.us&#xD;&#xA;    mastopoet =  https://poet.bolha.us&#xD;&#xA;    elk =  https://elk.bolha.us&#xD;&#xA;    pinafore =  https://pinafore.bolha.us&#xD;&#xA;pixelfed =  https://bolha.photos&#xD;&#xA;lemmy =  https://bolha.social&#xD;&#xA;writefreely =  https://bolha.blog&#xD;&#xA;bookwyrm =  https://bolha.review&#xD;&#xA;funkwhale =  https://bolha.studio&#xD;&#xA;friendica =  https://bolha.network&#xD;&#xA;&#xD;&#xA;Chat and video? We have it!&#xD;&#xA;    &#xD;&#xA;matrix =  https://bolha.chat&#xD;&#xA;jitsi =  https://bolha.video&#xD;&#xA;&#xD;&#xA;Translation tools&#xD;&#xA;&#xD;&#xA; libretranslate =  https://libretranslate.bolha.tools&#xD;&#xA; lingva =  https://translate.bolha.tools&#xD;&#xA;&#xD;&#xA;Video Platform Frontends&#xD;&#xA;&#xD;&#xA; invidious =  https://bolha.in&#xD;&#xA;&#xD;&#xA;Text Editors&#xD;&#xA;&#xD;&#xA; hedgeDoc =  https://notes.bolha.tools&#xD;&#xA; wise Mapping =  https://mindmap.bolha.tools&#xD;&#xA; overleaf =  https://overleaf.bolha.tools&#xD;&#xA; mermaid =  https://mermaid.bolha.tools&#xD;&#xA;&#xD;&#xA;You can also visit our hacking space!&#xD;&#xA;&#xD;&#xA;https://gcn.sh&#xD;&#xA;https://blog.gcn.sh&#xD;&#xA;&#xD;&#xA;Follow our founder!&#xD;&#xA;&#xD;&#xA;https://bolha.us/@gutocarvalho&#xD;&#xA;https://bolha.photos/@gutocarvalho&#xD;&#xA;https://bolha.forum@gutocarvalho&#xD;&#xA;https://bolha.blog/@gutocarvalho&#xD;&#xA;https://bolha.review/@gutocarvalho&#xD;&#xA;https://bolha.studio/@gutocarvalho&#xD;&#xA;https://bolha.network/@gutocarvalho&#xD;&#xA;matrix =  @bolha.chat@gutocarvalho&#xD;&#xA;&#xD;&#xA;Follow the status of our tools&#xD;&#xA;&#xD;&#xA;https://status.bolha.us&#xD;&#xA;&#xD;&#xA;Do you want to support us? You can!&#xD;&#xA;&#xD;&#xA;https://www.patreon.com/bolha&#xD;&#xA;https://apoia.se/bolha&#xD;&#xA;pix@bolha.us (local brazilian wire transfer)&#xD;&#xA;&#xD;&#xA;See you!&#xD;&#xA;&#xD;&#xA;[s]]]&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>

<hr>

<h3 id="did-you-like-our-content" id="did-you-like-our-content">Did you like our content?</h3>

<p>We have a lot to share; visit our site!</p>
<ul><li><a href="https://bolha.io" rel="nofollow">https://bolha.io</a></li></ul>

<p>Our fediverse services ;)</p>
<ul><li>mastodon =&gt; <a href="https://bolha.us" rel="nofollow">https://bolha.us</a>
<ul><li>mastopoet =&gt; <a href="https://poet.bolha.us" rel="nofollow">https://poet.bolha.us</a></li>
<li>elk =&gt; <a href="https://elk.bolha.us" rel="nofollow">https://elk.bolha.us</a></li>
<li>pinafore =&gt; <a href="https://pinafore.bolha.us" rel="nofollow">https://pinafore.bolha.us</a></li></ul></li>
<li>pixelfed =&gt; <a href="https://bolha.photos" rel="nofollow">https://bolha.photos</a></li>
<li>lemmy =&gt; <a href="https://bolha.social" rel="nofollow">https://bolha.social</a></li>
<li>writefreely =&gt; <a href="https://bolha.blog" rel="nofollow">https://bolha.blog</a></li>
<li>bookwyrm =&gt; <a href="https://bolha.review" rel="nofollow">https://bolha.review</a></li>
<li>funkwhale =&gt; <a href="https://bolha.studio" rel="nofollow">https://bolha.studio</a></li>
<li>friendica =&gt; <a href="https://bolha.network" rel="nofollow">https://bolha.network</a></li></ul>

<p>Chat and video? We have it!</p>
<ul><li>matrix =&gt; <a href="https://bolha.chat" rel="nofollow">https://bolha.chat</a></li>
<li>jitsi =&gt; <a href="https://bolha.video" rel="nofollow">https://bolha.video</a></li></ul>

<p>Translation tools</p>
<ul><li>libretranslate =&gt; <a href="https://libretranslate.bolha.tools" rel="nofollow">https://libretranslate.bolha.tools</a></li>
<li>lingva =&gt; <a href="https://translate.bolha.tools" rel="nofollow">https://translate.bolha.tools</a></li></ul>

<p>Video Platform Frontends</p>
<ul><li>invidious =&gt; <a href="https://bolha.in" rel="nofollow">https://bolha.in</a></li></ul>

<p>Text Editors</p>
<ul><li>hedgeDoc =&gt; <a href="https://notes.bolha.tools" rel="nofollow">https://notes.bolha.tools</a></li>
<li>wise Mapping =&gt; <a href="https://mindmap.bolha.tools" rel="nofollow">https://mindmap.bolha.tools</a></li>
<li>overleaf =&gt; <a href="https://overleaf.bolha.tools" rel="nofollow">https://overleaf.bolha.tools</a></li>
<li>mermaid =&gt; <a href="https://mermaid.bolha.tools" rel="nofollow">https://mermaid.bolha.tools</a></li></ul>

<p>You can also visit our hacking space!</p>
<ul><li><a href="https://gcn.sh" rel="nofollow">https://gcn.sh</a></li>
<li><a href="https://blog.gcn.sh" rel="nofollow">https://blog.gcn.sh</a></li></ul>

<p>Follow our founder!</p>
<ul><li><a href="https://bolha.us/@gutocarvalho" rel="nofollow">https://bolha.us/@gutocarvalho</a></li>
<li><a href="https://bolha.photos/@gutocarvalho" rel="nofollow">https://bolha.photos/@gutocarvalho</a></li>
<li><a href="https://bolha.forum@gutocarvalho" rel="nofollow">https://bolha.forum@gutocarvalho</a></li>
<li><a href="https://bolha.blog/@gutocarvalho" rel="nofollow">https://bolha.blog/@gutocarvalho</a></li>
<li><a href="https://bolha.review/@gutocarvalho" rel="nofollow">https://bolha.review/@gutocarvalho</a></li>
<li><a href="https://bolha.studio/@gutocarvalho" rel="nofollow">https://bolha.studio/@gutocarvalho</a></li>
<li><a href="https://bolha.network/@gutocarvalho" rel="nofollow">https://bolha.network/@gutocarvalho</a></li>
<li>matrix =&gt; @bolha.chat@gutocarvalho</li></ul>

<p>Follow the status of our tools</p>
<ul><li><a href="https://status.bolha.us" rel="nofollow">https://status.bolha.us</a></li></ul>

<p>Do you want to support us? You can!</p>
<ul><li><a href="https://www.patreon.com/bolha" rel="nofollow">https://www.patreon.com/bolha</a></li>
<li><a href="https://apoia.se/bolha" rel="nofollow">https://apoia.se/bolha</a></li>
<li>pix@bolha.us (local brazilian wire transfer)</li></ul>

<p>See you!</p>

<p>[s]</p>
]]></content:encoded>
      <guid>https://blog.gcn.sh/howtos/integrating-mastodon-and-libretranslate</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;hr&#xD;&#xA;Did you like our content?&#xD;&#xA;&#xD;&#xA;We have a lot to share; visit our site!&#xD;&#xA;&#xD;&#xA;https://bolha.io&#xD;&#xA;&#xD;&#xA;Our fediverse services ;)&#xD;&#xA;&#xD;&#xA;mastodon =  https://bolha.us&#xD;&#xA;    mastopoet =  https://poet.bolha.us&#xD;&#xA;    elk =  https://elk.bolha.us&#xD;&#xA;    pinafore =  https://pinafore.bolha.us&#xD;&#xA;pixelfed =  https://bolha.photos&#xD;&#xA;lemmy =  https://bolha.social&#xD;&#xA;writefreely =  https://bolha.blog&#xD;&#xA;bookwyrm =  https://bolha.review&#xD;&#xA;funkwhale =  https://bolha.studio&#xD;&#xA;friendica =  https://bolha.network&#xD;&#xA;&#xD;&#xA;Chat and video? We have it!&#xD;&#xA;    &#xD;&#xA;matrix =  https://bolha.chat&#xD;&#xA;jitsi =  https://bolha.video&#xD;&#xA;&#xD;&#xA;Translation tools&#xD;&#xA;&#xD;&#xA; libretranslate =  https://libretranslate.bolha.tools&#xD;&#xA; lingva =  https://translate.bolha.tools&#xD;&#xA;&#xD;&#xA;Video Platform Frontends&#xD;&#xA;&#xD;&#xA; invidious =  https://bolha.in&#xD;&#xA;&#xD;&#xA;Text Editors&#xD;&#xA;&#xD;&#xA; hedgeDoc =  https://notes.bolha.tools&#xD;&#xA; wise Mapping =  https://mindmap.bolha.tools&#xD;&#xA; overleaf =  https://overleaf.bolha.tools&#xD;&#xA; mermaid =  https://mermaid.bolha.tools&#xD;&#xA;&#xD;&#xA;You can also visit our hacking space!&#xD;&#xA;&#xD;&#xA;https://gcn.sh&#xD;&#xA;https://blog.gcn.sh&#xD;&#xA;&#xD;&#xA;Follow our founder!&#xD;&#xA;&#xD;&#xA;https://bolha.us/@gutocarvalho&#xD;&#xA;https://bolha.photos/@gutocarvalho&#xD;&#xA;https://bolha.forum@gutocarvalho&#xD;&#xA;https://bolha.blog/@gutocarvalho&#xD;&#xA;https://bolha.review/@gutocarvalho&#xD;&#xA;https://bolha.studio/@gutocarvalho&#xD;&#xA;https://bolha.network/@gutocarvalho&#xD;&#xA;matrix =  @bolha.chat@gutocarvalho&#xD;&#xA;&#xD;&#xA;Follow the status of our tools&#xD;&#xA;&#xD;&#xA;https://status.bolha.us&#xD;&#xA;&#xD;&#xA;Do you want to support us? You can!&#xD;&#xA;&#xD;&#xA;https://www.patreon.com/bolha&#xD;&#xA;https://apoia.se/bolha&#xD;&#xA;pix@bolha.us (local brazilian wire transfer)&#xD;&#xA;&#xD;&#xA;See you!&#xD;&#xA;&#xD;&#xA;[s]]]&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>

<hr>

<h3 id="did-you-like-our-content" id="did-you-like-our-content">Did you like our content?</h3>

<p>We have a lot to share; visit our site!</p>
<ul><li><a href="https://bolha.io" rel="nofollow">https://bolha.io</a></li></ul>

<p>Our fediverse services ;)</p>
<ul><li>mastodon =&gt; <a href="https://bolha.us" rel="nofollow">https://bolha.us</a>
<ul><li>mastopoet =&gt; <a href="https://poet.bolha.us" rel="nofollow">https://poet.bolha.us</a></li>
<li>elk =&gt; <a href="https://elk.bolha.us" rel="nofollow">https://elk.bolha.us</a></li>
<li>pinafore =&gt; <a href="https://pinafore.bolha.us" rel="nofollow">https://pinafore.bolha.us</a></li></ul></li>
<li>pixelfed =&gt; <a href="https://bolha.photos" rel="nofollow">https://bolha.photos</a></li>
<li>lemmy =&gt; <a href="https://bolha.social" rel="nofollow">https://bolha.social</a></li>
<li>writefreely =&gt; <a href="https://bolha.blog" rel="nofollow">https://bolha.blog</a></li>
<li>bookwyrm =&gt; <a href="https://bolha.review" rel="nofollow">https://bolha.review</a></li>
<li>funkwhale =&gt; <a href="https://bolha.studio" rel="nofollow">https://bolha.studio</a></li>
<li>friendica =&gt; <a href="https://bolha.network" rel="nofollow">https://bolha.network</a></li></ul>

<p>Chat and video? We have it!</p>
<ul><li>matrix =&gt; <a href="https://bolha.chat" rel="nofollow">https://bolha.chat</a></li>
<li>jitsi =&gt; <a href="https://bolha.video" rel="nofollow">https://bolha.video</a></li></ul>

<p>Translation tools</p>
<ul><li>libretranslate =&gt; <a href="https://libretranslate.bolha.tools" rel="nofollow">https://libretranslate.bolha.tools</a></li>
<li>lingva =&gt; <a href="https://translate.bolha.tools" rel="nofollow">https://translate.bolha.tools</a></li></ul>

<p>Video Platform Frontends</p>
<ul><li>invidious =&gt; <a href="https://bolha.in" rel="nofollow">https://bolha.in</a></li></ul>

<p>Text Editors</p>
<ul><li>hedgeDoc =&gt; <a href="https://notes.bolha.tools" rel="nofollow">https://notes.bolha.tools</a></li>
<li>wise Mapping =&gt; <a href="https://mindmap.bolha.tools" rel="nofollow">https://mindmap.bolha.tools</a></li>
<li>overleaf =&gt; <a href="https://overleaf.bolha.tools" rel="nofollow">https://overleaf.bolha.tools</a></li>
<li>mermaid =&gt; <a href="https://mermaid.bolha.tools" rel="nofollow">https://mermaid.bolha.tools</a></li></ul>

<p>You can also visit our hacking space!</p>
<ul><li><a href="https://gcn.sh" rel="nofollow">https://gcn.sh</a></li>
<li><a href="https://blog.gcn.sh" rel="nofollow">https://blog.gcn.sh</a></li></ul>

<p>Follow our founder!</p>
<ul><li><a href="https://bolha.us/@gutocarvalho" rel="nofollow">https://bolha.us/@gutocarvalho</a></li>
<li><a href="https://bolha.photos/@gutocarvalho" rel="nofollow">https://bolha.photos/@gutocarvalho</a></li>
<li><a href="https://bolha.forum@gutocarvalho" rel="nofollow">https://bolha.forum@gutocarvalho</a></li>
<li><a href="https://bolha.blog/@gutocarvalho" rel="nofollow">https://bolha.blog/@gutocarvalho</a></li>
<li><a href="https://bolha.review/@gutocarvalho" rel="nofollow">https://bolha.review/@gutocarvalho</a></li>
<li><a href="https://bolha.studio/@gutocarvalho" rel="nofollow">https://bolha.studio/@gutocarvalho</a></li>
<li><a href="https://bolha.network/@gutocarvalho" rel="nofollow">https://bolha.network/@gutocarvalho</a></li>
<li>matrix =&gt; @bolha.chat@gutocarvalho</li></ul>

<p>Follow the status of our tools</p>
<ul><li><a href="https://status.bolha.us" rel="nofollow">https://status.bolha.us</a></li></ul>

<p>Do you want to support us? You can!</p>
<ul><li><a href="https://www.patreon.com/bolha" rel="nofollow">https://www.patreon.com/bolha</a></li>
<li><a href="https://apoia.se/bolha" rel="nofollow">https://apoia.se/bolha</a></li>
<li>pix@bolha.us (local brazilian wire transfer)</li></ul>

<p>See you!</p>

<p>[s]</p>
]]></content:encoded>
      <guid>https://blog.gcn.sh/howtos/installing-libretranslate-using-docker-and-ubuntu</guid>
      <pubDate>Wed, 05 Jul 2023 00:39:07 +0000</pubDate>
    </item>
    <item>
      <title>Installing dokuwiki using Docker and Ubuntu</title>
      <link>https://blog.gcn.sh/howtos/installing-dokuwiki-using-docker-and-ubuntu</link>
      <description>&lt;![CDATA[Why?&#xA;&#xA;We need to organize our docs and information about the gcn and bolha collective and dokuwiki is the best wiki because we don&#39;t need a database, it&#39;s a flatfile system.&#xA;&#xA;Fast, flexible and easy to backup.&#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://www.dokuwiki.org/dokuwiki&#xA;https://hub.docker.com/r/linuxserver/dokuwiki&#xA;&#xA;How I can install it?&#xA;&#xA;first, let&#39;s create the directories&#xA;&#xA;mkdir -p /opt/dokuwiki/docker&#xA;mkdir -p /opt/dokuwiki/data&#xA;&#xA;then, let&#39;s create the docker-compose file&#xA;&#xA;cd /opt/dokuwiki/docker&#xA;vim docker-compose.yaml&#xA;&#xA;here follows the content, change the parameters for you setup&#xA;&#xA;version: &#39;3&#39;&#xA;services:&#xA;  dokuwiki:&#xA;    image: lscr.io/linuxserver/dokuwiki:latest&#xA;    containername: dokuwiki&#xA;    environment:&#xA;      PUID=1000&#xA;      PGID=1000&#xA;      TZ=Etc/UTC&#xA;    volumes:&#xA;      dokuwikiconfig:/config&#xA;    ports:&#xA;      8081:80&#xA;    restart: unless-stopped&#xA;&#xA;volumes:&#xA;  dokuwikiconfig:&#xA;    driveropts:&#xA;      type: none&#xA;      device: /opt/dokuwiki/data&#xA;      o: bind&#xA;&#xA;all right, let&#39;s spin up the dokuwiki&#xA;&#xA;docker-compose up -d&#xA;&#xA;No finish the configuration using the web browser&#xA;&#xA;    https://dokuwiki.domain.tld/install.php&#xA;&#xA;external nginx&#xA;&#xA;In our case, Dokuwiki is behind an External NGINX Reverse Proxy.&#xA;&#xA;Here follow the config snippet used&#xA;&#xA;upstream dokuwiki {&#xA;    server yourdockerhostip:yourdokuwikiport failtimeout=0;&#xA;}&#xA;&#xA;server {&#xA;  listen 144.217.95.91:80;&#xA;  servername dokuwiki.domain.tld;&#xA;  return 301 https://dokuwkrequesturi;&#xA;}&#xA;&#xA;server {&#xA;&#xA;  listen 144.217.95.91:443 ssl http2;&#xA;  servername dokuwiki.domain.tld;&#xA;&#xA;  accesslog /var/log/nginx/dokuwiki-domain-tld.log;&#xA;  errorlog /var/log/nginx/dokuwiki-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;    proxy_pass http://dokuwiki;&#xA;  }&#xA;&#xA;}&#xA;&#xA;That&#39;s it :)&#xA;&#xA;[s]&#xA;&#xA;hr&#xD;&#xA;Did you like our content?&#xD;&#xA;&#xD;&#xA;We have a lot to share; visit our site!&#xD;&#xA;&#xD;&#xA;https://bolha.io&#xD;&#xA;&#xD;&#xA;Our fediverse services ;)&#xD;&#xA;&#xD;&#xA;mastodon =  https://bolha.us&#xD;&#xA;    mastopoet =  https://poet.bolha.us&#xD;&#xA;    elk =  https://elk.bolha.us&#xD;&#xA;    pinafore =  https://pinafore.bolha.us&#xD;&#xA;pixelfed =  https://bolha.photos&#xD;&#xA;lemmy =  https://bolha.social&#xD;&#xA;writefreely =  https://bolha.blog&#xD;&#xA;bookwyrm =  https://bolha.review&#xD;&#xA;funkwhale =  https://bolha.studio&#xD;&#xA;friendica =  https://bolha.network&#xD;&#xA;&#xD;&#xA;Chat and video? We have it!&#xD;&#xA;    &#xD;&#xA;matrix =  https://bolha.chat&#xD;&#xA;jitsi =  https://bolha.video&#xD;&#xA;&#xD;&#xA;Translation tools&#xD;&#xA;&#xD;&#xA; libretranslate =  https://libretranslate.bolha.tools&#xD;&#xA; lingva =  https://translate.bolha.tools&#xD;&#xA;&#xD;&#xA;Video Platform Frontends&#xD;&#xA;&#xD;&#xA; invidious =  https://bolha.in&#xD;&#xA;&#xD;&#xA;Text Editors&#xD;&#xA;&#xD;&#xA; hedgeDoc =  https://notes.bolha.tools&#xD;&#xA; wise Mapping =  https://mindmap.bolha.tools&#xD;&#xA; overleaf =  https://overleaf.bolha.tools&#xD;&#xA; mermaid =  https://mermaid.bolha.tools&#xD;&#xA;&#xD;&#xA;You can also visit our hacking space!&#xD;&#xA;&#xD;&#xA;https://gcn.sh&#xD;&#xA;https://blog.gcn.sh&#xD;&#xA;&#xD;&#xA;Follow our founder!&#xD;&#xA;&#xD;&#xA;https://bolha.us/@gutocarvalho&#xD;&#xA;https://bolha.photos/@gutocarvalho&#xD;&#xA;https://bolha.forum@gutocarvalho&#xD;&#xA;https://bolha.blog/@gutocarvalho&#xD;&#xA;https://bolha.review/@gutocarvalho&#xD;&#xA;https://bolha.studio/@gutocarvalho&#xD;&#xA;https://bolha.network/@gutocarvalho&#xD;&#xA;matrix =  @bolha.chat@gutocarvalho&#xD;&#xA;&#xD;&#xA;Follow the status of our tools&#xD;&#xA;&#xD;&#xA;https://status.bolha.us&#xD;&#xA;&#xD;&#xA;Do you want to support us? You can!&#xD;&#xA;&#xD;&#xA;https://www.patreon.com/bolha&#xD;&#xA;https://apoia.se/bolha&#xD;&#xA;pix@bolha.us (local brazilian wire transfer)&#xD;&#xA;&#xD;&#xA;See you!&#xD;&#xA;&#xD;&#xA;[s]]]&gt;</description>
      <content:encoded><![CDATA[<h2 id="why" id="why">Why?</h2>

<p>We need to organize our docs and information about the gcn and bolha collective and dokuwiki is the best wiki because we don&#39;t need a database, it&#39;s a flatfile system.</p>

<p>Fast, flexible and easy to backup.</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://www.dokuwiki.org/dokuwiki" rel="nofollow">https://www.dokuwiki.org/dokuwiki</a></li>
<li><a href="https://hub.docker.com/r/linuxserver/dokuwiki" rel="nofollow">https://hub.docker.com/r/linuxserver/dokuwiki</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/dokuwiki/docker
mkdir -p /opt/dokuwiki/data
</code></pre>

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

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

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

<pre><code>version: &#39;3&#39;
services:
  dokuwiki:
    image: lscr.io/linuxserver/dokuwiki:latest
    container_name: dokuwiki
    environment:
      - PUID=1000
      - PGID=1000
      - TZ=Etc/UTC
    volumes:
      - dokuwiki_config:/config
    ports:
      - 8081:80
    restart: unless-stopped

volumes:
  dokuwiki_config:
    driver_opts:
      type: none
      device: /opt/dokuwiki/data
      o: bind
</code></pre>

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

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

<p>No finish the configuration using the web browser</p>

<p>    <a href="https://dokuwiki.domain.tld/install.php" rel="nofollow">https://dokuwiki.domain.tld/install.php</a></p>

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

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

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

<pre><code>upstream dokuwiki {
    server your_docker_host_ip:your_dokuwiki_port fail_timeout=0;
}

server {
  listen 144.217.95.91:80;
  server_name dokuwiki.domain.tld;
  return 301 https://dokuwkrequest_uri;
}

server {

  listen 144.217.95.91:443 ssl http2;
  server_name dokuwiki.domain.tld;

  access_log /var/log/nginx/dokuwiki-domain-tld.log;
  error_log /var/log/nginx/dokuwiki-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://dokuwiki;
  }

}
</code></pre>

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

<p>[s]</p>

<hr>

<h3 id="did-you-like-our-content" id="did-you-like-our-content">Did you like our content?</h3>

<p>We have a lot to share; visit our site!</p>
<ul><li><a href="https://bolha.io" rel="nofollow">https://bolha.io</a></li></ul>

<p>Our fediverse services ;)</p>
<ul><li>mastodon =&gt; <a href="https://bolha.us" rel="nofollow">https://bolha.us</a>
<ul><li>mastopoet =&gt; <a href="https://poet.bolha.us" rel="nofollow">https://poet.bolha.us</a></li>
<li>elk =&gt; <a href="https://elk.bolha.us" rel="nofollow">https://elk.bolha.us</a></li>
<li>pinafore =&gt; <a href="https://pinafore.bolha.us" rel="nofollow">https://pinafore.bolha.us</a></li></ul></li>
<li>pixelfed =&gt; <a href="https://bolha.photos" rel="nofollow">https://bolha.photos</a></li>
<li>lemmy =&gt; <a href="https://bolha.social" rel="nofollow">https://bolha.social</a></li>
<li>writefreely =&gt; <a href="https://bolha.blog" rel="nofollow">https://bolha.blog</a></li>
<li>bookwyrm =&gt; <a href="https://bolha.review" rel="nofollow">https://bolha.review</a></li>
<li>funkwhale =&gt; <a href="https://bolha.studio" rel="nofollow">https://bolha.studio</a></li>
<li>friendica =&gt; <a href="https://bolha.network" rel="nofollow">https://bolha.network</a></li></ul>

<p>Chat and video? We have it!</p>
<ul><li>matrix =&gt; <a href="https://bolha.chat" rel="nofollow">https://bolha.chat</a></li>
<li>jitsi =&gt; <a href="https://bolha.video" rel="nofollow">https://bolha.video</a></li></ul>

<p>Translation tools</p>
<ul><li>libretranslate =&gt; <a href="https://libretranslate.bolha.tools" rel="nofollow">https://libretranslate.bolha.tools</a></li>
<li>lingva =&gt; <a href="https://translate.bolha.tools" rel="nofollow">https://translate.bolha.tools</a></li></ul>

<p>Video Platform Frontends</p>
<ul><li>invidious =&gt; <a href="https://bolha.in" rel="nofollow">https://bolha.in</a></li></ul>

<p>Text Editors</p>
<ul><li>hedgeDoc =&gt; <a href="https://notes.bolha.tools" rel="nofollow">https://notes.bolha.tools</a></li>
<li>wise Mapping =&gt; <a href="https://mindmap.bolha.tools" rel="nofollow">https://mindmap.bolha.tools</a></li>
<li>overleaf =&gt; <a href="https://overleaf.bolha.tools" rel="nofollow">https://overleaf.bolha.tools</a></li>
<li>mermaid =&gt; <a href="https://mermaid.bolha.tools" rel="nofollow">https://mermaid.bolha.tools</a></li></ul>

<p>You can also visit our hacking space!</p>
<ul><li><a href="https://gcn.sh" rel="nofollow">https://gcn.sh</a></li>
<li><a href="https://blog.gcn.sh" rel="nofollow">https://blog.gcn.sh</a></li></ul>

<p>Follow our founder!</p>
<ul><li><a href="https://bolha.us/@gutocarvalho" rel="nofollow">https://bolha.us/@gutocarvalho</a></li>
<li><a href="https://bolha.photos/@gutocarvalho" rel="nofollow">https://bolha.photos/@gutocarvalho</a></li>
<li><a href="https://bolha.forum@gutocarvalho" rel="nofollow">https://bolha.forum@gutocarvalho</a></li>
<li><a href="https://bolha.blog/@gutocarvalho" rel="nofollow">https://bolha.blog/@gutocarvalho</a></li>
<li><a href="https://bolha.review/@gutocarvalho" rel="nofollow">https://bolha.review/@gutocarvalho</a></li>
<li><a href="https://bolha.studio/@gutocarvalho" rel="nofollow">https://bolha.studio/@gutocarvalho</a></li>
<li><a href="https://bolha.network/@gutocarvalho" rel="nofollow">https://bolha.network/@gutocarvalho</a></li>
<li>matrix =&gt; @bolha.chat@gutocarvalho</li></ul>

<p>Follow the status of our tools</p>
<ul><li><a href="https://status.bolha.us" rel="nofollow">https://status.bolha.us</a></li></ul>

<p>Do you want to support us? You can!</p>
<ul><li><a href="https://www.patreon.com/bolha" rel="nofollow">https://www.patreon.com/bolha</a></li>
<li><a href="https://apoia.se/bolha" rel="nofollow">https://apoia.se/bolha</a></li>
<li>pix@bolha.us (local brazilian wire transfer)</li></ul>

<p>See you!</p>

<p>[s]</p>
]]></content:encoded>
      <guid>https://blog.gcn.sh/howtos/installing-dokuwiki-using-docker-and-ubuntu</guid>
      <pubDate>Sun, 02 Jul 2023 14:43:30 +0000</pubDate>
    </item>
    <item>
      <title>Installing passbolt using Docker and Ubuntu</title>
      <link>https://blog.gcn.sh/howtos/installing-passbolt-using-docker-and-ubuntu</link>
      <description>&lt;![CDATA[Why?&#xA;&#xA;I like to have my own password manager, self-hosted, I trust only myself :)&#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://www.passbolt.com&#xA;https://hub.docker.com/r/passbolt/passbolt/&#xA;https://www.passbolt.com/ce/docker&#xA;&#xA;How I can install it?&#xA;&#xA;first, let&#39;s create the directories&#xA;&#xA;mkdir -p /opt/passbolt/docker&#xA;mkdir -p /opt/passbolt/data/{database,gpg,jwt}&#xA;&#xA;then, let&#39;s create the docker-compose file&#xA;&#xA;cd /opt/passbolt/docker&#xA;vim docker-compose.yaml&#xA;&#xA;here follows the content, change the parameters for you setup&#xA;&#xA;version: &#34;3.9&#34;&#xA;services:&#xA;  db:&#xA;    image: mariadb:10.11&#xA;    restart: unless-stopped&#xA;    environment:&#xA;      MYSQLRANDOMROOTPASSWORD: &#34;true&#34;&#xA;      MYSQLDATABASE: &#34;passbolt&#34;&#xA;      MYSQLUSER: &#34;passbolt&#34;&#xA;      MYSQLPASSWORD: &#34;yourmysqlpasswordhere&#34;&#xA;    volumes:&#xA;      databasevolume:/var/lib/mysql&#xA;&#xA;  passbolt:&#xA;    image: passbolt/passbolt:latest-ce&#xA;    #Alternatively you can use rootless:&#xA;    #image: passbolt/passbolt:latest-ce-non-root&#xA;    restart: unless-stopped&#xA;    dependson:&#xA;      db&#xA;    environment:&#xA;      DATASOURCESDEFAULTHOST: &#34;db&#34;&#xA;      DATASOURCESDEFAULTUSERNAME: &#34;passbolt&#34;&#xA;      DATASOURCESDEFAULTPASSWORD: &#34;yourmysqlpasswordhere&#34;&#xA;      DATASOURCESDEFAULTDATABASE: &#34;passbolt&#34;&#xA;      APPFULLBASEURL: https://passbolt.domain.tld&#xA;      EMAILDEFAULTFROM: passbolt@domain.tld&#xA;      EMAILTRANSPORTDEFAULTHOST: mail.domain.tld&#xA;      EMAILTRANSPORTDEFAULTPORT: 587&#xA;      EMAILTRANSPORTDEFAULTUSERNAME: user@domain.tld&#xA;      EMAILTRANSPORTDEFAULTPASSWORD: userpasswordhere&#xA;      EMAILTRANSPORTDEFAULTTLS: true&#xA;      PASSBOLTKEYEMAIL: passbolt@domain.tld&#xA;&#xA;    volumes:&#xA;      gpgvolume:/etc/passbolt/gpg&#xA;      jwtvolume:/etc/passbolt/jwt&#xA;    command:&#xA;      [&#xA;        &#34;/usr/bin/wait-for.sh&#34;,&#xA;        &#34;-t&#34;,&#xA;        &#34;0&#34;,&#xA;        &#34;db:3306&#34;,&#xA;        &#34;--&#34;,&#xA;        &#34;/docker-entrypoint.sh&#34;,&#xA;      ]&#xA;    ports:&#xA;      80:80&#xA;&#xA;volumes:&#xA;  databasevolume:&#xA;    driveropts:&#xA;      type: none&#xA;      device: /opt/passbolt/data/database&#xA;      o: bind&#xA;  gpgvolume:&#xA;    driveropts:&#xA;      type: none&#xA;      device: /opt/passbolt/data/gpg&#xA;      o: bind&#xA;  jwtvolume:&#xA;    driveropts:&#xA;      type: none&#xA;      device: /opt/passbolt/data/jwt&#xA;      o: bind&#xA;&#xA;all right, let&#39;s spin up the passbolt&#xA;&#xA;docker-compose up -d&#xA;&#xA;now let&#39;s test the e-mail configuration, we cannot create our user without a working e-mail relay.&#xA;&#xA;docker-compose exec passbolt su -m -c &#34;bin/cake passbolt sendtestemail -r user@domain.tld&#34;&#xA;&#xA;if you got the e-mail, it&#39;s time to create the first admin user&#xA;&#xA;docker-compose exec passbolt su -m -c &#34;bin/cake passbolt registeruser -u user@domain.tld -f Guto -l Carvalho -r admin&#34; -s /bin/sh www-data&#xA;&#xA;output expected&#xA;&#xA;                                 &#xA;    /  \   _/ /  ___  / / /&#xA;   / // /  `/ / /  \/  \/ / /&#xA;  / __/ // (  |  ) // / // / / /&#xA; //    \,/_//./\//\_/&#xA;&#xA; Open source password manager for teams&#xA;-------------------------------------------------------------------------------&#xA;User saved successfully.&#xA;To start registration follow the link provided in your mailbox or here:&#xA;https://passbolt.domain.tld/setup/install/1111111-8d5c-43a7-8fc2-301403b93766/efd71548-bcb4-4d58-b98d-a6877799d548&#xA;&#xA;Now you can access your Passbolt and finish the configuration!&#xA;&#xA;external nginx&#xA;&#xA;In our case, Passbolt is behind an External NGINX Reserve Proxy.&#xA;&#xA;Here follow the config snippet used&#xA;&#xA;upstream passbolt {&#xA;    server yourpassboltdockerserveriphere:yourporthere failtimeout=0;&#xA;}&#xA;&#xA;server {&#xA;  listen yournginxlisteniphere:80;&#xA;  servername passbolt.domain.tld;&#xA;  return 301 https://passbolt.domain.tld$requesturi;&#xA;}&#xA;&#xA;server {&#xA;&#xA;  listen yournginxlisteniphere:443 ssl http2;&#xA;  servername passbolt.domain.tld;&#xA;&#xA;  accesslog /var/log/nginx/passbolt-domain-tld.log;&#xA;  errorlog /var/log/nginx/passbolt-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://passbolt;&#xA;  }&#xA;&#xA;}&#xA;&#xA;That&#39;s it :)&#xA;&#xA;[s]&#xA;&#xA;hr&#xD;&#xA;Did you like our content?&#xD;&#xA;&#xD;&#xA;We have a lot to share; visit our site!&#xD;&#xA;&#xD;&#xA;https://bolha.io&#xD;&#xA;&#xD;&#xA;Our fediverse services ;)&#xD;&#xA;&#xD;&#xA;mastodon =  https://bolha.us&#xD;&#xA;    mastopoet =  https://poet.bolha.us&#xD;&#xA;    elk =  https://elk.bolha.us&#xD;&#xA;    pinafore =  https://pinafore.bolha.us&#xD;&#xA;pixelfed =  https://bolha.photos&#xD;&#xA;lemmy =  https://bolha.social&#xD;&#xA;writefreely =  https://bolha.blog&#xD;&#xA;bookwyrm =  https://bolha.review&#xD;&#xA;funkwhale =  https://bolha.studio&#xD;&#xA;friendica =  https://bolha.network&#xD;&#xA;&#xD;&#xA;Chat and video? We have it!&#xD;&#xA;    &#xD;&#xA;matrix =  https://bolha.chat&#xD;&#xA;jitsi =  https://bolha.video&#xD;&#xA;&#xD;&#xA;Translation tools&#xD;&#xA;&#xD;&#xA; libretranslate =  https://libretranslate.bolha.tools&#xD;&#xA; lingva =  https://translate.bolha.tools&#xD;&#xA;&#xD;&#xA;Video Platform Frontends&#xD;&#xA;&#xD;&#xA; invidious =  https://bolha.in&#xD;&#xA;&#xD;&#xA;Text Editors&#xD;&#xA;&#xD;&#xA; hedgeDoc =  https://notes.bolha.tools&#xD;&#xA; wise Mapping =  https://mindmap.bolha.tools&#xD;&#xA; overleaf =  https://overleaf.bolha.tools&#xD;&#xA; mermaid =  https://mermaid.bolha.tools&#xD;&#xA;&#xD;&#xA;You can also visit our hacking space!&#xD;&#xA;&#xD;&#xA;https://gcn.sh&#xD;&#xA;https://blog.gcn.sh&#xD;&#xA;&#xD;&#xA;Follow our founder!&#xD;&#xA;&#xD;&#xA;https://bolha.us/@gutocarvalho&#xD;&#xA;https://bolha.photos/@gutocarvalho&#xD;&#xA;https://bolha.forum@gutocarvalho&#xD;&#xA;https://bolha.blog/@gutocarvalho&#xD;&#xA;https://bolha.review/@gutocarvalho&#xD;&#xA;https://bolha.studio/@gutocarvalho&#xD;&#xA;https://bolha.network/@gutocarvalho&#xD;&#xA;matrix =  @bolha.chat@gutocarvalho&#xD;&#xA;&#xD;&#xA;Follow the status of our tools&#xD;&#xA;&#xD;&#xA;https://status.bolha.us&#xD;&#xA;&#xD;&#xA;Do you want to support us? You can!&#xD;&#xA;&#xD;&#xA;https://www.patreon.com/bolha&#xD;&#xA;https://apoia.se/bolha&#xD;&#xA;pix@bolha.us (local brazilian wire transfer)&#xD;&#xA;&#xD;&#xA;See you!&#xD;&#xA;&#xD;&#xA;[s]]]&gt;</description>
      <content:encoded><![CDATA[<h2 id="why" id="why">Why?</h2>

<p>I like to have my own password manager, self-hosted, I trust only myself :)</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://www.passbolt.com" rel="nofollow">https://www.passbolt.com</a></li>
<li><a href="https://hub.docker.com/r/passbolt/passbolt/" rel="nofollow">https://hub.docker.com/r/passbolt/passbolt/</a></li>
<li><a href="https://www.passbolt.com/ce/docker" rel="nofollow">https://www.passbolt.com/ce/docker</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/passbolt/docker
mkdir -p /opt/passbolt/data/{database,gpg,jwt}
</code></pre>

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

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

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

<pre><code>version: &#34;3.9&#34;
services:
  db:
    image: mariadb:10.11
    restart: unless-stopped
    environment:
      MYSQL_RANDOM_ROOT_PASSWORD: &#34;true&#34;
      MYSQL_DATABASE: &#34;passbolt&#34;
      MYSQL_USER: &#34;passbolt&#34;
      MYSQL_PASSWORD: &#34;your_mysql_password_here&#34;
    volumes:
      - database_volume:/var/lib/mysql

  passbolt:
    image: passbolt/passbolt:latest-ce
    #Alternatively you can use rootless:
    #image: passbolt/passbolt:latest-ce-non-root
    restart: unless-stopped
    depends_on:
      - db
    environment:
      DATASOURCES_DEFAULT_HOST: &#34;db&#34;
      DATASOURCES_DEFAULT_USERNAME: &#34;passbolt&#34;
      DATASOURCES_DEFAULT_PASSWORD: &#34;your_mysql_password_here&#34;
      DATASOURCES_DEFAULT_DATABASE: &#34;passbolt&#34;
      APP_FULL_BASE_URL: https://passbolt.domain.tld
      EMAIL_DEFAULT_FROM: passbolt@domain.tld
      EMAIL_TRANSPORT_DEFAULT_HOST: mail.domain.tld
      EMAIL_TRANSPORT_DEFAULT_PORT: 587
      EMAIL_TRANSPORT_DEFAULT_USERNAME: user@domain.tld
      EMAIL_TRANSPORT_DEFAULT_PASSWORD: user_password_here
      EMAIL_TRANSPORT_DEFAULT_TLS: true
      PASSBOLT_KEY_EMAIL: passbolt@domain.tld

    volumes:
      - gpg_volume:/etc/passbolt/gpg
      - jwt_volume:/etc/passbolt/jwt
    command:
      [
        &#34;/usr/bin/wait-for.sh&#34;,
        &#34;-t&#34;,
        &#34;0&#34;,
        &#34;db:3306&#34;,
        &#34;--&#34;,
        &#34;/docker-entrypoint.sh&#34;,
      ]
    ports:
      - 80:80

volumes:
  database_volume:
    driver_opts:
      type: none
      device: /opt/passbolt/data/database
      o: bind
  gpg_volume:
    driver_opts:
      type: none
      device: /opt/passbolt/data/gpg
      o: bind
  jwt_volume:
    driver_opts:
      type: none
      device: /opt/passbolt/data/jwt
      o: bind
</code></pre>

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

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

<p>now let&#39;s test the e-mail configuration, we cannot create our user without a working e-mail relay.</p>

<pre><code>docker-compose exec passbolt su -m -c &#34;bin/cake passbolt send_test_email -r user@domain.tld&#34;
</code></pre>

<p>if you got the e-mail, it&#39;s time to create the first admin user</p>

<pre><code>docker-compose exec passbolt su -m -c &#34;bin/cake passbolt register_user -u user@domain.tld -f Guto -l Carvalho -r admin&#34; -s /bin/sh www-data
</code></pre>

<p>output expected</p>

<pre><code>     ____                  __          ____
    / __ \____  _____ ____/ /_  ____  / / /_
   / /_/ / __ `/ ___/ ___/ __ \/ __ \/ / __/
  / ____/ /_/ (__  |__  ) /_/ / /_/ / / /
 /_/    \__,_/____/____/_.___/\____/_/\__/

 Open source password manager for teams
-------------------------------------------------------------------------------
User saved successfully.
To start registration follow the link provided in your mailbox or here:
https://passbolt.domain.tld/setup/install/1111111-8d5c-43a7-8fc2-301403b93766/efd71548-bcb4-4d58-b98d-a6877799d548
</code></pre>

<p>Now you can access your Passbolt and finish the configuration!</p>

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

<p>In our case, Passbolt is behind an External NGINX Reserve Proxy.</p>

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

<pre><code>upstream passbolt {
    server your_passbolt_docker_server_ip_here:your_port_here fail_timeout=0;
}

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

server {

  listen your_nginx_listen_ip_here:443 ssl http2;
  server_name passbolt.domain.tld;

  access_log /var/log/nginx/passbolt-domain-tld.log;
  error_log /var/log/nginx/passbolt-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://passbolt;
  }

}
</code></pre>

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

<p>[s]</p>

<hr>

<h3 id="did-you-like-our-content" id="did-you-like-our-content">Did you like our content?</h3>

<p>We have a lot to share; visit our site!</p>
<ul><li><a href="https://bolha.io" rel="nofollow">https://bolha.io</a></li></ul>

<p>Our fediverse services ;)</p>
<ul><li>mastodon =&gt; <a href="https://bolha.us" rel="nofollow">https://bolha.us</a>
<ul><li>mastopoet =&gt; <a href="https://poet.bolha.us" rel="nofollow">https://poet.bolha.us</a></li>
<li>elk =&gt; <a href="https://elk.bolha.us" rel="nofollow">https://elk.bolha.us</a></li>
<li>pinafore =&gt; <a href="https://pinafore.bolha.us" rel="nofollow">https://pinafore.bolha.us</a></li></ul></li>
<li>pixelfed =&gt; <a href="https://bolha.photos" rel="nofollow">https://bolha.photos</a></li>
<li>lemmy =&gt; <a href="https://bolha.social" rel="nofollow">https://bolha.social</a></li>
<li>writefreely =&gt; <a href="https://bolha.blog" rel="nofollow">https://bolha.blog</a></li>
<li>bookwyrm =&gt; <a href="https://bolha.review" rel="nofollow">https://bolha.review</a></li>
<li>funkwhale =&gt; <a href="https://bolha.studio" rel="nofollow">https://bolha.studio</a></li>
<li>friendica =&gt; <a href="https://bolha.network" rel="nofollow">https://bolha.network</a></li></ul>

<p>Chat and video? We have it!</p>
<ul><li>matrix =&gt; <a href="https://bolha.chat" rel="nofollow">https://bolha.chat</a></li>
<li>jitsi =&gt; <a href="https://bolha.video" rel="nofollow">https://bolha.video</a></li></ul>

<p>Translation tools</p>
<ul><li>libretranslate =&gt; <a href="https://libretranslate.bolha.tools" rel="nofollow">https://libretranslate.bolha.tools</a></li>
<li>lingva =&gt; <a href="https://translate.bolha.tools" rel="nofollow">https://translate.bolha.tools</a></li></ul>

<p>Video Platform Frontends</p>
<ul><li>invidious =&gt; <a href="https://bolha.in" rel="nofollow">https://bolha.in</a></li></ul>

<p>Text Editors</p>
<ul><li>hedgeDoc =&gt; <a href="https://notes.bolha.tools" rel="nofollow">https://notes.bolha.tools</a></li>
<li>wise Mapping =&gt; <a href="https://mindmap.bolha.tools" rel="nofollow">https://mindmap.bolha.tools</a></li>
<li>overleaf =&gt; <a href="https://overleaf.bolha.tools" rel="nofollow">https://overleaf.bolha.tools</a></li>
<li>mermaid =&gt; <a href="https://mermaid.bolha.tools" rel="nofollow">https://mermaid.bolha.tools</a></li></ul>

<p>You can also visit our hacking space!</p>
<ul><li><a href="https://gcn.sh" rel="nofollow">https://gcn.sh</a></li>
<li><a href="https://blog.gcn.sh" rel="nofollow">https://blog.gcn.sh</a></li></ul>

<p>Follow our founder!</p>
<ul><li><a href="https://bolha.us/@gutocarvalho" rel="nofollow">https://bolha.us/@gutocarvalho</a></li>
<li><a href="https://bolha.photos/@gutocarvalho" rel="nofollow">https://bolha.photos/@gutocarvalho</a></li>
<li><a href="https://bolha.forum@gutocarvalho" rel="nofollow">https://bolha.forum@gutocarvalho</a></li>
<li><a href="https://bolha.blog/@gutocarvalho" rel="nofollow">https://bolha.blog/@gutocarvalho</a></li>
<li><a href="https://bolha.review/@gutocarvalho" rel="nofollow">https://bolha.review/@gutocarvalho</a></li>
<li><a href="https://bolha.studio/@gutocarvalho" rel="nofollow">https://bolha.studio/@gutocarvalho</a></li>
<li><a href="https://bolha.network/@gutocarvalho" rel="nofollow">https://bolha.network/@gutocarvalho</a></li>
<li>matrix =&gt; @bolha.chat@gutocarvalho</li></ul>

<p>Follow the status of our tools</p>
<ul><li><a href="https://status.bolha.us" rel="nofollow">https://status.bolha.us</a></li></ul>

<p>Do you want to support us? You can!</p>
<ul><li><a href="https://www.patreon.com/bolha" rel="nofollow">https://www.patreon.com/bolha</a></li>
<li><a href="https://apoia.se/bolha" rel="nofollow">https://apoia.se/bolha</a></li>
<li>pix@bolha.us (local brazilian wire transfer)</li></ul>

<p>See you!</p>

<p>[s]</p>
]]></content:encoded>
      <guid>https://blog.gcn.sh/howtos/installing-passbolt-using-docker-and-ubuntu</guid>
      <pubDate>Sun, 02 Jul 2023 14:19:17 +0000</pubDate>
    </item>
    <item>
      <title>Installing Unifi Network Controller </title>
      <link>https://blog.gcn.sh/howtos/installing-unifi-network-controller-using-docker-and-ubuntu</link>
      <description>&lt;![CDATA[Installing Unifi Network Controller Using Docker and Ubuntu&#xA;&#xA;Why?&#xA;&#xA;Usually, the Unifi Network Controller is installed on your personal computer, but, if you want to install it in a virtual machine, you can do that.&#xA;&#xA;Reqs?&#xA;&#xA;Linux&#xA;Docker&#xA;Docker-compose&#xA;&#xA;Here we&#39;re using a Virtual Machine Ubuntu 20.04 for this, running inside a Hypervisor ProxMox 7.4.&#xA;&#xA;How?&#xA;&#xA;creating the directory&#xA;&#xA;mkdir -p /opt/unifi/controller/docker&#xA;mkdir -p /opt/unifi/controller/data/sites/default&#xA;cd /opt/unifi/controller/docker&#xA;&#xA;create a docker-compose file&#xA;&#xA;vim docker-compose.yml&#xA;&#xA;insert the content bellow&#xA;&#xA;---&#xA;version: &#34;2.1&#34;&#xA;services:&#xA;  unifi-controller:&#xA;    image: lscr.io/linuxserver/unifi-controller:7.3.83&#xA;    containername: unifi-controller&#xA;    environment:&#xA;      PUID=1000&#xA;      PGID=1000&#xA;    volumes:&#xA;      /opt/unifi-controller/config:/config&#xA;    ports:&#xA;      8443:8443&#xA;      3478:3478/udp&#xA;      10001:10001/udp&#xA;      8080:8080&#xA;    restart: unless-stopped&#xA;&#xA;in my case, since I&#39;m using USG Router with two WAN connections, and I want to redirect ports to the WAN2, I&#39;ll create a file /opt/unifi/controller/data/sites/default/config.gateway.json with the content bellow&#xA;&#xA;{&#xA;&#x9;&#34;port-forward&#34;: {&#xA;&#x9;&#x9;&#34;wan-interface&#34;: &#34;eth2&#34;&#xA;&#x9;}&#xA;}&#xA;&#xA;This will set the eth2 as the default interface for port-forward, usually it&#39;s the eth0. Now le&#39;ts spin up the container.&#xA;&#xA;docker-compose up -d&#xA;&#xA;and now you can access the dashboard from your browser&#xA;&#xA;https://yourip_here:8443&#xA;&#xA;[s]&#xA;Guto&#xA;&#xA;hr&#xD;&#xA;Did you like our content?&#xD;&#xA;&#xD;&#xA;We have a lot to share; visit our site!&#xD;&#xA;&#xD;&#xA;https://bolha.io&#xD;&#xA;&#xD;&#xA;Our fediverse services ;)&#xD;&#xA;&#xD;&#xA;mastodon =  https://bolha.us&#xD;&#xA;    mastopoet =  https://poet.bolha.us&#xD;&#xA;    elk =  https://elk.bolha.us&#xD;&#xA;    pinafore =  https://pinafore.bolha.us&#xD;&#xA;pixelfed =  https://bolha.photos&#xD;&#xA;lemmy =  https://bolha.social&#xD;&#xA;writefreely =  https://bolha.blog&#xD;&#xA;bookwyrm =  https://bolha.review&#xD;&#xA;funkwhale =  https://bolha.studio&#xD;&#xA;friendica =  https://bolha.network&#xD;&#xA;&#xD;&#xA;Chat and video? We have it!&#xD;&#xA;    &#xD;&#xA;matrix =  https://bolha.chat&#xD;&#xA;jitsi =  https://bolha.video&#xD;&#xA;&#xD;&#xA;Translation tools&#xD;&#xA;&#xD;&#xA; libretranslate =  https://libretranslate.bolha.tools&#xD;&#xA; lingva =  https://translate.bolha.tools&#xD;&#xA;&#xD;&#xA;Video Platform Frontends&#xD;&#xA;&#xD;&#xA; invidious =  https://bolha.in&#xD;&#xA;&#xD;&#xA;Text Editors&#xD;&#xA;&#xD;&#xA; hedgeDoc =  https://notes.bolha.tools&#xD;&#xA; wise Mapping =  https://mindmap.bolha.tools&#xD;&#xA; overleaf =  https://overleaf.bolha.tools&#xD;&#xA; mermaid =  https://mermaid.bolha.tools&#xD;&#xA;&#xD;&#xA;You can also visit our hacking space!&#xD;&#xA;&#xD;&#xA;https://gcn.sh&#xD;&#xA;https://blog.gcn.sh&#xD;&#xA;&#xD;&#xA;Follow our founder!&#xD;&#xA;&#xD;&#xA;https://bolha.us/@gutocarvalho&#xD;&#xA;https://bolha.photos/@gutocarvalho&#xD;&#xA;https://bolha.forum@gutocarvalho&#xD;&#xA;https://bolha.blog/@gutocarvalho&#xD;&#xA;https://bolha.review/@gutocarvalho&#xD;&#xA;https://bolha.studio/@gutocarvalho&#xD;&#xA;https://bolha.network/@gutocarvalho&#xD;&#xA;matrix =  @bolha.chat@gutocarvalho&#xD;&#xA;&#xD;&#xA;Follow the status of our tools&#xD;&#xA;&#xD;&#xA;https://status.bolha.us&#xD;&#xA;&#xD;&#xA;Do you want to support us? You can!&#xD;&#xA;&#xD;&#xA;https://www.patreon.com/bolha&#xD;&#xA;https://apoia.se/bolha&#xD;&#xA;pix@bolha.us (local brazilian wire transfer)&#xD;&#xA;&#xD;&#xA;See you!&#xD;&#xA;&#xD;&#xA;[s]]]&gt;</description>
      <content:encoded><![CDATA[<p>Installing Unifi Network Controller Using Docker and Ubuntu</p>

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

<p>Usually, the Unifi Network Controller is installed on your personal computer, but, if you want to install it in a virtual machine, you can do that.</p>

<h3 id="reqs" id="reqs">Reqs?</h3>
<ul><li>Linux</li>
<li>Docker</li>
<li>Docker-compose</li></ul>

<p>Here we&#39;re using a Virtual Machine Ubuntu 20.04 for this, running inside a Hypervisor ProxMox 7.4.</p>

<h3 id="how" id="how">How?</h3>

<p>creating the directory</p>

<pre><code>mkdir -p /opt/unifi/controller/docker
mkdir -p /opt/unifi/controller/data/sites/default
cd /opt/unifi/controller/docker
</code></pre>

<p>create a docker-compose file</p>

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

<p>insert the content bellow</p>

<pre><code>---
version: &#34;2.1&#34;
services:
  unifi-controller:
    image: lscr.io/linuxserver/unifi-controller:7.3.83
    container_name: unifi-controller
    environment:
      - PUID=1000
      - PGID=1000
    volumes:
      - /opt/unifi-controller/config:/config
    ports:
      - 8443:8443
      - 3478:3478/udp
      - 10001:10001/udp
      - 8080:8080
    restart: unless-stopped
</code></pre>

<p>in my case, since I&#39;m using USG Router with two WAN connections, and I want to redirect ports to the WAN2, I&#39;ll create a file /opt/unifi/controller/data/sites/default/config.gateway.json with the content bellow</p>

<pre><code>{
	&#34;port-forward&#34;: {
		&#34;wan-interface&#34;: &#34;eth2&#34;
	}
}
</code></pre>

<p>This will set the eth2 as the default interface for port-forward, usually it&#39;s the eth0. Now le&#39;ts spin up the container.</p>

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

<p>and now you can access the dashboard from your browser</p>

<pre><code>https://your_ip_here:8443
</code></pre>

<p>[s]
Guto</p>

<hr>

<h3 id="did-you-like-our-content" id="did-you-like-our-content">Did you like our content?</h3>

<p>We have a lot to share; visit our site!</p>
<ul><li><a href="https://bolha.io" rel="nofollow">https://bolha.io</a></li></ul>

<p>Our fediverse services ;)</p>
<ul><li>mastodon =&gt; <a href="https://bolha.us" rel="nofollow">https://bolha.us</a>
<ul><li>mastopoet =&gt; <a href="https://poet.bolha.us" rel="nofollow">https://poet.bolha.us</a></li>
<li>elk =&gt; <a href="https://elk.bolha.us" rel="nofollow">https://elk.bolha.us</a></li>
<li>pinafore =&gt; <a href="https://pinafore.bolha.us" rel="nofollow">https://pinafore.bolha.us</a></li></ul></li>
<li>pixelfed =&gt; <a href="https://bolha.photos" rel="nofollow">https://bolha.photos</a></li>
<li>lemmy =&gt; <a href="https://bolha.social" rel="nofollow">https://bolha.social</a></li>
<li>writefreely =&gt; <a href="https://bolha.blog" rel="nofollow">https://bolha.blog</a></li>
<li>bookwyrm =&gt; <a href="https://bolha.review" rel="nofollow">https://bolha.review</a></li>
<li>funkwhale =&gt; <a href="https://bolha.studio" rel="nofollow">https://bolha.studio</a></li>
<li>friendica =&gt; <a href="https://bolha.network" rel="nofollow">https://bolha.network</a></li></ul>

<p>Chat and video? We have it!</p>
<ul><li>matrix =&gt; <a href="https://bolha.chat" rel="nofollow">https://bolha.chat</a></li>
<li>jitsi =&gt; <a href="https://bolha.video" rel="nofollow">https://bolha.video</a></li></ul>

<p>Translation tools</p>
<ul><li>libretranslate =&gt; <a href="https://libretranslate.bolha.tools" rel="nofollow">https://libretranslate.bolha.tools</a></li>
<li>lingva =&gt; <a href="https://translate.bolha.tools" rel="nofollow">https://translate.bolha.tools</a></li></ul>

<p>Video Platform Frontends</p>
<ul><li>invidious =&gt; <a href="https://bolha.in" rel="nofollow">https://bolha.in</a></li></ul>

<p>Text Editors</p>
<ul><li>hedgeDoc =&gt; <a href="https://notes.bolha.tools" rel="nofollow">https://notes.bolha.tools</a></li>
<li>wise Mapping =&gt; <a href="https://mindmap.bolha.tools" rel="nofollow">https://mindmap.bolha.tools</a></li>
<li>overleaf =&gt; <a href="https://overleaf.bolha.tools" rel="nofollow">https://overleaf.bolha.tools</a></li>
<li>mermaid =&gt; <a href="https://mermaid.bolha.tools" rel="nofollow">https://mermaid.bolha.tools</a></li></ul>

<p>You can also visit our hacking space!</p>
<ul><li><a href="https://gcn.sh" rel="nofollow">https://gcn.sh</a></li>
<li><a href="https://blog.gcn.sh" rel="nofollow">https://blog.gcn.sh</a></li></ul>

<p>Follow our founder!</p>
<ul><li><a href="https://bolha.us/@gutocarvalho" rel="nofollow">https://bolha.us/@gutocarvalho</a></li>
<li><a href="https://bolha.photos/@gutocarvalho" rel="nofollow">https://bolha.photos/@gutocarvalho</a></li>
<li><a href="https://bolha.forum@gutocarvalho" rel="nofollow">https://bolha.forum@gutocarvalho</a></li>
<li><a href="https://bolha.blog/@gutocarvalho" rel="nofollow">https://bolha.blog/@gutocarvalho</a></li>
<li><a href="https://bolha.review/@gutocarvalho" rel="nofollow">https://bolha.review/@gutocarvalho</a></li>
<li><a href="https://bolha.studio/@gutocarvalho" rel="nofollow">https://bolha.studio/@gutocarvalho</a></li>
<li><a href="https://bolha.network/@gutocarvalho" rel="nofollow">https://bolha.network/@gutocarvalho</a></li>
<li>matrix =&gt; @bolha.chat@gutocarvalho</li></ul>

<p>Follow the status of our tools</p>
<ul><li><a href="https://status.bolha.us" rel="nofollow">https://status.bolha.us</a></li></ul>

<p>Do you want to support us? You can!</p>
<ul><li><a href="https://www.patreon.com/bolha" rel="nofollow">https://www.patreon.com/bolha</a></li>
<li><a href="https://apoia.se/bolha" rel="nofollow">https://apoia.se/bolha</a></li>
<li>pix@bolha.us (local brazilian wire transfer)</li></ul>

<p>See you!</p>

<p>[s]</p>
]]></content:encoded>
      <guid>https://blog.gcn.sh/howtos/installing-unifi-network-controller-using-docker-and-ubuntu</guid>
      <pubDate>Thu, 29 Jun 2023 19:05:46 +0000</pubDate>
    </item>
    <item>
      <title>Enabling Wasabi Object Storage for Mastodon Media</title>
      <link>https://blog.gcn.sh/howtos/enabling-wasabi-object-storage-for-mastodon-media</link>
      <description>&lt;![CDATA[This post is a continuation of this post&#xA;&#xA;https://blog.gcn.sh/howtos/installing-mastodon-4-1-2-using-docker-on-ubuntu&#xA;&#xA;It depends on the first one.&#xA;&#xA;1. Wasabi Config&#xA;&#xA;Since I&#39;m running my Baremetal in OVH Canada, I&#39;ll create my bucket in the same country.&#xA;&#xA;Wasabi CA Central 1 (Toronto)&#x9;s3.ca-central-1.wasabisys.com&#xA;&#xA;1.1 create a bucket mastodon-prod-media&#xA;&#xA;Add this polity to the bucket policy configuration&#xA;&#xA;{&#xA;  &#34;Version&#34;: &#34;2012-10-17&#34;,&#xA;  &#34;Statement&#34;: [&#xA;    {&#xA;      &#34;Sid&#34;: &#34;AddPerm&#34;,&#xA;      &#34;Effect&#34;: &#34;Allow&#34;,&#xA;      &#34;Principal&#34;: {&#xA;        &#34;AWS&#34;: &#34;&#34;&#xA;      },&#xA;      &#34;Action&#34;: &#34;s3:GetObject&#34;,&#xA;      &#34;Resource&#34;: &#34;arn:aws:s3:::mastodon-prod-media/&#34;&#xA;    }&#xA;  ]&#xA;}&#xA;&#xA;1.2 create a user mastodon-prod-user&#xA;&#xA;Create an user with Programmatic API Key.&#xA;Save the key in your password manager.&#xA;&#xA;1.3 create a policy mastodon-prod-policy&#xA;&#xA;Create a policy with the content bellow&#xA;&#xA;{&#xA;  &#34;Version&#34;: &#34;2012-10-17&#34;,&#xA;  &#34;Statement&#34;: [&#xA;    {&#xA;      &#34;Effect&#34;: &#34;Allow&#34;,&#xA;      &#34;Action&#34;: &#34;s3:ListBucket&#34;,&#xA;      &#34;Resource&#34;: &#34;arn:aws:s3:::mastodon-prod-media&#34;&#xA;    },&#xA;    {&#xA;      &#34;Effect&#34;: &#34;Allow&#34;,&#xA;      &#34;Action&#34;: [&#34;s3:PutObject&#34;, &#34;s3:GetObject&#34;, &#34;s3:DeleteObject&#34;],&#xA;      &#34;Resource&#34;: &#34;arn:aws:s3:::mastodon-prod-media/&#34;&#xA;    }&#xA;  ]&#xA;}&#xA;&#xA;1.4 edit the user and add the police&#xA;&#xA;Go to the url &#xA;&#xA;https://console.wasabisys.com/users/mastodon-prod-user&#xA;&#xA;Configure the policy&#xA;&#xA;select the policies tab&#xA;select the mastodon-prod-policy&#xA;&#xA;Done!&#xA;&#xA;2. Mastodon Config&#xA;&#xA;2.1 Sync static files&#xA;&#xA;install the aws-cli&#xA;&#xA;apt install python3-pip&#xA;pip install awscli&#xA;&#xA;configure your aws-credentials&#xA;&#xA;$aws configure&#xA;AWS Access Key ID [None]: XXXXXXXXXXXX&#xA;AWS Secret Access Key [None]: XXXXXXXXXXXXXXXXXX&#xA;Default region name [None]:&#xA;Default output format [None]:&#xA;&#xA;copy the existing files to the object storage&#xA;&#xA;cd /opt/mastodon/data&#xA;screen&#xA;aws s3 sync system/ s3://mastodon-prod-media/ --endpoint-url=https://s3.ca-central-1.wasabisys.com&#xA;&#xA;2.2 Mastodon Configuration&#xA;&#xA;Edit the application.env file&#xA;&#xA;vim /etc/mastodon/docker/application.env&#xA;&#xA;You will change this on the application.env&#xA;&#xA;rails will serve static files?&#xA;&#xA;RAILSSERVESTATICFILES=false&#xA;&#xA;And you will add this section to the application.env&#xA;&#xA;File storage (optional)&#xA;-----------------------&#xA;S3ENABLED=true&#xA;S3BUCKET=mastodon-prod-media&#xA;AWSACCESSKEYID=YOURACCESSKEYHERE&#xA;AWSSECRETACCESSKEY=YOURACCESSSECRETKEYHERE&#xA;S3HOSTNAME=media.gcn.sh&#xA;S3PROTOCOL=https&#xA;S3ENDPOINT=https://s3.ca-central-1.wasabisys.com&#xA;S3FORCESINGLEREQUEST=true&#xA;&#xA;Restart your mastodon stack.&#xA;&#xA;docker-compose down&#xA;docker-compose up -d&#xA;&#xA;Done!&#xA;&#xA;3. NGINX Config&#xA;&#xA;We&#39;ll use a NGINX in front of our mastodon to have a friendly URL for our media files and a cache layer to improve the performance.&#xA;&#xA;proxycachepath /var/cache/mastodon-prod-media levels=1:2 keyszone=mastodonmedia:100m maxsize=2g inactive=12h;&#xA;&#xA;server {&#xA;    listen yourlisteniphere:80;&#xA;    servername media.gcn.sh;&#xA;    return 301 https://media.gcn.sh$requesturi;&#xA;&#xA;    accesslog /dev/null;&#xA;    errorlog /dev/null;&#xA;}&#xA;&#xA;server {&#xA;    listen yourlisteniphere:443 ssl http2;&#xA;    servername media.gcn.sh;&#xA;&#xA;    accesslog /var/log/nginx/media-mastodon-access.log;&#xA;    errorlog /var/log/nginx/media-mastodon-error.log;&#xA;&#xA;  sslprotocols TLSv1.2 TLSv1.3;&#xA;  sslciphers HIGH:!MEDIUM:!LOW:!aNULL:!NULL:!SHA;&#xA;  sslpreferserverciphers on;&#xA;  sslsessioncache shared:SSL:10m;&#xA;  sslsessiontickets off;&#xA;&#xA;  sslcertificate /etc/letsencrypt/live/gcn.sh/fullchain.pem;&#xA;  sslcertificatekey /etc/letsencrypt/live/gcn.sh/privkey.pem;&#xA;&#xA;    location /mastodon-prod-media/ {&#xA;        proxycache mastodonmedia;&#xA;        proxycacherevalidate on;&#xA;        proxybuffering on;&#xA;        proxycacheusestale error timeout updating http500 http502 http503 http504;&#xA;        proxycachebackgroundupdate on;&#xA;        proxycachelock on;&#xA;        proxycachevalid 1d;&#xA;        proxycachevalid 404 1h;&#xA;        proxyignoreheaders Cache-Control;&#xA;        addheader X-Cached $upstreamcachestatus;&#xA;        proxypass https://s3.us-central-1.wasabisys.com/mastodon-prod-media/;&#xA;    }&#xA;}&#xA;&#xA;It&#39;ll cache the requests for about 12h and we&#39;re limiting the disk usage to 2 GB.&#xA;&#xA;3.1 NGINX cache validation&#xA;&#xA;Go to your account, copy a image URL address and use CURL againt the URL.&#xA;&#xA;curl -I https://media.gcn.sh/mastodon-prod-media/mediaattachments/cache/media_attachments/files/110/220/330/440/550/660/small/filename.jpeg&#xA;&#xA;On the first try need to get a MISS on the x-cached header response&#xA;&#xA;x-cached: MISS&#xA;&#xA;On the second try, you need to get a HIT on the x-cached header response&#xA;&#xA;x-cached: HIT&#xA;&#xA;If you get the MISS and the HIT after, everything is fine.&#xA;&#xA;If you get the HIT, it&#39;s ok too :)&#xA;&#xA;4. Cleanup session&#xA;&#xA;Run the sync one more time, just to be sure&#xA;Remove the contents of the directory /opt/mastodon/data/web/system&#xA;&#xA;rm -rf /opt/mastodon/data/web/system/&#xA;&#xA;4.1 Why am I removing this?&#xA;&#xA;Your media files are now on the Wasabi Object Storage, you don&#39;t need the local files anymore.&#xA;&#xA;5. References&#xA;&#xA;https://docs.joinmastodon.org/admin/optional/object-storage/&#xA;https://stanislas.blog/2018/05/moving-mastodon-media-files-to-wasabi-object-storage/&#xA;https://github.com/cybrespace/cybrespace-meta/blob/master/s3.md&#xA;https://thomas-leister.de/en/mastodon-s3-media-storage/&#xA;&#xA;hr&#xD;&#xA;Did you like our content?&#xD;&#xA;&#xD;&#xA;We have a lot to share; visit our site!&#xD;&#xA;&#xD;&#xA;https://bolha.io&#xD;&#xA;&#xD;&#xA;Our fediverse services ;)&#xD;&#xA;&#xD;&#xA;mastodon =  https://bolha.us&#xD;&#xA;    mastopoet =  https://poet.bolha.us&#xD;&#xA;    elk =  https://elk.bolha.us&#xD;&#xA;    pinafore =  https://pinafore.bolha.us&#xD;&#xA;pixelfed =  https://bolha.photos&#xD;&#xA;lemmy =  https://bolha.social&#xD;&#xA;writefreely =  https://bolha.blog&#xD;&#xA;bookwyrm =  https://bolha.review&#xD;&#xA;funkwhale =  https://bolha.studio&#xD;&#xA;friendica =  https://bolha.network&#xD;&#xA;&#xD;&#xA;Chat and video? We have it!&#xD;&#xA;    &#xD;&#xA;matrix =  https://bolha.chat&#xD;&#xA;jitsi =  https://bolha.video&#xD;&#xA;&#xD;&#xA;Translation tools&#xD;&#xA;&#xD;&#xA; libretranslate =  https://libretranslate.bolha.tools&#xD;&#xA; lingva =  https://translate.bolha.tools&#xD;&#xA;&#xD;&#xA;Video Platform Frontends&#xD;&#xA;&#xD;&#xA; invidious =  https://bolha.in&#xD;&#xA;&#xD;&#xA;Text Editors&#xD;&#xA;&#xD;&#xA; hedgeDoc =  https://notes.bolha.tools&#xD;&#xA; wise Mapping =  https://mindmap.bolha.tools&#xD;&#xA; overleaf =  https://overleaf.bolha.tools&#xD;&#xA; mermaid =  https://mermaid.bolha.tools&#xD;&#xA;&#xD;&#xA;You can also visit our hacking space!&#xD;&#xA;&#xD;&#xA;https://gcn.sh&#xD;&#xA;https://blog.gcn.sh&#xD;&#xA;&#xD;&#xA;Follow our founder!&#xD;&#xA;&#xD;&#xA;https://bolha.us/@gutocarvalho&#xD;&#xA;https://bolha.photos/@gutocarvalho&#xD;&#xA;https://bolha.forum@gutocarvalho&#xD;&#xA;https://bolha.blog/@gutocarvalho&#xD;&#xA;https://bolha.review/@gutocarvalho&#xD;&#xA;https://bolha.studio/@gutocarvalho&#xD;&#xA;https://bolha.network/@gutocarvalho&#xD;&#xA;matrix =  @bolha.chat@gutocarvalho&#xD;&#xA;&#xD;&#xA;Follow the status of our tools&#xD;&#xA;&#xD;&#xA;https://status.bolha.us&#xD;&#xA;&#xD;&#xA;Do you want to support us? You can!&#xD;&#xA;&#xD;&#xA;https://www.patreon.com/bolha&#xD;&#xA;https://apoia.se/bolha&#xD;&#xA;pix@bolha.us (local brazilian wire transfer)&#xD;&#xA;&#xD;&#xA;See you!&#xD;&#xA;&#xD;&#xA;[s]]]&gt;</description>
      <content:encoded><![CDATA[<p>This post is a continuation of this post</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>It depends on the first one.</p>

<h2 id="1-wasabi-config" id="1-wasabi-config">1. Wasabi Config</h2>

<p>Since I&#39;m running my Baremetal in OVH Canada, I&#39;ll create my bucket in the same country.</p>

<pre><code>Wasabi CA Central 1 (Toronto)	s3.ca-central-1.wasabisys.com
</code></pre>

<h3 id="1-1-create-a-bucket-mastodon-prod-media" id="1-1-create-a-bucket-mastodon-prod-media">1.1 create a bucket mastodon-prod-media</h3>

<p>Add this polity to the bucket policy configuration</p>

<pre><code>{
  &#34;Version&#34;: &#34;2012-10-17&#34;,
  &#34;Statement&#34;: [
    {
      &#34;Sid&#34;: &#34;AddPerm&#34;,
      &#34;Effect&#34;: &#34;Allow&#34;,
      &#34;Principal&#34;: {
        &#34;AWS&#34;: &#34;*&#34;
      },
      &#34;Action&#34;: &#34;s3:GetObject&#34;,
      &#34;Resource&#34;: &#34;arn:aws:s3:::mastodon-prod-media/*&#34;
    }
  ]
}
</code></pre>

<h3 id="1-2-create-a-user-mastodon-prod-user" id="1-2-create-a-user-mastodon-prod-user">1.2 create a user mastodon-prod-user</h3>
<ol><li>Create an user with Programmatic API Key.</li>
<li>Save the key in your password manager.</li></ol>

<h3 id="1-3-create-a-policy-mastodon-prod-policy" id="1-3-create-a-policy-mastodon-prod-policy">1.3 create a policy mastodon-prod-policy</h3>

<p>Create a policy with the content bellow</p>

<pre><code>{
  &#34;Version&#34;: &#34;2012-10-17&#34;,
  &#34;Statement&#34;: [
    {
      &#34;Effect&#34;: &#34;Allow&#34;,
      &#34;Action&#34;: &#34;s3:ListBucket&#34;,
      &#34;Resource&#34;: &#34;arn:aws:s3:::mastodon-prod-media&#34;
    },
    {
      &#34;Effect&#34;: &#34;Allow&#34;,
      &#34;Action&#34;: [&#34;s3:PutObject&#34;, &#34;s3:GetObject&#34;, &#34;s3:DeleteObject&#34;],
      &#34;Resource&#34;: &#34;arn:aws:s3:::mastodon-prod-media/*&#34;
    }
  ]
}
</code></pre>

<h3 id="1-4-edit-the-user-and-add-the-police" id="1-4-edit-the-user-and-add-the-police">1.4 edit the user and add the police</h3>

<p>Go to the url</p>
<ul><li><a href="https://console.wasabisys.com/users/mastodon-prod-user" rel="nofollow">https://console.wasabisys.com/users/mastodon-prod-user</a></li></ul>

<p>Configure the policy</p>
<ol><li>select the policies tab</li>
<li>select the mastodon-prod-policy</li></ol>

<p>Done!</p>

<h2 id="2-mastodon-config" id="2-mastodon-config">2. Mastodon Config</h2>

<h3 id="2-1-sync-static-files" id="2-1-sync-static-files">2.1 Sync static files</h3>

<p>install the aws-cli</p>

<pre><code>apt install python3-pip
pip install awscli
</code></pre>

<p>configure your aws-credentials</p>

<pre><code>$aws configure
AWS Access Key ID [None]: XXXXXXXXXXXX
AWS Secret Access Key [None]: XXXXXXXXXXXXXXXXXX
Default region name [None]:
Default output format [None]:
</code></pre>

<p>copy the existing files to the object storage</p>

<pre><code>cd /opt/mastodon/data
screen
aws s3 sync system/ s3://mastodon-prod-media/ --endpoint-url=https://s3.ca-central-1.wasabisys.com
</code></pre>

<h3 id="2-2-mastodon-configuration" id="2-2-mastodon-configuration">2.2 Mastodon Configuration</h3>

<p>Edit the application.env file</p>

<pre><code>vim /etc/mastodon/docker/application.env
</code></pre>

<p>You will change this on the application.env</p>

<pre><code># rails will serve static files?

RAILS_SERVE_STATIC_FILES=false
</code></pre>

<p>And you will add this section to the application.env</p>

<pre><code># File storage (optional)
# -----------------------
S3_ENABLED=true
S3_BUCKET=mastodon-prod-media
AWS_ACCESS_KEY_ID=YOUR_ACCESS_KEY_HERE
AWS_SECRET_ACCESS_KEY=YOUR_ACCESS_SECRET_KEY_HERE
S3_HOSTNAME=media.gcn.sh
S3_PROTOCOL=https
S3_ENDPOINT=https://s3.ca-central-1.wasabisys.com
S3_FORCE_SINGLE_REQUEST=true
</code></pre>

<p>Restart your mastodon stack.</p>

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

<p>Done!</p>

<h2 id="3-nginx-config" id="3-nginx-config">3. NGINX Config</h2>

<p>We&#39;ll use a NGINX in front of our mastodon to have a friendly URL for our media files and a cache layer to improve the performance.</p>

<pre><code>proxy_cache_path /var/cache/mastodon-prod-media levels=1:2 keys_zone=mastodon_media:100m max_size=2g inactive=12h;

server {
    listen your_listen_ip_here:80;
    server_name media.gcn.sh;
    return 301 https://media.gcn.sh$request_uri;

    access_log /dev/null;
    error_log /dev/null;
}

server {
    listen your_listen_ip_here:443 ssl http2;
    server_name media.gcn.sh;

    access_log /var/log/nginx/media-mastodon-access.log;
    error_log /var/log/nginx/media-mastodon-error.log;

  ssl_protocols TLSv1.2 TLSv1.3;
  ssl_ciphers HIGH:!MEDIUM:!LOW:!aNULL:!NULL:!SHA;
  ssl_prefer_server_ciphers on;
  ssl_session_cache shared:SSL:10m;
  ssl_session_tickets off;

  ssl_certificate /etc/letsencrypt/live/gcn.sh/fullchain.pem;
  ssl_certificate_key /etc/letsencrypt/live/gcn.sh/privkey.pem;

    location /mastodon-prod-media/ {
        proxy_cache mastodon_media;
        proxy_cache_revalidate on;
        proxy_buffering on;
        proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504;
        proxy_cache_background_update on;
        proxy_cache_lock on;
        proxy_cache_valid 1d;
        proxy_cache_valid 404 1h;
        proxy_ignore_headers Cache-Control;
        add_header X-Cached $upstream_cache_status;
        proxy_pass https://s3.us-central-1.wasabisys.com/mastodon-prod-media/;
    }
}
</code></pre>

<p>It&#39;ll cache the requests for about 12h and we&#39;re limiting the disk usage to 2 GB.</p>

<h3 id="3-1-nginx-cache-validation" id="3-1-nginx-cache-validation">3.1 NGINX cache validation</h3>

<p>Go to your account, copy a image URL address and use CURL againt the URL.</p>

<pre><code>curl -I https://media.gcn.sh/mastodon-prod-media/media_attachments/cache/media_attachments/files/110/220/330/440/550/660/small/filename.jpeg
</code></pre>

<p>On the first try need to get a MISS on the x-cached header response</p>

<pre><code>x-cached: MISS
</code></pre>

<p>On the second try, you need to get a HIT on the x-cached header response</p>

<pre><code>x-cached: HIT
</code></pre>

<p>If you get the MISS and the HIT after, everything is fine.</p>

<p>If you get the HIT, it&#39;s ok too :)</p>

<h2 id="4-cleanup-session" id="4-cleanup-session">4. Cleanup session</h2>
<ol><li>Run the sync one more time, just to be sure</li>
<li>Remove the contents of the directory /opt/mastodon/data/web/system</li></ol>

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

<h3 id="4-1-why-am-i-removing-this" id="4-1-why-am-i-removing-this">4.1 Why am I removing this?</h3>

<p>Your media files are now on the Wasabi Object Storage, you don&#39;t need the local files anymore.</p>

<h2 id="5-references" id="5-references">5. References</h2>
<ul><li><a href="https://docs.joinmastodon.org/admin/optional/object-storage/" rel="nofollow">https://docs.joinmastodon.org/admin/optional/object-storage/</a></li>
<li><a href="https://stanislas.blog/2018/05/moving-mastodon-media-files-to-wasabi-object-storage/" rel="nofollow">https://stanislas.blog/2018/05/moving-mastodon-media-files-to-wasabi-object-storage/</a></li>
<li><a href="https://github.com/cybrespace/cybrespace-meta/blob/master/s3.md" rel="nofollow">https://github.com/cybrespace/cybrespace-meta/blob/master/s3.md</a></li>
<li><a href="https://thomas-leister.de/en/mastodon-s3-media-storage/" rel="nofollow">https://thomas-leister.de/en/mastodon-s3-media-storage/</a></li></ul>

<hr>

<h3 id="did-you-like-our-content" id="did-you-like-our-content">Did you like our content?</h3>

<p>We have a lot to share; visit our site!</p>
<ul><li><a href="https://bolha.io" rel="nofollow">https://bolha.io</a></li></ul>

<p>Our fediverse services ;)</p>
<ul><li>mastodon =&gt; <a href="https://bolha.us" rel="nofollow">https://bolha.us</a>
<ul><li>mastopoet =&gt; <a href="https://poet.bolha.us" rel="nofollow">https://poet.bolha.us</a></li>
<li>elk =&gt; <a href="https://elk.bolha.us" rel="nofollow">https://elk.bolha.us</a></li>
<li>pinafore =&gt; <a href="https://pinafore.bolha.us" rel="nofollow">https://pinafore.bolha.us</a></li></ul></li>
<li>pixelfed =&gt; <a href="https://bolha.photos" rel="nofollow">https://bolha.photos</a></li>
<li>lemmy =&gt; <a href="https://bolha.social" rel="nofollow">https://bolha.social</a></li>
<li>writefreely =&gt; <a href="https://bolha.blog" rel="nofollow">https://bolha.blog</a></li>
<li>bookwyrm =&gt; <a href="https://bolha.review" rel="nofollow">https://bolha.review</a></li>
<li>funkwhale =&gt; <a href="https://bolha.studio" rel="nofollow">https://bolha.studio</a></li>
<li>friendica =&gt; <a href="https://bolha.network" rel="nofollow">https://bolha.network</a></li></ul>

<p>Chat and video? We have it!</p>
<ul><li>matrix =&gt; <a href="https://bolha.chat" rel="nofollow">https://bolha.chat</a></li>
<li>jitsi =&gt; <a href="https://bolha.video" rel="nofollow">https://bolha.video</a></li></ul>

<p>Translation tools</p>
<ul><li>libretranslate =&gt; <a href="https://libretranslate.bolha.tools" rel="nofollow">https://libretranslate.bolha.tools</a></li>
<li>lingva =&gt; <a href="https://translate.bolha.tools" rel="nofollow">https://translate.bolha.tools</a></li></ul>

<p>Video Platform Frontends</p>
<ul><li>invidious =&gt; <a href="https://bolha.in" rel="nofollow">https://bolha.in</a></li></ul>

<p>Text Editors</p>
<ul><li>hedgeDoc =&gt; <a href="https://notes.bolha.tools" rel="nofollow">https://notes.bolha.tools</a></li>
<li>wise Mapping =&gt; <a href="https://mindmap.bolha.tools" rel="nofollow">https://mindmap.bolha.tools</a></li>
<li>overleaf =&gt; <a href="https://overleaf.bolha.tools" rel="nofollow">https://overleaf.bolha.tools</a></li>
<li>mermaid =&gt; <a href="https://mermaid.bolha.tools" rel="nofollow">https://mermaid.bolha.tools</a></li></ul>

<p>You can also visit our hacking space!</p>
<ul><li><a href="https://gcn.sh" rel="nofollow">https://gcn.sh</a></li>
<li><a href="https://blog.gcn.sh" rel="nofollow">https://blog.gcn.sh</a></li></ul>

<p>Follow our founder!</p>
<ul><li><a href="https://bolha.us/@gutocarvalho" rel="nofollow">https://bolha.us/@gutocarvalho</a></li>
<li><a href="https://bolha.photos/@gutocarvalho" rel="nofollow">https://bolha.photos/@gutocarvalho</a></li>
<li><a href="https://bolha.forum@gutocarvalho" rel="nofollow">https://bolha.forum@gutocarvalho</a></li>
<li><a href="https://bolha.blog/@gutocarvalho" rel="nofollow">https://bolha.blog/@gutocarvalho</a></li>
<li><a href="https://bolha.review/@gutocarvalho" rel="nofollow">https://bolha.review/@gutocarvalho</a></li>
<li><a href="https://bolha.studio/@gutocarvalho" rel="nofollow">https://bolha.studio/@gutocarvalho</a></li>
<li><a href="https://bolha.network/@gutocarvalho" rel="nofollow">https://bolha.network/@gutocarvalho</a></li>
<li>matrix =&gt; @bolha.chat@gutocarvalho</li></ul>

<p>Follow the status of our tools</p>
<ul><li><a href="https://status.bolha.us" rel="nofollow">https://status.bolha.us</a></li></ul>

<p>Do you want to support us? You can!</p>
<ul><li><a href="https://www.patreon.com/bolha" rel="nofollow">https://www.patreon.com/bolha</a></li>
<li><a href="https://apoia.se/bolha" rel="nofollow">https://apoia.se/bolha</a></li>
<li>pix@bolha.us (local brazilian wire transfer)</li></ul>

<p>See you!</p>

<p>[s]</p>
]]></content:encoded>
      <guid>https://blog.gcn.sh/howtos/enabling-wasabi-object-storage-for-mastodon-media</guid>
      <pubDate>Wed, 14 Jun 2023 06:55:34 +0000</pubDate>
    </item>
    <item>
      <title>Installing invidious with docker on Ubuntu</title>
      <link>https://blog.gcn.sh/howtos/installing-invidious-with-docker-on-ubuntu</link>
      <description>&lt;![CDATA[about the project&#xA;&#xA;Invidious is an open-source alternative front-end to YouTube.&#xA;&#xA;Privacy focused&#xA;Ethically designed&#xA;No Ads&#xA;Developer API&#xA;Multilingual&#xA;No need of an Youtube Account&#xA;&#xA;Visit the project&#xA;&#xA;https://invidious.io&#xA;https://docs.invidious.io&#xA;&#xA;installation steps&#xA;&#xA;generate a password for your postgresql.&#xA;&#xA;openssl rand -hex 15&#xA;&#xA;create the directory&#xA;&#xA;mkdir -p /opt/invidious/data/postgresql&#xA;cd /opt/invidious/&#xA;&#xA;clone the project&#xA;&#xA;git clone https://github.com/iv-org/invidious.git docker&#xA;cd docker&#xA;&#xA;configure your installation &#xA;&#xA;vim docker-compose.yml&#xA;&#xA;content&#xA;&#xA;version: &#34;3&#34;&#xA;services:&#xA;&#xA;  invidious:&#xA;    image: quay.io/invidious/invidious:latest&#xA;    restart: unless-stopped&#xA;    ports:&#xA;      &#34;3000:3000&#34;&#xA;    environment:&#xA;      INVIDIOUSCONFIG: |&#xA;        db:&#xA;          dbname: invidious&#xA;          user: kemal&#xA;          password: yourpostgresqlpasswordhere&#xA;          host: invidious-db&#xA;          port: 5432&#xA;        checktables: true&#xA;    healthcheck:&#xA;      test: wget -nv --tries=1 --spider http://127.0.0.1:3000/api/v1/comments/jNQXAC9IVRw || exit 1&#xA;      interval: 30s&#xA;      timeout: 5s&#xA;      retries: 2&#xA;    logging:&#xA;      options:&#xA;        max-size: &#34;1G&#34;&#xA;        max-file: &#34;4&#34;&#xA;    dependson:&#xA;      invidious-db&#xA;&#xA;  invidious-db:&#xA;    image: docker.io/library/postgres:14&#xA;    restart: unless-stopped&#xA;    volumes:&#xA;      postgresdata:/var/lib/postgresql/data&#xA;      ./config/sql:/config/sql&#xA;      ./docker/init-invidious-db.sh:/docker-entrypoint-initdb.d/init-invidious-db.sh&#xA;    environment:&#xA;      POSTGRESDB: invidious&#xA;      POSTGRESUSER: kemal&#xA;      POSTGRESPASSWORD: yourpostgresqlpasswordhere&#xA;    healthcheck:&#xA;      test: [&#34;CMD-SHELL&#34;, &#34;pgisready -U $$POSTGRESUSER -d $$POSTGRESDB&#34;]&#xA;&#xA;volumes:&#xA;  postgresql:&#xA;    driveropts:&#xA;      type: none&#xA;      device: /opt/invidious/data/postgresql&#xA;      o: bind&#xA;&#xA;start your invidious&#xA;&#xA;docker-compose up -d&#xA;&#xA;visit your instance&#xA;&#xA;https://yourdockerhostip:3000&#xA;&#xA;nginx configuration example&#xA;&#xA;server {&#xA;    listen yourlisteniphere:80;&#xA;    servername tube.bolha.tools;&#xA;    location / {&#xA;        return 301 https://tube.bolha.tools$requesturi;&#xA;    }&#xA;}&#xA;&#xA;server {&#xA;    listen yourlisteniphere:443 ssl http2;&#xA;    servername tube.bolha.tools;&#xA;&#xA;    sslcertificate /etc/letsencrypt/live/bolha.tools/fullchain.pem;&#xA;    sslcertificatekey /etc/letsencrypt/live/bolha.tools/privkey.pem;&#xA;&#xA;    accesslog /var/log/nginx/tube-bolha-tools-access.log;&#xA;    errorlog /var/log/nginx/tube-bolha-tools-error.log;&#xA;&#xA;    location / {&#xA;        proxypass http://yourinvidiousiphere:yourporthere;&#xA;        proxysetheader X-Forwarded-For $remoteaddr;&#xA;        proxysetheader Host $host;    # so Invidious knows domain&#xA;        proxyhttpversion 1.1;     # to keep alive&#xA;        proxysetheader Connection &#34;&#34;; # to keep alive&#xA;    }&#xA;&#xA;}&#xA;&#xA;Enjoy!&#xA;&#xA;hr&#xD;&#xA;Did you like our content?&#xD;&#xA;&#xD;&#xA;We have a lot to share; visit our site!&#xD;&#xA;&#xD;&#xA;https://bolha.io&#xD;&#xA;&#xD;&#xA;Our fediverse services ;)&#xD;&#xA;&#xD;&#xA;mastodon =  https://bolha.us&#xD;&#xA;    mastopoet =  https://poet.bolha.us&#xD;&#xA;    elk =  https://elk.bolha.us&#xD;&#xA;    pinafore =  https://pinafore.bolha.us&#xD;&#xA;pixelfed =  https://bolha.photos&#xD;&#xA;lemmy =  https://bolha.social&#xD;&#xA;writefreely =  https://bolha.blog&#xD;&#xA;bookwyrm =  https://bolha.review&#xD;&#xA;funkwhale =  https://bolha.studio&#xD;&#xA;friendica =  https://bolha.network&#xD;&#xA;&#xD;&#xA;Chat and video? We have it!&#xD;&#xA;    &#xD;&#xA;matrix =  https://bolha.chat&#xD;&#xA;jitsi =  https://bolha.video&#xD;&#xA;&#xD;&#xA;Translation tools&#xD;&#xA;&#xD;&#xA; libretranslate =  https://libretranslate.bolha.tools&#xD;&#xA; lingva =  https://translate.bolha.tools&#xD;&#xA;&#xD;&#xA;Video Platform Frontends&#xD;&#xA;&#xD;&#xA; invidious =  https://bolha.in&#xD;&#xA;&#xD;&#xA;Text Editors&#xD;&#xA;&#xD;&#xA; hedgeDoc =  https://notes.bolha.tools&#xD;&#xA; wise Mapping =  https://mindmap.bolha.tools&#xD;&#xA; overleaf =  https://overleaf.bolha.tools&#xD;&#xA; mermaid =  https://mermaid.bolha.tools&#xD;&#xA;&#xD;&#xA;You can also visit our hacking space!&#xD;&#xA;&#xD;&#xA;https://gcn.sh&#xD;&#xA;https://blog.gcn.sh&#xD;&#xA;&#xD;&#xA;Follow our founder!&#xD;&#xA;&#xD;&#xA;https://bolha.us/@gutocarvalho&#xD;&#xA;https://bolha.photos/@gutocarvalho&#xD;&#xA;https://bolha.forum@gutocarvalho&#xD;&#xA;https://bolha.blog/@gutocarvalho&#xD;&#xA;https://bolha.review/@gutocarvalho&#xD;&#xA;https://bolha.studio/@gutocarvalho&#xD;&#xA;https://bolha.network/@gutocarvalho&#xD;&#xA;matrix =  @bolha.chat@gutocarvalho&#xD;&#xA;&#xD;&#xA;Follow the status of our tools&#xD;&#xA;&#xD;&#xA;https://status.bolha.us&#xD;&#xA;&#xD;&#xA;Do you want to support us? You can!&#xD;&#xA;&#xD;&#xA;https://www.patreon.com/bolha&#xD;&#xA;https://apoia.se/bolha&#xD;&#xA;pix@bolha.us (local brazilian wire transfer)&#xD;&#xA;&#xD;&#xA;See you!&#xD;&#xA;&#xD;&#xA;[s]]]&gt;</description>
      <content:encoded><![CDATA[<h2 id="about-the-project" id="about-the-project">about the project</h2>

<p>Invidious is an open-source alternative front-end to YouTube.</p>
<ul><li>Privacy focused</li>
<li>Ethically designed</li>
<li>No Ads</li>
<li>Developer API</li>
<li>Multilingual</li>
<li>No need of an Youtube Account</li></ul>

<p>Visit the project</p>
<ul><li><a href="https://invidious.io" rel="nofollow">https://invidious.io</a></li>
<li><a href="https://docs.invidious.io" rel="nofollow">https://docs.invidious.io</a></li></ul>

<h2 id="installation-steps" id="installation-steps">installation steps</h2>

<p>generate a password for your postgresql.</p>

<pre><code>openssl rand -hex 15
</code></pre>

<p>create the directory</p>

<pre><code>mkdir -p /opt/invidious/data/postgresql
cd /opt/invidious/
</code></pre>

<p>clone the project</p>

<pre><code>git clone https://github.com/iv-org/invidious.git docker
cd docker
</code></pre>

<p>configure your installation</p>

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

<p>content</p>

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

  invidious:
    image: quay.io/invidious/invidious:latest
    restart: unless-stopped
    ports:
      - &#34;3000:3000&#34;
    environment:
      INVIDIOUS_CONFIG: |
        db:
          dbname: invidious
          user: kemal
          password: your_postgresql_password_here
          host: invidious-db
          port: 5432
        check_tables: true
    healthcheck:
      test: wget -nv --tries=1 --spider http://127.0.0.1:3000/api/v1/comments/jNQXAC9IVRw || exit 1
      interval: 30s
      timeout: 5s
      retries: 2
    logging:
      options:
        max-size: &#34;1G&#34;
        max-file: &#34;4&#34;
    depends_on:
      - invidious-db

  invidious-db:
    image: docker.io/library/postgres:14
    restart: unless-stopped
    volumes:
      - postgresdata:/var/lib/postgresql/data
      - ./config/sql:/config/sql
      - ./docker/init-invidious-db.sh:/docker-entrypoint-initdb.d/init-invidious-db.sh
    environment:
      POSTGRES_DB: invidious
      POSTGRES_USER: kemal
      POSTGRES_PASSWORD: your_postgresql_password_here
    healthcheck:
      test: [&#34;CMD-SHELL&#34;, &#34;pg_isready -U $$POSTGRES_USER -d $$POSTGRES_DB&#34;]

volumes:
  postgresql:
    driver_opts:
      type: none
      device: /opt/invidious/data/postgresql
      o: bind
</code></pre>

<p>start your invidious</p>

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

<p>visit your instance</p>

<pre><code>https://your_docker_host_ip:3000
</code></pre>

<p>nginx configuration example</p>

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

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

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

    access_log /var/log/nginx/tube-bolha-tools-access.log;
    error_log /var/log/nginx/tube-bolha-tools-error.log;

    location / {
        proxy_pass http://your_invidious_ip_here:your_port_here;
        proxy_set_header X-Forwarded-For $remote_addr;
        proxy_set_header Host $host;    # so Invidious knows domain
        proxy_http_version 1.1;     # to keep alive
        proxy_set_header Connection &#34;&#34;; # to keep alive
    }

}
</code></pre>

<p>Enjoy!</p>

<hr>

<h3 id="did-you-like-our-content" id="did-you-like-our-content">Did you like our content?</h3>

<p>We have a lot to share; visit our site!</p>
<ul><li><a href="https://bolha.io" rel="nofollow">https://bolha.io</a></li></ul>

<p>Our fediverse services ;)</p>
<ul><li>mastodon =&gt; <a href="https://bolha.us" rel="nofollow">https://bolha.us</a>
<ul><li>mastopoet =&gt; <a href="https://poet.bolha.us" rel="nofollow">https://poet.bolha.us</a></li>
<li>elk =&gt; <a href="https://elk.bolha.us" rel="nofollow">https://elk.bolha.us</a></li>
<li>pinafore =&gt; <a href="https://pinafore.bolha.us" rel="nofollow">https://pinafore.bolha.us</a></li></ul></li>
<li>pixelfed =&gt; <a href="https://bolha.photos" rel="nofollow">https://bolha.photos</a></li>
<li>lemmy =&gt; <a href="https://bolha.social" rel="nofollow">https://bolha.social</a></li>
<li>writefreely =&gt; <a href="https://bolha.blog" rel="nofollow">https://bolha.blog</a></li>
<li>bookwyrm =&gt; <a href="https://bolha.review" rel="nofollow">https://bolha.review</a></li>
<li>funkwhale =&gt; <a href="https://bolha.studio" rel="nofollow">https://bolha.studio</a></li>
<li>friendica =&gt; <a href="https://bolha.network" rel="nofollow">https://bolha.network</a></li></ul>

<p>Chat and video? We have it!</p>
<ul><li>matrix =&gt; <a href="https://bolha.chat" rel="nofollow">https://bolha.chat</a></li>
<li>jitsi =&gt; <a href="https://bolha.video" rel="nofollow">https://bolha.video</a></li></ul>

<p>Translation tools</p>
<ul><li>libretranslate =&gt; <a href="https://libretranslate.bolha.tools" rel="nofollow">https://libretranslate.bolha.tools</a></li>
<li>lingva =&gt; <a href="https://translate.bolha.tools" rel="nofollow">https://translate.bolha.tools</a></li></ul>

<p>Video Platform Frontends</p>
<ul><li>invidious =&gt; <a href="https://bolha.in" rel="nofollow">https://bolha.in</a></li></ul>

<p>Text Editors</p>
<ul><li>hedgeDoc =&gt; <a href="https://notes.bolha.tools" rel="nofollow">https://notes.bolha.tools</a></li>
<li>wise Mapping =&gt; <a href="https://mindmap.bolha.tools" rel="nofollow">https://mindmap.bolha.tools</a></li>
<li>overleaf =&gt; <a href="https://overleaf.bolha.tools" rel="nofollow">https://overleaf.bolha.tools</a></li>
<li>mermaid =&gt; <a href="https://mermaid.bolha.tools" rel="nofollow">https://mermaid.bolha.tools</a></li></ul>

<p>You can also visit our hacking space!</p>
<ul><li><a href="https://gcn.sh" rel="nofollow">https://gcn.sh</a></li>
<li><a href="https://blog.gcn.sh" rel="nofollow">https://blog.gcn.sh</a></li></ul>

<p>Follow our founder!</p>
<ul><li><a href="https://bolha.us/@gutocarvalho" rel="nofollow">https://bolha.us/@gutocarvalho</a></li>
<li><a href="https://bolha.photos/@gutocarvalho" rel="nofollow">https://bolha.photos/@gutocarvalho</a></li>
<li><a href="https://bolha.forum@gutocarvalho" rel="nofollow">https://bolha.forum@gutocarvalho</a></li>
<li><a href="https://bolha.blog/@gutocarvalho" rel="nofollow">https://bolha.blog/@gutocarvalho</a></li>
<li><a href="https://bolha.review/@gutocarvalho" rel="nofollow">https://bolha.review/@gutocarvalho</a></li>
<li><a href="https://bolha.studio/@gutocarvalho" rel="nofollow">https://bolha.studio/@gutocarvalho</a></li>
<li><a href="https://bolha.network/@gutocarvalho" rel="nofollow">https://bolha.network/@gutocarvalho</a></li>
<li>matrix =&gt; @bolha.chat@gutocarvalho</li></ul>

<p>Follow the status of our tools</p>
<ul><li><a href="https://status.bolha.us" rel="nofollow">https://status.bolha.us</a></li></ul>

<p>Do you want to support us? You can!</p>
<ul><li><a href="https://www.patreon.com/bolha" rel="nofollow">https://www.patreon.com/bolha</a></li>
<li><a href="https://apoia.se/bolha" rel="nofollow">https://apoia.se/bolha</a></li>
<li>pix@bolha.us (local brazilian wire transfer)</li></ul>

<p>See you!</p>

<p>[s]</p>
]]></content:encoded>
      <guid>https://blog.gcn.sh/howtos/installing-invidious-with-docker-on-ubuntu</guid>
      <pubDate>Wed, 14 Jun 2023 05:21:47 +0000</pubDate>
    </item>
  </channel>
</rss>