website/blog/gentle-introduction-to-the-.../index.html

429 lines
26 KiB
HTML
Raw Permalink Normal View History

2022-09-06 13:34:25 +00:00
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width" />
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png" />
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png" />
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png" />
<link rel="manifest" href="/site.webmanifest" />
<link rel="me" href="https://pouet.chapril.org/@gna" />
<link rel="stylesheet" href="https://gna.org/main.css" />
<link
rel="stylesheet"
media="screen and (max-width: 1300px)"
href="https://gna.org/mobile.css"
/>
<meta name="referrer" content="no-referrer-when-downgrade" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="stylesheet" href="https://gna.org/main.css" />
<link
rel="stylesheet"
media="screen and (max-width: 1300px)"
href="https://gna.org/mobile.css"
/>
<meta name="referrer" content="no-referrer-when-downgrade" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
2023-01-09 09:59:43 +00:00
<title>[tutorial] A gentle introduction to the gitea doctor | Gna!: Managed Forgejo Hosting </title>
2022-09-06 13:34:25 +00:00
<meta name="referrer" content="no-referrer-when-downgrade" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="description" content="The doctor command is useful to check the health of a running Gitea instance. Specially after performing an upgrade." />
2023-01-09 09:59:43 +00:00
<meta property="og:title" content="[tutorial] A gentle introduction to the gitea doctor | Gna!: Managed Forgejo Hosting " />
2022-09-06 13:34:25 +00:00
<meta property="og:type" content="article" />
<meta property="og:url" content="https:&#x2F;&#x2F;gna.org" />
<meta property="og:description" content="The doctor command is useful to check the health of a running Gitea instance. Specially after performing an upgrade." />
<meta
property="og:site_name"
2023-01-09 09:59:43 +00:00
content="[tutorial] A gentle introduction to the gitea doctor | Gna!: Managed Forgejo Hosting "
2022-09-06 13:34:25 +00:00
/>
<link
rel="apple-touch-icon"
sizes="57x57"
href="https://gna.org/apple-icon-57x57.png?h=c21de14cfdf862a6472ae977557fa048a7c36d39337e61d3274705e9bd8e857f"
/>
<link
rel="apple-touch-icon"
sizes="60x60"
href="https://gna.org/apple-icon-60x60.png?h=67089d9025a52d0d1ddce450078c7acefe2c150a2427dec9f5e13c6314f74281"
/>
<link
rel="apple-touch-icon"
sizes="72x72"
href="https://gna.org/apple-icon-72x72.png?h=70725943de8884804f9da28202ced0ad6fed483ae9cf8f6d874aa133e30cb693"
/>
<link
rel="apple-touch-icon"
sizes="76x76"
href="https://gna.org/apple-icon-76x76.png?h=1e6e8072df3b21bdcea254a42aac6e993611e845f91ddd79f6f35a6c441710a5"
/>
<link
rel="apple-touch-icon"
sizes="114x114"
href="https://gna.org/apple-icon-114x114.png?h=c20099f8190ed3962fab5726c5594857a871cdb3ee98439343c622cd3727fed6"
/>
<link
rel="apple-touch-icon"
sizes="120x120"
href="https://gna.org/apple-icon-120x120.png?h=4df78e402e60b58c6d44764678bdd737b5b6a836aeb85fb75fa49f706f7e8c81"
/>
<link
rel="apple-touch-icon"
sizes="144x144"
href="https://gna.org/apple-icon-144x144.png?h=0c44e6655d714f89ee95cc151032d1f0dc3204bd24d1ca2ee9d94692d4ede84d"
/>
<link
rel="apple-touch-icon"
sizes="152x152"
href="https://gna.org/apple-icon-152x152.png?h=157918f883ff95d4eeb6452d0ebb61ca5e21ea0dcac1aefe825f3e2f3999052f"
/>
<link
rel="apple-touch-icon"
sizes="180x180"
href="https://gna.org/apple-icon-180x180.png?h=7d5c16d379b7db6d8ea5aae64921d7162b84f543763acd8fc7c107f80a600213"
/>
<link
rel="icon"
type="image/png"
sizes="192x192"
href="https://gna.org/android-icon-192x192.png?h=095e3835b082dba07f606c33fa6f71bcd671a71e987b0ab2e46dcddceef52b9c"
/>
<link
rel="icon"
type="image/png"
sizes="32x32"
href="https://gna.org/favicon-32x32.png?h=1bf54bf111572b1d1639192b5360ee4345f702e563aa71bb66610a95a7290437"
/>
<link
rel="icon"
type="image/png"
sizes="96x96"
href="https://gna.org/favicon-96x96.png?h=5a6ed96c09f5055526e3b236867a1272a26f7ba957d48b267bccd51ef0845fbe"
/>
<link
rel="icon"
type="image/png"
sizes="16x16"
href="https://gna.org/favicon-16x16.png?h=1e5fa59ae78516055f662e40bb2599dc3828a7adb34567e9d8d2cfcaa6b7aa5f"
/>
<link
rel="manifest"
href="https://gna.org/manifest.json?h=27eca3e8297eb7ff340deb3849b210185a459b3845456aa4d0036f6d966b3518"
/>
<meta name="msapplication-TileColor" content="#ffffff" />
<meta
name="msapplication-TileImage"
content="https://gna.org/ms-icon-144x144.png?h=8170ab51b871b84b8f98bd03cf441afdffb2998b7dfffb04abb7ebf5deeb1f94"
/>
<meta name="theme-color" content="#ffffff" />
</head>
</head>
<body class="base">
<header>
<nav class="nav__container">
<input type="checkbox" class="nav__toggle" id="nav__toggle" />
<div class="nav__header">
<a class="nav__logo-container" href="/">
<img src="https://gna.org/gna-logo-rectangle-48px.png?h=ba9eab043277265f94c51b87d5e14f9ca35789403ecb8afc9bd1e33b13c6a2a5" alt="Gna!"/>
</a>
<label class="nav__hamburger-menu" for="nav__toggle">
<span class="nav__hamburger-inner"></span>
</label>
</div>
<div class="nav__spacer--small"></div>
<div class="nav__link-group">
<div class="nav__link-container">
<a class="nav__link" rel="noreferrer" href="&#x2F;about&#x2F;">About</a>
</div>
<div class="nav__link-container">
<a class="nav__link" rel="noreferrer" href="&#x2F;blog&#x2F;">Blog</a>
</div>
<div class="nav__link-container">
<a class="nav__link" rel="noreferrer" href="https:&#x2F;&#x2F;matrix.to&#x2F;#&#x2F;#gna:matrix.batsense.net">Chat</a>
</div>
<div class="nav__link-container">
2023-01-09 09:59:43 +00:00
<a class="nav__link" rel="noreferrer" href="&#x2F;forgejo-clinic&#x2F;">Clinic</a>
2022-09-06 13:34:25 +00:00
</div>
<div class="nav__link-container">
<a class="nav__link" rel="noreferrer" href="https:&#x2F;&#x2F;forum.gna.org">Forum</a>
</div>
<div class="nav__link-container">
<a class="nav__link" rel="noreferrer" href="https:&#x2F;&#x2F;pouet.chapril.org&#x2F;@gna">Mastodon</a>
</div>
</div>
<div class="nav__spacer"></div>
<div class="nav__link-group--small">
<div class="nav__link-container">
<a class="nav__link" rel="noreferrer" href="https:&#x2F;&#x2F;hosteadashboard.gna.org&#x2F;login&#x2F;">Login</a>
</div>
<div class="nav__link-container--action">
<a class="nav__link" rel="noreferrer" href="https:&#x2F;&#x2F;hosteadashboard.gna.org&#x2F;register&#x2F;">Join</a>
</div>
</div>
</nav>
</header>
<!-- See ../sass/main.scss. Required for pushing footer to the very
bottom of the page -->
<div class="main__content-container">
<main>
<div class="page__container">
<h1 class="page__group-title">[tutorial] A gentle introduction to the gitea doctor</h1>
<p class="blog__post-meta">
<a href="https:&#x2F;&#x2F;dachary.org" class="post__author">Loïc Dachary</a>
&middot; 14
June
,
2022 &middot; <b>7 min read</b>
</p>
<div class="blog__content">
<p>While helping people with their upgrades <a href="https://discourse.gitea.io/t/migration-from-1-2-to-1-16-8/5309">in the Gitea forum</a> or <a href="https://forum.gna.org/t/gitea-upgrade-from-1-14-1-to-1-16-8/90">at the Gna! clinic</a>, I realized that few Gitea admins know about the <a href="https://docs.gitea.io/en-us/command-line/#doctor"><code>gitea doctor</code></a> command and decided to write this blog post as a gentle introduction.</p>
<h3 id="an-apple-a-day-keeps-the-doctor-away">An apple a day keeps the doctor away<a class="zola-anchor" href="#an-apple-a-day-keeps-the-doctor-away" aria-label="Anchor link for: an-apple-a-day-keeps-the-doctor-away"
><span class="anchor-icon">#</span></a
>
</h3>
<p>Or in our case, Gitea versions <a href="https://github.com/go-gitea/gitea/blob/v1.11.5/cmd/doctor.go">below 1.11.5</a>. Since then, the <code>gitea doctor</code> is available and is designed to run against a specific Gitea version. It would not be a good idea to try to run the doctor from Gitea 1.16 to verify the sanity of a Gitea 1.2 instance: it will be confused by how the database is organized and a number of other details. Historical fun fact: the <code>gitea doctor</code> was backported to <a href="https://github.com/go-gitea/gitea/blob/v1.10.5/cmd/doctor.go">Gitea 1.10.5</a> and <a href="https://github.com/go-gitea/gitea/blob/v1.10.6/cmd/doctor.go">Gitea 1.10.6</a> and may be of help if you run this particular version and are facing the problem that motivated the backport.</p>
<p>With each version <code>gitea doctor</code> improves and gains new capabilities. For instance, in Gitea 1.17 it becomes aware of <a href="https://github.com/go-gitea/gitea/pull/19731">orphaned pull requests</a> and is able to fix them. If such a problem exists in Gitea 1.16, it does not know about it.</p>
<h3 id="calling-the-doctor">Calling the doctor<a class="zola-anchor" href="#calling-the-doctor" aria-label="Anchor link for: calling-the-doctor"
><span class="anchor-icon">#</span></a
>
</h3>
<p>In the following, examples are based on a Gitea 1.16.8 instance you can run as follows:</p>
<pre data-lang="bash" style="background-color:#2b303b;color:#c0c5ce;" class="language-bash "><code class="language-bash" data-lang="bash"><span style="color:#bf616a;">$</span><span> docker run</span><span style="color:#bf616a;"> --name</span><span> gitea</span><span style="color:#bf616a;"> -p</span><span> 3000:3000</span><span style="color:#bf616a;"> -e</span><span> GITEA__security__INSTALL_LOCK=true</span><span style="color:#bf616a;"> -d</span><span> gitea/gitea:1.16.8-rootless
</span><span style="color:#bf616a;">$</span><span> docker exec gitea gitea admin user create</span><span style="color:#bf616a;"> --admin --username</span><span> root</span><span style="color:#bf616a;"> --password</span><span> admin1234</span><span style="color:#bf616a;"> --email</span><span> root@example.com
</span><span style="color:#bf616a;">$</span><span> docker exec gitea mkdir /var/lib/gitea/data/log
</span></code></pre>
<p>And then you can go to the <a href="https://127.0.0.1:3000/">web interface</a> to create a <code>test</code> repository, with an initial <code>README.md</code> file. When this is done the doctor can be called as follows:</p>
<pre data-lang="bash" style="background-color:#2b303b;color:#c0c5ce;" class="language-bash "><code class="language-bash" data-lang="bash"><span style="color:#bf616a;">$</span><span> docker exec gitea gitea doctor</span><span style="color:#bf616a;"> --all
</span><span style="color:#bf616a;">[1]</span><span> Check paths and basic configuration
</span><span> </span><span style="color:#bf616a;">- </span><span style="color:#b48ead;">[</span><span>I</span><span style="color:#b48ead;">]</span><span> Configuration File Path: &quot;</span><span style="color:#a3be8c;">/etc/gitea/app.ini</span><span>&quot;
</span><span> </span><span style="color:#bf616a;">- </span><span style="color:#b48ead;">[</span><span>I</span><span style="color:#b48ead;">]</span><span> Repository Root Path: &quot;</span><span style="color:#a3be8c;">/var/lib/gitea/git/repositories</span><span>&quot;
</span><span> </span><span style="color:#bf616a;">- </span><span style="color:#b48ead;">[</span><span>I</span><span style="color:#b48ead;">]</span><span> Data Root Path: &quot;</span><span style="color:#a3be8c;">/var/lib/gitea</span><span>&quot;
</span><span> </span><span style="color:#bf616a;">- </span><span style="color:#b48ead;">[</span><span>I</span><span style="color:#b48ead;">]</span><span> Custom File Root Path: &quot;</span><span style="color:#a3be8c;">/var/lib/gitea/custom</span><span>&quot;
</span><span> </span><span style="color:#bf616a;">- </span><span style="color:#b48ead;">[</span><span>I</span><span style="color:#b48ead;">]</span><span> Work directory: &quot;</span><span style="color:#a3be8c;">/var/lib/gitea</span><span>&quot;
</span><span> </span><span style="color:#bf616a;">- </span><span style="color:#b48ead;">[</span><span>I</span><span style="color:#b48ead;">]</span><span> Log Root Path: &quot;</span><span style="color:#a3be8c;">/var/lib/gitea/data/log</span><span>&quot;
</span><span style="color:#bf616a;">OK
</span><span style="color:#bf616a;">[2]</span><span> Check if there is garbage storage files
</span><span style="color:#bf616a;">OK
</span><span style="color:#bf616a;">[3]</span><span> Check Database Version
</span><span style="color:#bf616a;">OK
</span><span style="color:#bf616a;">[4]</span><span> Check consistency of database
</span><span style="color:#bf616a;">OK
</span><span style="color:#bf616a;">[5]</span><span> Check if user with wrong type exist
</span><span style="color:#bf616a;">OK
</span><span style="color:#bf616a;">[6]</span><span> Check if OpenSSH authorized_keys file is up-to-date
</span><span style="color:#bf616a;">OK
</span><span style="color:#bf616a;">[7]</span><span> Check if SCRIPT_TYPE is available
</span><span> </span><span style="color:#bf616a;">- </span><span style="color:#b48ead;">[</span><span>I</span><span style="color:#b48ead;">]</span><span> ScriptType bash is on the current PATH at /bin/bash
</span><span style="color:#bf616a;">OK
</span><span style="color:#bf616a;">[8]</span><span> Check if hook files are up-to-date and executable
</span><span style="color:#bf616a;">OK
</span><span style="color:#bf616a;">[9]</span><span> Recalculate Stars number for all user
</span><span style="color:#bf616a;">OK
</span><span style="color:#bf616a;">[10]</span><span> Check old archives
</span><span> </span><span style="color:#bf616a;">- </span><span style="color:#b48ead;">[</span><span>I</span><span style="color:#b48ead;">]</span><span> 0 old archives in repository need to be deleted
</span><span style="color:#bf616a;">OK
</span><span style="color:#bf616a;">[11]</span><span> Enable push options
</span><span> </span><span style="color:#bf616a;">- </span><span style="color:#b48ead;">[</span><span>I</span><span style="color:#b48ead;">]</span><span> Checked 1 repositories, 0 need updates.
</span><span style="color:#bf616a;">OK
</span><span style="color:#bf616a;">[12]</span><span> Check for incorrectly dumped repo_units (See </span><span style="color:#65737e;">#16961)
</span><span> </span><span style="color:#bf616a;">- </span><span style="color:#b48ead;">[</span><span>W</span><span style="color:#b48ead;">]</span><span> Found 0 broken repo_units
</span><span style="color:#bf616a;">OK
</span><span style="color:#bf616a;">[13]</span><span> Recalculate merge bases
</span><span> </span><span style="color:#bf616a;">- </span><span style="color:#b48ead;">[</span><span>W</span><span style="color:#b48ead;">]</span><span> 0 PRs with incorrect mergebases of 0 PRs total in 1 repos
</span><span style="color:#bf616a;">OK
</span><span style="color:#bf616a;">[14]</span><span> Check git-daemon-export-ok files
</span><span> </span><span style="color:#bf616a;">- </span><span style="color:#b48ead;">[</span><span>I</span><span style="color:#b48ead;">]</span><span> Checked 1 repositories, 0 need updates.
</span></code></pre>
<h3 id="what-does-the-doctor-know">What does the doctor know?<a class="zola-anchor" href="#what-does-the-doctor-know" aria-label="Anchor link for: what-does-the-doctor-know"
><span class="anchor-icon">#</span></a
>
</h3>
<p>Although the <code>doctor</code> can be compared to <a href="https://en.wikipedia.org/wiki/Fsck">fsck(8)</a>, it does not know everything. It took decades for <code>fsck</code> to become the ultimate authority on finding problems on file systems and reliably fixing them without losing data. Nowadays, only a handful of people in the world are brave enough to manually attempt a file system recovery when <code>fsck</code> cannot recover from a data loss.</p>
<p>The first <code>doctor</code> version is two years old and Gitea admins are still routinely running SQL queries against the database or moving files around when trying to figure out why a Gitea instance is not behaving as it should. It is however worth checking if the doctor does not already have a solution by listing all it can do:</p>
<pre data-lang="bash" style="background-color:#2b303b;color:#c0c5ce;" class="language-bash "><code class="language-bash" data-lang="bash"><span style="color:#bf616a;">$</span><span> docker exec gitea gitea doctor</span><span style="color:#bf616a;"> --list
</span><span style="color:#bf616a;">Default</span><span> Name Title
</span><span style="color:#bf616a;">*</span><span> paths Check paths and basic configuration
</span><span> </span><span style="color:#bf616a;">storages</span><span> Check if there is garbage storage files
</span><span style="color:#bf616a;">*</span><span> check-db-version Check Database Version
</span><span> </span><span style="color:#bf616a;">check-db-consistency</span><span> Check consistency of database
</span><span style="color:#bf616a;">*</span><span> check-user-type Check if user with wrong type exist
</span><span style="color:#bf616a;">*</span><span> authorized-keys Check if OpenSSH authorized_keys file is up-to-date
</span><span> </span><span style="color:#bf616a;">script-type</span><span> Check if SCRIPT_TYPE is available
</span><span> </span><span style="color:#bf616a;">hooks</span><span> Check if hook files are up-to-date and executable
</span><span> </span><span style="color:#bf616a;">recalculate-stars-number</span><span> Recalculate Stars number for all user
</span><span> </span><span style="color:#bf616a;">check-old-archives</span><span> Check old archives
</span><span> </span><span style="color:#bf616a;">enable-push-options</span><span> Enable push options
</span><span> </span><span style="color:#bf616a;">fix-broken-repo-units</span><span> Check for incorrectly dumped repo_units (See </span><span style="color:#65737e;">#16961)
</span><span> </span><span style="color:#bf616a;">recalculate-merge-bases</span><span> Recalculate merge bases
</span><span> </span><span style="color:#bf616a;">check-git-daemon-export-ok</span><span> Check git-daemon-export-ok files
</span></code></pre>
<p>And then call the <code>check</code> that looks interesting:</p>
<pre data-lang="bash" style="background-color:#2b303b;color:#c0c5ce;" class="language-bash "><code class="language-bash" data-lang="bash"><span style="color:#bf616a;">$</span><span> docker exec gitea gitea doctor</span><span style="color:#bf616a;"> --run</span><span> authorized-keys
</span><span style="color:#bf616a;">[1]</span><span> Check if OpenSSH authorized_keys file is up-to-date
</span><span style="color:#bf616a;">OK
</span></code></pre>
<p>The challenge is to figure out which <code>check</code> does what and at the moment the best source of information is ... <a href="https://github.com/go-gitea/gitea/tree/v1.16.8">the sources</a> themselves. The <a href="https://github.com/go-gitea/gitea/blob/v1.16.8/cmd/doctor.go">doctor.go</a> command is the entry point and <a href="https://github.com/go-gitea/gitea/tree/v1.16.8/modules/doctor">the doctor directory</a> contains the rest.</p>
<p>Some <code>checks</code> are straightforward to understand, even if you do not know Go, such as <a href="https://github.com/go-gitea/gitea/blob/v1.16.8/modules/doctor/authorizedkeys.go">the authorized-keys check</a>. Others are much more involved and your best chance is to <a href="https://matrix.to/#/#gitea:matrix.org">ask the Gitea chatroom</a> for help.</p>
<h3 id="is-it-going-to-hurt">Is it going to hurt?<a class="zola-anchor" href="#is-it-going-to-hurt" aria-label="Anchor link for: is-it-going-to-hurt"
><span class="anchor-icon">#</span></a
>
</h3>
<p>By default the doctor (very much like <code>fsck -N</code>) only performs non destructive checks and displays diagnostics, with an indication of how serious the problem is. In the example above, there only are lines with <strong>[I]</strong> (which indicates an information) and <strong>[W]</strong> which indicates a warning that can be ignored but may be worth looking into. Those two warnings are actually just informational and should be labelled as <strong>[I]</strong>, <a href="https://github.com/go-gitea/gitea/pull/19836">which has been fixed</a> in a more recent version of the doctor.</p>
<p>Now let's do something bad: remove the permissions from a hook in our repository:</p>
<pre data-lang="bash" style="background-color:#2b303b;color:#c0c5ce;" class="language-bash "><code class="language-bash" data-lang="bash"><span style="color:#bf616a;">$</span><span> docker exec gitea chmod</span><span style="color:#bf616a;"> -x</span><span> /var/lib/gitea/git/repositories/root/test.git/hooks/post-receive
</span></code></pre>
<p>Run the doctor with the <code>check</code> supposed to find that out:</p>
<pre data-lang="bash" style="background-color:#2b303b;color:#c0c5ce;" class="language-bash "><code class="language-bash" data-lang="bash"><span style="color:#bf616a;">$</span><span> docker exec gitea gitea doctor</span><span style="color:#bf616a;"> --run</span><span> hooks
</span><span style="color:#bf616a;">[1]</span><span> Check if hook files are up-to-date and executable
</span><span> </span><span style="color:#bf616a;">- </span><span style="color:#b48ead;">[</span><span>W</span><span style="color:#b48ead;">]</span><span> old hook file /var/lib/gitea/git/repositories/root/test.git/hooks/post-receive is not executable
</span></code></pre>
<p>Ask it to fix this with the <code>--fix</code> flag:</p>
<pre data-lang="bash" style="background-color:#2b303b;color:#c0c5ce;" class="language-bash "><code class="language-bash" data-lang="bash"><span style="color:#bf616a;">$</span><span> docker exec gitea gitea doctor</span><span style="color:#bf616a;"> --run</span><span> hooks</span><span style="color:#bf616a;"> --fix
</span><span style="color:#bf616a;">[1]</span><span> Check if hook files are up-to-date and executable
</span><span> </span><span style="color:#bf616a;">- </span><span style="color:#b48ead;">[</span><span>W</span><span style="color:#b48ead;">]</span><span> Regenerated hooks for root/test
</span><span> </span><span style="color:#bf616a;">- </span><span style="color:#b48ead;">[</span><span>W</span><span style="color:#b48ead;">]</span><span> old hook file /var/lib/gitea/git/repositories/root/test.git/hooks/post-receive is not executable
</span></code></pre>
<p>And run it one last time to check all is well:</p>
<pre data-lang="bash" style="background-color:#2b303b;color:#c0c5ce;" class="language-bash "><code class="language-bash" data-lang="bash"><span style="color:#bf616a;">$</span><span> docker exec gitea gitea doctor</span><span style="color:#bf616a;"> --run</span><span> hooks
</span><span style="color:#bf616a;">[1]</span><span> Check if hook files are up-to-date and executable
</span><span style="color:#bf616a;">OK
</span></code></pre>
<p>Even when the doctor is unable to fix a problem, it can help by showing extensive debug output which can be found, by default, in the <code>doctor.log</code> file in the directory from which it runs. Or it can be displayed on the standard output with <code>--log-file -</code>, which is most convenient when running in docker.</p>
<h3 id="going-further">Going further<a class="zola-anchor" href="#going-further" aria-label="Anchor link for: going-further"
><span class="anchor-icon">#</span></a
>
</h3>
<p>If that was helpful to you, I would very much appreciate if you <a href="https://mastodon.online/@dachary">send me a message on Mastodon</a>. It will encourage me to write more blog posts to share what I learn about Gitea. Even better: you could <a href="https://github.com/go-gitea/gitea/pulls">send a pull request</a> to improve the doctor and help it mature.</p>
</div>
<br>
<br>
<div class="blog__post-tag-container">
<a class="blog__post-tag" href="/tags/gna">#gna</a>
<a class="blog__post-tag" href="/tags/gitea">#gitea</a>
<a class="blog__post-tag" href="/tags/troubleshoot">#troubleshoot</a>
<a class="blog__post-tag" href="/tags/problem">#problem</a>
<a class="blog__post-tag" href="/tags/tutorial">#tutorial</a>
</div>
</div>
</main>
<footer>
<div class="footer__container">
<!-- <div class="footer__column"> --->
<p class="footer__column license__conatiner">
All text <a
class="license__link"
rel="noreferrer"
href="http://creativecommons.org/licenses/by-sa/4.0/"
target="_blank"
>&nbsp;CC-BY-SA&nbsp;</a
>
&amp; code
<a
class="license__link"
rel="noreferrer"
href="https://www.gnu.org/licenses/agpl-3.0.en.html"
target="_blank"
>&nbsp;AGPL&nbsp;</a
>
|
<a
class="license__link"
rel="noreferrer"
href="https://www.eff.org/issues/do-not-track/amp/"
target="_blank"
>&nbsp;No AMP&nbsp;</a
>
</p>
<!-- </div> -->
<div class="footer__column--center">
<a href="/blog/atom.xml" target="_blank" rel="noopener" title="RSS">
<img
src="https://gna.org/icons/rss.svg?h=f6cd584bdbcd2eb4d1b8b84c9cf083ef45f772167c33fdcee754b35ae8ff4c7d"
class="footer__icon"
alt="Email icon"
/>
</a>
</div>
<div class="footer__column">
<a href="/about" title="About">About</a>
<a href="/coc" title="Code of Conduct">CoC</a>
<span class="footer__column-divider--mobile-only">|</span>
<a href="/legalese" title="Legalese">Legalese</a>
<a href="/privacy-policy" title="Privacy Policy">Privacy</a>
<span class="footer__column-divider--mobile-only">|</span>
<a
2023-01-09 09:59:43 +00:00
href="https://forgejo.gna.org/Gna"
2022-09-06 13:34:25 +00:00
rel="noreferrer"
target="_blank"
title="Status"
>Source Code</a
>
<a href="/tos" title="Terms of Service">ToS</a>
</div>
</div>
</footer>
</div>
</body>
</html>