1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
|
<!DOCTYPE html>
<html
class="detail single" dir="ltr" lang="en-US">
<head>
<title>Install Gitea With Nginx, Postgresql On Ubuntu 18.04 - Luxagraf, Writing</title>
<meta charset="utf-8">
<meta http-equiv="x-ua-compatible" content="ie=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description"
content="None">
<meta name="author" content="Scott Gilbertson">
<!--[if IE]>
<script src="/js/html5css3ie.min.js"></script>
<![endif]-->
<link rel="alternate"
type="application/rss+xml"
title="Luxagraf RSS feed"
href="https://luxagraf.net/rss/">
<link rel="stylesheet"
href="/media/screenv9.css"
media="screen">
<!--[if IE]>
<link rel="stylesheet"
href="/media/css/ie.css"
media="screen">
<![endif]-->
<link rel="shortcut icon" href="favicon.ico" type="image/x-icon">
<link rel="manifest" href="/manifest.webmanifest" />
<link rel="stylesheet" href="/media/src/solarized.css" type="text/css" media="screen"/>
<link rel="canonical" href="https://luxagraf.net/tools/install-gitea-nginx-postgresql-ubuntu-1804" />
<meta property="og:type" content="article" />
<meta property="og:title" content="Install Gitea with Nginx, Postgresql on Ubuntu 18.04" />
<meta property="og:url" content="https://luxagraf.net/tools/install-gitea-nginx-postgresql-ubuntu-1804" />
<meta property="og:description" content="How to set up Gitea, a nice, open source, self-hosted alternative to GitHub and GitLab." />
<meta property="article:published_time" content="2018-10-12T14:14:05" />
<meta property="article:author" content="Scott Gilbertson" />
<meta property="og:site_name" content="Luxagraf" />
<meta property="og:image" content="" />
<meta property="og:locale" content="en_US" />
<meta name="twitter:card" content="summary_large_image"/>
<meta name="twitter:description" content="How to set up Gitea, a nice, open source, self-hosted alternative to GitHub and GitLab."/>
<meta name="twitter:title" content="Install Gitea with Nginx, Postgresql on Ubuntu 18.04"/>
<meta name="twitter:site" content="@luxagraf"/>
<meta name="twitter:domain" content="luxagraf"/>
<meta name="twitter:creator" content="@luxagraf"/>
</head>
<body class="src">
<div class="wrapper" id="wrapper">
<div class="header-wrapper">
<header role="banner">
<h1><a id="logo" href="/" title="home">Luxagraf</a></h1>
<h2>Walk Slowly</h2>
</header>
<nav role="navigation" class="bl">
<ul>
<li id="laverdad"><a href="/jrnl/" title="What we've been up to lately">Jrnl</a></li>
<li id="laverdad"><a href="/essays/" title="Writings">Essays</a></li>
<!--<li id="nota"><a href="/field-notes/" title="Quick notes and images from the road">Notes</a></li>
<li id="fotos"><a href="/photos/" title="Photos from travels around the world">Photos</a></li>i-->
<!--<li id="maps"><a href="/map" title="Maps">Map</a></li>-->
<li id="about"><a href="/about" title="About Luxagraf">About</a></li>
<li id="etc" class="last"><a href="/projects/" title="the less visible portions of the iceberg">More</a></li>
</ul>
</nav>
</div>
<main>
<article class="h-entry hentry " itemscope itemType="http://schema.org/Article">
<header id="header" class="post-header ">
<h1 class="p-name entry-title post-title" itemprop="headline">Install Gitea with Nginx, Postgresql on Ubuntu 18.04</h1>
<h2 class="post-subtitle">How to set up Gitea, a nice, open source, self-hosted alternative to GitHub and GitLab.</h2>
<h4 class="post-source">Originally Published By: <a href="" title="View Install Gitea with Nginx, Postgresql on Ubuntu 18.04 on "></a></h4>
<time class="dt-published published dt-updated post-date" datetime="2018-10-12T14:14:05" itemprop="datePublished">October <span>12, 2018</span></time>
<aside class="p-location h-adr adr post-location" itemprop="contentLocation" itemscope itemtype="http://schema.org/Place">
<span class="p-region"></span>, <a class="p-country-name country-name" href="/jrnl//" title="travel writing from "></a>
</aside>
</header>
<div id="article" class="e-content entry-content post--body post--body--" itemprop="articleBody">
<p>I’ve never liked hosting my git repos on someone else’s servers. GitHub especially is not a company I’d do business with, ever. I do have a repo or two hosted over at <a href="https://gitlab.com/luxagraf">GitLab</a> because those are projects I want to be easily available to anyone. But I store almost everything in git — notes, my whole documents folder, all my code projects, all my writing, pretty much everything is in git — but I like to keep all that private and on my own server.</p>
<p>For years I used <a href="http://gitlist.org/">Gitlist</a> because it was clean, simple, and did 95 percent of what I needed in a web-based interface for my repos. But Gitlist is abandonware at this point and broken if you’re using PHP 7.2. There are few forks that <a href="https://github.com/patrikx3/gitlist">patch it</a>, but it’s copyrighted to the original dev and I don’t want to depend on illegitimate forks for something so critical to my workflow. Then there’s self-hosted Gitlab, which I like, but the system requirements are ridiculous.</p>
<p>Some searching eventually led me to Gitea, which is lightweight, written in Go and has everything I need. </p>
<p>Here’s a quick guide to getting Gitea up and running on your Ubuntu 18.04 — or similar — VPS.</p>
<h3>Set up Gitea</h3>
<p>The first thing we’re going to do is isolate Gitea from the rest of our server, running it under a different user seems to be the standard practice. Installing Gitea via the Arch User Repository will create a <code>git</code> user, so that’s what I used on Ubuntu 18.04 as well. </p>
<p>Here’s a shell command to create a user named <code>git</code>:</p>
<pre class="highlight"><code class="language-console">sudo adduser --system --shell /bin/bash --group --disabled-password --home /home/git git</code></pre>
<p>This is pretty much a standard adduser command such as you’d use when setting up a new VPS, the only difference is that we’ve added the <code>--disable-password</code> flag so you can’t actually log in with it. While we will use this user to authenticate over SSH, we’ll do so with a key, not a password.</p>
<p>Now we need to grab the latest Gitea binary. At the time of writing that’s version 1.5.2, but be sure to check the <a href="https://dl.gitea.io/gitea/">Gitea downloads page</a> for the latest version and adjust the commands below to work with that version number. Let’s download the Gitea binary and then we’ll verify the signing key. Verifying keys is very important when working with binaries since you can’t see the code behind them<sup id="fnref:1"><a class="footnote-ref" href="#fn:1" rel="footnote">1</a></sup>.</p>
<pre class="highlight"><code class="language-console">wget -O gitea https://dl.gitea.io/gitea/1.5.2/gitea-1.5.2-linux-amd64
gpg --keyserver pgp.mit.edu --recv 0x2D9AE806EC1592E2
wget https://dl.gitea.io/gitea/1.5.2/gitea-1.5.2-linux-amd64.asc
gpg --verify gitea-1.5.2-linux-amd64.asc gitea</code></pre>
<p>A couple of notes here, GPG should say the keys match, but then it should also warn that “this key is not certified with a trusted signature!” That means, essentially, that this binary could have been signed by anybody. All we know for sure is that wasn’t tampered with in transit<sup id="fnref2:1"><a class="footnote-ref" href="#fn:1" rel="footnote">1</a></sup>.</p>
<p>Now let’s make the binary executable and test it to make sure it’s working:</p>
<pre class="highlight"><code class="language-console">chmod +x gitea
./gitea web</code></pre>
<p>You can stop Gitea with <code>Ctrl+C</code>. Let’s move the binary to a more traditional location:</p>
<pre class="highlight"><code class="language-console">sudo cp gitea /usr/local/bin/gitea</code></pre>
<p>The next thing we’re going to do is create all the directories we need. </p>
<pre class="highlight"><code class="language-console">sudo mkdir -p /var/lib/gitea/{custom,data,indexers,public,log}
sudo chown git:git /var/lib/gitea/{data,indexers,log}
sudo chmod 750 /var/lib/gitea/{data,indexers,log}
sudo mkdir /etc/gitea
sudo chown root:git /etc/gitea
sudo chmod 770 /etc/gitea</code></pre>
<p>That last line should make you nervous, that’s too permissive for a public directory, but don’t worry, as soon as we’re done setting up Gitea we’ll change the permissions on that directory and the config file inside it. </p>
<p>Before we do that though let’s create a systemd service file to start and stop Gitea. The Gitea project has a service file that will work well for our purposes, so let’s grab it, make a couple changes and then we’ll add it to our system:</p>
<pre class="highlight"><code class="language-console">wget https://raw.githubusercontent.com/go-gitea/gitea/master/contrib/systemd/gitea.service </code></pre>
<p>Now open that file and uncomment the line <code>After=postgresql.service</code> so that Gitea starts after postgresql is running. The resulting config file should look like this:</p>
<pre class="highlight"><code class="language-ini">[Unit]
Description=Gitea (Git with a cup of tea)
After=syslog.target
After=network.target
#After=mysqld.service
After=postgresql.service
#After=memcached.service
#After=redis.service
[Service]
# Modify these two values and uncomment them if you have
# repos with lots of files and get an HTTP error 500 because
# of that
###
#LimitMEMLOCK=infinity
#LimitNOFILE=65535
RestartSec=2s
Type=simple
User=git
Group=git
WorkingDirectory=/var/lib/gitea/
ExecStart=/usr/local/bin/gitea web -c /etc/gitea/app.ini
Restart=always
Environment=USER=git HOME=/home/git GITEA_WORK_DIR=/var/lib/gitea
# If you want to bind Gitea to a port below 1024 uncomment
# the two values below
###
#CapabilityBoundingSet=CAP_NET_BIND_SERVICE
#AmbientCapabilities=CAP_NET_BIND_SERVICE
[Install]
WantedBy=multi-user.target</code></pre>
<p>Now we need to move the service file to somewhere systemd expects it and then start and enable the service so Gitea will launch automatically when the server boots.</p>
<pre class="highlight"><code class="language-console">sudo cp gitea.service /etc/systemd/system/
sudo systemctl enable gitea
sudo systemctl start gitea</code></pre>
<p>There you have it, Gitea is installed, running and will automatically start whenever we restart the server. Now we need to set up Postgresql and then Nginx to serve up our Gitea site to the world. Or at least to us.</p>
<h3>Setup a Postgresql and Nginx</h3>
<p>Gitea needs a database to store all our data in; I use PostgreSQL. You can also use MySQL, but you’re on your own there. Install PostgreSQL if you haven’t already:</p>
<pre class="highlight"><code class="language-console">sudo apt install postgresql</code></pre>
<p>Now let’s create a new user and database for Gitea:</p>
<pre class="highlight"><code class="language-console">sudo su postgres
createuser gitea
createdb gitea -O gitea</code></pre>
<p>Exit the postgres user shell by hitting <code>Ctrl+D</code>. </p>
<p>Now let’s set up Nginx to serve our Gitea site. </p>
<pre class="highlight"><code class="language-console">sudo apt update
sudo apt install nginx</code></pre>
<p>For the next part you’ll need a domain name. I use a subdomain, git.mydomain.com, but for simplicity sake I’ll refer to <code>mydomain.com</code> for the rest of this tutorial. Replace <code>mydomain.com</code> in all the instructions below with your actual domain name.</p>
<p>We need to create a config file for our domain. By default Nginx will look for config files in <code>/etc/nginx/sites-enabled/</code>, so the config file we’ll create is:</p>
<pre class="highlight"><code class="language-console">nano /etc/nginx/sites-enabled/mydomain.com.conf</code></pre>
<p>Here’s what that file looks like:</p>
<pre class="highlight"><code class="language-nginx">server {
listen 80;
listen [::]:80;
server_name <mydomain.com>;
location / {
proxy_pass http://localhost:3000;
}
proxy_set_header X-Real-IP $remote_addr;
}</code></pre>
<p>The main line here is the <code>proxy_pass</code> bit, which takes all requests and sends it to gitea, which is listening on <code>localhost:3000</code> by default. You can change that if you have something else that conflicts with it, but you’ll need to change it here and in the service file that we used to start Gitea.</p>
<p>The last step is to add an SSL cert to our site so we can clone over https (and SSH if you keep reading). I have another tutorial on setting up <a href="/src/certbot-nginx-ubuntu-1804">Certbot for Nginx on Ubuntu</a>. You can use that to get Certbot installed and auto-renewing certs. Then all you need to do is run:</p>
<pre class="highlight"><code class="language-console">sudo certbot --nginx</code></pre>
<p>Select your Gitea domain, follow the prompts and when you’re done you’ll be ready to set up Gitea. </p>
<h3>Setting up Gitea</h3>
<p>Point your browser to <code>https://mydomain.com/install</code> and go through the Gitea setup process. That screen looks like this, and you can use these values, except for the domain name (and be sure to enter the password you used when we created the <code>gitea</code> user for postgresql).</p>
<p>One note, if you intend your Gitea instance to be for you alone, I strongly recommend you check the “disable self registration” box, which will stop anyone else from being able to sign up. But, turning off registration means you’ll need to create an administrator account at the bottom of the page. </p>
<div class="picwide">
<a href="http:///127.0.0.1:8066/media/images/original/2018/gitea-install_FAW0kIJ.jpg " title="view larger image">
<img sizes="(max-width: 1439px) 100vw, (min-width: 1440px) 1440px" srcset="http:///127.0.0.1:8066/media/images/2018/gitea-install_FAW0kIJ_picwide-med.jpg 1170w" alt="Gitea installation screen photographed by luxagraf" data-jslghtbx="http:///127.0.0.1:8066/media/images/original/2018/gitea-install_FAW0kIJ.jpg" data-jslghtbx-group="group" >
</a>
</div>
<p>Okay, now that we’ve got Gitea initialized it’s time to go back and change the permissions on those directories that we set up earlier.</p>
<pre class="highlight"><code class="language-console">sudo chmod 750 /etc/gitea
sudo chmod 644 /etc/gitea/app.ini</code></pre>
<p>Now you’re ready to create your first repo in Gitea. Click the little button next to the repositories menu on the right side of your Gitea dashboard and that’ll walk you through creating your first repo. Once that’s done you can clone that repo with:</p>
<pre class="highlight"><code class="language-console">git clone https://mydomain.com/giteausername/reponame.git</code></pre>
<p>Now if you have an existing repo that you want to push to your new Gitea repo, just edit the <code>.git/config</code> files to make your Gitea repo the new url, e.g.:</p>
<pre class="highlight"><code class="language-ini">[remote "origin"]
url = https://mydomain.com/giteausername/reponame.git
fetch = +refs/heads/*:refs/remotes/origin/*</code></pre>
<p>Now do this:</p>
<pre class="highlight"><code class="language-console">git push origin master </code></pre>
<h3>Setting up SSH</h3>
<p>Working with git over https is pretty good, but I prefer the more secure method of SSH with a key. To get that working we’ll need to add our SSH key to Gitea. That means you’ll need a GPG key. If you don’t have one already, open the terminal on your local machine and issue this command:</p>
<pre class="highlight"><code class="language-console">ssh-keygen -o -a 100 -t ed25519</code></pre>
<p>That will create a key named <code>id_ed25519</code> in the directory <code>.ssh/</code>. If you want to know where that command comes from, read <a href="https://blog.g3rt.nl/upgrade-your-ssh-keys.html">this article</a>.</p>
<p>Now we need to add that key to Gitea. First open the file <code>.ssh/id_ed25519.pub</code> and copy the contents to your clipboard. Now in the Gitea web interface, click on the user menu at the upper right and select “settings”. Then across the top you’ll see a bunch of tabs. Click the one that reads “SSH / GPG Keys”. Click the add key button, give your key a name and paste in the contents of the key.</p>
<p>Note: depending on how your VPS was set up, you may need to add the <code>git</code> user to your sshd config. Open <code>/etc/ssh/sshd_config</code> and look for a line that reads something like this:</p>
<pre class="highlight"><code class="language-console">AllowUsers myuser myotheruser git</code></pre>
<p>Add <code>git</code> to the list of allowed users so you’ll be able to authenticate with the git user over ssh. Now test SSH cloning with this line, substituting your SSH clone url:</p>
<pre class="highlight"><code class="language-console">git clone ssh://git@mydomain/giteausername/reponame.git</code></pre>
<p>Assuming that works then you’re all set, Gitea is working and you can create all the repos you need. If you have any problems you can drop a comment in the form below and I’ll do my best to help you out.</p>
<p>If you want to add some other niceties, the Gitea docs have a good guide to <a href="https://docs.gitea.io/en-us/fail2ban-setup/">setting up Fail2Ban for Gitea</a> and then there’s a whole section on <a href="https://docs.gitea.io/en-us/backup-and-restore/">backing up Gitea</a> that’s well worth a read.</p>
<div class="footnote">
<hr>
<ol>
<li id="fn:1">
<p>You can compile Gitea yourself if you like, there are <a href="https://docs.gitea.io/en-us/install-from-source/">instructions on the Gitea site</a>, but be forewarned its uses quite a bit of RAM to build. <a class="footnote-backref" href="#fnref:1" rev="footnote" title="Jump back to footnote 1 in the text">↩</a><a class="footnote-backref" href="#fnref2:1" rev="footnote" title="Jump back to footnote 1 in the text">↩</a></p>
</li>
</ol>
</div>
</div>
<div class="afterward">
<h4>Afterward</h4>
</div>
</article>
</main>
<p class="comments--header" style="text-align: center">Sorry, comments have been disabled for this post.</p>
<footer role="contentinfo">
<nav class="bl">
<ul>
<li><a href="/blogroll" title="Sites that inspire us">Blogroll</a></li>
<li><a href="/contact/" title="contact luxagraf">Contact</a></li>
<li>Follow Along:
<ul>
<li><a href="/jrnl/feed.xml" title="RSS feed">RSS</a></li>
<li><a href="/email/subscribe" title="Luxagraf Email Updates">Email</a></li>
<li><a href="https://twitter.com/luxagraf" rel="me" title="follow luxagraf on Twitter">Twitter</a></li>
<li><a href="https://www.facebook.com/luxagraf" rel="me" title="luxagraf on Facebook">Facebook</a></li>
</ul>
</ul>
<div class="support">Support luxagraf:
<div class="donate-btn">
<form action="https://www.paypal.com/cgi-bin/webscr" method="post" target="_top">
<input type="hidden" name="cmd" value="_s-xclick">
<input type="hidden" name="hosted_button_id" value="HYJFZQSBGJ8QQ">
<input type="submit" name="submit" alt="Donate to luxagraf via PayPal">
</form>
</div>
<div class="donate-btn">
<a class="liberapay-btn" href="https://liberapay.com/luxagraf/donate"><span>Donate</span></a>
</div>
</div>
</nav>
<p id="license">
© 2003-2019
<span class="h-card"><a class="p-name u-url" href="https://luxagraf.net/">Scott Gilbertson</a><data class="p-nickname" value="luxagraf"></data><data class="p-locality" value="Athens"></data><data class="p-region" value="Georgia"></data><data class="p-country-name" value="United States"></data></span>, except photos, which are licensed under the Creative Commons (<a href="http://creativecommons.org/licenses/by-sa/3.0/" title="read the Attribution-Share Alike 3.0 deed">details</a>).
</p>
</footer>
</div>
<script type="text/javascript">
document.addEventListener("DOMContentLoaded", function(event) {
var leaflet = document.createElement('script');
leaflet.src = "/media/js/leaflet-master/leaflet-mod.js";
document.body.appendChild(leaflet);
var lightbox = document.createElement('script');
lightbox.src = "/media/js/lightbox.js";
document.body.appendChild(lightbox);
leaflet.onload = function(){
var detail = document.createElement('script');
detail.src = "/media/js/detail.min.js";
document.body.appendChild(detail);
}
lightbox.onload = function() {
var opts= {
//nextOnClick: false,
captions: true,
onload: function(){
var im = document.getElementById("jslghtbx-contentwrapper");
var link = im.appendChild(document.createElement('a'))
link.href = im.firstChild.src;
link.innerHTML= "open ";
link.target = "_blank";
link.setAttribute('class', 'p-link');
im.appendChild(link);
}
};
var lightbox = new Lightbox();
lightbox.load(opts);
}
});
</script>
<script>
// Register our service-worker
if (navigator.serviceWorker) {
window.addEventListener('load', function() {
if (navigator.serviceWorker.controller) {
navigator.serviceWorker.controller.postMessage({'command': 'trimCaches'});
} else {
navigator.serviceWorker.register('/media/js/serviceworker.js', {
scope: '/'
});
}
});
}
</script>
</body>
</html>
|