Version 21.1 by Alexandru Pentilescu on 2024/07/16 22:38

Hide last authors
Alexandru Pentilescu 5.1 1 {{box cssClass="floatinginfobox" title="**Contents**"}}
2 {{toc /}}
3 {{/box}}
Alexandru Pentilescu 1.1 4
5 = Basic installation =
Alexandru Pentilescu 5.1 6
Alexandru Pentilescu 1.1 7 To setup a gitea server using docker, the following docker-compose.yml file shall be used:
8
9 {{code language="yaml"}}
10 version: '2'
11
12 networks:
13 gitea:
14 external: false
15
16 services:
17 web:
18 image: gitea/gitea:latest
19 environment:
20 - USER_UID=1002
21 - USER_GID=1002
22 volumes:
23 - ./data:/data
24 - /home/git/.ssh/:/data/git/.ssh
25 ports:
26 - "3000:3000"
27 - "2200:22"
28 depends_on:
29 - db
30 restart: always
31 networks:
32 - gitea
33 db:
34 image: mariadb
35 restart: always
36 environment:
37 - MYSQL_ROOT_PASSWORD=<redacted>
38 - MYSQL_DATABASE=gitea
39 - MYSQL_USER=gitea
40 - MYSQL_PASSWORD=<redacted>
41 volumes:
42 - ./db/:/var/lib/mysql
43 networks:
44 - gitea
45 {{/code}}
Alexandru Pentilescu 3.1 46
47 What the above docker-compose configuration will do is that it will, in essence, create two, always on, services, that will forever be restarted: a mariadb database server that will write all of its data to a local "db" directory, and another web service that will server as the main git server and the web server alongside it.
48
49 Before starting the docker services, please create the necessary resources first.
50
51 = Create the required local directories to store the data in =
52
53 Do a simple command to create the necessary directories:
54
Alexandru Pentilescu 5.1 55 {{code language="bash"}}mkdir data db{{/code}}
Alexandru Pentilescu 3.1 56 Backing up just these two directories should, in theory, be enough to allow for full restoration of all git repository resources into the future. **WARNING: This has not been tested yet!!!**
57
58 = Create a separate git user to login into via SSH =
Alexandru Pentilescu 5.1 59
Alexandru Pentilescu 3.1 60 Creating a separate user, technically, is unnecessary, but it makes the configuration more conventional.
61
62 {{code language="bash"}}
63 useradd -m -u 1002 git
64 {{/code}}
65
66 Assuming the 1002 UID is already assigned to a different user, feel free to use a different UID (**be sure to update the yaml configuration with the proper user ID, then**).
67
68 Once this configuration has been done, go ahead and generate an /home/git/.ssh/ directory for the user to have. Be sure to chown this specific directory to the git user as appropriate:
69
70 {{code language="bash"}}
71 chown git:git -R /home/git/.ssh/
72 chmod 700 /home/git/.ssh/
73 {{/code}}
Alexandru Pentilescu 4.1 74
75 Once all these steps are done, you can proceed to the next step.
76
77 = Spin up a container from the docker image =
78
79 {{code language="bash"}}
80 docker-compose up -d
81 {{/code}}
82
83 Had all the necessary steps been done properly, this should yield a fully functional container. If there are any errors encountered by this point, please fix them before proceeding.
84
85 = Set up a proper nginx endpoint for the docker service =
Alexandru Pentilescu 5.1 86
Alexandru Pentilescu 4.1 87 Deploy the following configuration to make the container accessible to the outside world:
88
89 {{code language="nginx"}}
90 server {
91 server_name git.transistor.one;
92
93 listen [::]:443 http2 ssl; # managed by Certbot
94 listen 443 http2 ssl; # managed by Certbot
95 # http2 on;
96
97 include /etc/nginx/snippets/ssl.conf;
98
99 location / {
100 proxy_pass http://localhost:3000;
101 }
102 }
103 {{/code}}
Alexandru Pentilescu 5.1 104
105 Once this is done, restart nginx:
106
107 {{code language="bash"}}
108 systemctl restart nginx
109 {{/code}}
Alexandru Pentilescu 6.1 110
111 Confirm that the web page is accessible at the git.transistor.one URL. In case it's not, fix it.
112
113 # Customize Gitea configuration #
114
115 Assuming you do need to change a couple of settings, gitea will have generated a configuration file at ./data/gitea/conf/app.ini.
116
117 Make whatever changes you need to make in this file.
118
119 The changes will take effect only after stopping and restarting the container, though.
120
121 Notable changes that are worth mentioning is setting up an SMTP endpoint:
122
123 {{code language="ini"}}
124 [mailer]
125 ENABLED = true
126 PROTOCOL = smtp+starttls
127 HOST = mail.transistor.one:587
128 FROM = gitea@transistor.one
129 USER =
130 PASSWD =
131 {{/code}}
132
133 And, of course, the server hostname configuration:
134
135 {{code language="ini"}}
136 [server]
137 APP_DATA_PATH = /data/gitea
138 DOMAIN = transistor.one
139 SSH_DOMAIN = transistor.one
140 HTTP_PORT = 3000
141 ROOT_URL = https://git.transistor.one/
142 DISABLE_SSH = false
143 SSH_PORT = 22
144 SSH_LISTEN_PORT = 22
145 {{/code}}
146
147 Oh and, almost forgot, disable user registrations by setting
148
149 {{code language="ini"}}
150 [service]
151 DISABLE_REGISTRATION = true
152 {{/code}}
153
154 If you need more configuration information, check [[this>>https://docs.gitea.com/administration/config-cheat-sheet]] out.
Alexandru Pentilescu 7.1 155
156 = Activating SSH passthrough =
Alexandru Pentilescu 9.1 157
Alexandru Pentilescu 7.1 158 This is the most complex step out of all of them. In order to take advantage of the fact that SSH git pulls/pushes will be done via standard port 22, normal SSH traffic needs to be differentiated from git specific SSH traffic.
159
160 To this end, multiple configurations will need to be done.
161
162 This one's extremely important. Failing to perform this step will make SSH git pulls and pushes require to be done directly from the 2200 port like so
163
164 {{code language="bash"}}
165 git clone ssh://git@transistor.one:2200/Alex/Licenta.git
166 {{/code}}
167
168 While this isn't the end of the world, ideally, all SSH traffic should be routed to port 22, as is standard. VPS firewalls or intermediary ISPs may, themselves, block off incoming or outgoing traffic to unconventional ports, which can cause issues. As such, using the standard port 22 for SSH communication would be ideal.
169
Alexandru Pentilescu 8.1 170 == Enable SSH login for the git user ==
Alexandru Pentilescu 9.1 171
Alexandru Pentilescu 7.1 172 So, to enable SSH capabilities to the git user, please edit the "/etc/ssh/sshd_config" configuration and change the following line:
173
174 {{code language="text"}}
175 AllowUsers alex git
176 {{/code}}
177
178 Obviously the "alex" user doesn't need to be here. The git user does. Change this list as best suits your needs. Don't forget to restart the service after you're done:
179
180 {{code language="bash"}}
181 systemctl restart ssh
182 {{/code}}
Alexandru Pentilescu 9.1 183
184 == Generate a proper public/private keypair for all the accounts that need to use git via SSH with ==
185
186 This part's pretty self explanatory.
187
188 For each user, on each device, that will require SSH git access to the aforementioned git server, they will need to have their own public/private authentication keypair set under a Gitea user that's already registered on the Gitea web portal.
189
Alexandru Pentilescu 13.1 190 Check to see if a public/private keypair doesn't already exist under your user's /home/<username>/.ssh/ directory. You'll recognize already existent keypairs by the presence, in this directory, of <name>.pub files. If you already have at least one such file already there, copy the contents of the <name>.pub file to the clipboard and add it to your Gitea user's settings. In case there is no such .pub file already existent, you'll have to manually generate ones for yourself.
Alexandru Pentilescu 9.1 191
Alexandru Pentilescu 13.1 192 To do so, simply log into each user and run from the terminal:
193
194 {{code language="bash"}}
195 ssh-keygen
196 {{/code}}
197
198 That's pretty much it. Once you generated a keypair, again, visit the /home/<username>/.ssh/ directory and check for <name>.pub files. There should be at least one there, now.
199
200 Copy its contents and add it to your Gitea's user settings through the web interface, as follows:
201 [[image:1.png]][[image:2.png]][[image:3.png]]
Alexandru Pentilescu 14.1 202
203 Once the public key is registered here, you should be able to do git push and git pull from this particular repository using SSH, without the need for further authentication. However, there's still a couple more steps left to follow:
204
205 == Generate a public/private keypair for the git user as well ==
206
207 This might not be immediately obvious why this is necessary, but in order for the SSH passthrough to work, the git user that we'll log into in the future will have to forward all SSH requests to inside the docker container. In order to do so, the container's own SSH server will need to recognize the requests as authenticated from the git user on the host machine.
208
209 To this end, we will have to generate a keypair for the git user as well:
210
211 {{code language="bash"}}
212 sudo -u git ssh-keygen -t rsa -b 4096 -C "Gitea Host Key"
213 {{/code}}
214
215 Once this part is done register the newly generated public key to the SSH server inside the docker container, by appending it to the /home/git/.ssh/authorized_keys files inside the host.
216
217 To do so, please do:
218
219 {{code language="bash"}}
220 sudo -u git cat /home/git/.ssh/id_rsa.pub | sudo -u git tee -a /home/git/.ssh/authorized_keys
221 sudo -u git chmod 600 /home/git/.ssh/authorized_keys
222 {{/code}}
223
224 You might wonder why we're changing a file on the host filesystem and not inside the docker, where the relevant SSH service is running. The reason for this is, remember, this particular directory is already mapped in our docker-compose.yml file, so it exists in both the host machine and in the docker container, simultaneously. All changes that take place to it on the host will reflect inside the container.
225
Alexandru Pentilescu 17.1 226 Please do note that registering the git user's public key has to be done using the above commands **AND NOT THROUGH THE WEB INTERFACE, LIKE IN THE PREVIOUS STEP** (I already lost 2 days investigating why this thing didn't work because I didn't pay attention to this step)
227
228 == Write an SSH Shim script ==
229
230 Here, we'll need to generate a script at "/usr/local/bin/gitea" owned by root:root and with chmod 755 with the following contents:
231
232 {{code language="bash"}}
233 #!/bin/sh
234 ssh -p 2200 -o StrictHostKeyChecking=no git@127.0.0.1 "SSH_ORIGINAL_COMMAND=\"$SSH_ORIGINAL_COMMAND\" $0 $@"
235 {{/code}}
236
237 This script might seem confusing, at first glance, especially since there's another, entirely different "/usr/local/bin/gitea" script that exists in the docker container.
238
239 The script above will simply forward all incoming SSH connections that originally came to the host server and sends them to the docker container (specifically to localhost port 2200 which, according to the yaml file above, is mapped to port 22 inside the container). There, the container will run the command that was originally sent to the host machine inside of itself and return the result to the original outside client.
240
Alexandru Pentilescu 18.1 241 You may be thinking "But how does the host SSH server know when to run this script to forward requests inside the container and when not to forward requests?". Basically, this is done via the /home/git/.ssh/authorized_keys file.
242
Alexandru Pentilescu 21.1 243 When we added all those public keys at [[this>>https://wiki.transistor.one/bin/view/Guides/How%20to%20set%20up%20a%20gitea%20docker%20instance/#HGenerateaproperpublic2FprivatekeypairforalltheaccountsthatneedtousegitviaSSHwith]] step, the Gitea webserver appended those public keys to the /home/git/.ssh/authorized_keys file that is already mapped into the container. Those keys are written with a special "command="/usr/local/bin/gitea --config=/data/gitea/conf/app.ini serv key-9",no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty,no-user-rc,restrict ssh-ed25519 AAAAC...." prefix, which basically tells the SSH server running on the host that, whenever an SSH client that authenticates itself with a matching public key from this format, connects, then the command that this client sent us is saved in an SSH_ORIGINAL_COMMAND environment variable and the command after the "=" symbol gets automatically executed by the SSH server. In our case, this will run the "/usr/local/bin/gitea" shim script from the host machine which we already created in the previous step, which in turn will forward that command to inside the docker container to be ultimately handled.
244
245 Of note is the fact that entries inside the "/home/git/.ssh/authorized_keys" file which don't start with the "command=" format that the Gitea web server saves its entries under, will simply login as normal via SSH.
246
247 = We're done =
248 The server is officially running. Happy coding!