A Day of Gitea
2018-02-22Under this post, I'll cover setting up the managed Git hosting service, Gitea, via a quick path through Docker. It'll follow the same path that I used to setup my own hosted Git service, git.fraley.codes.
This post assumes you are using a RedHat-based Linux. There will be disclaimers where the instructions may differ for a different flavor of Linux.
What we want
Once all said and done, we want a secure Gitea server setup on our domain, with encrypted communications over https. The plan for that is to run Gitea in a Docker instance, giving us ssh and http ports to talk over, and then wrap the http port in an https Nginx server with an SSL certificate.
Moving the SSH port we're currently using
We'll want to host our Gitea server on the default ssh port, 22. Unforunately, we're using it right now to configure the machine! To change which port our underlying machine listens on, edit /etc/ssh/sshd_config and make the following change:
# Change the following line: #Port 22 # To this line: Port 2222
Restart the sshd service. On Amazon Linux, this is:
sudo service sshd restart
After that, log out, and log back in using port 2222 instead of the default.
Getting the SSL certificate
This guide uses Let's Encrypt to secure an SSL certificate. If you already have a certificate, or plan to use a different method, you can move ahead to the next section.
If you are not using Amazon Linux, go to the certbot site to see how to use the certificate-fetch program. If you are running Amazon Linux, you can run the following command to get your certificate:
wget https://dl.eff.org/certbot-auto chmod a+x certbot-auto sudo ./certbot-auto certonly --debug
Follow the instructions, providing your email address, domain, and standalone as the details for the program. It should generate the certificate files and store them under /etc/letsencrypt/live/your.domain/ (check the output to ensure that's correct).
Now that we have the SSL certificate, we can move on to...
Setting up the Nginx reverse proxy
Now we'll setup the reverse proxy that will wrap the insecure Gitea http server and use the certificate we just acquired to guarantee authenticity.
To start, go ahead and install Nginx. On Amazon Linux, this is:
sudo yum install nginx
After that, start the service and enable it for boot. On Amazon Linux, this is:
# Start the service sudo service nginx start # Enable the service at boot sudo chkconfig nginx on
Go to /etc/nginx/nginx.conf and remove the default server configurations. We'll add our own server configuration at /etc/nginx/conf.d/gitea_reverse_proxy.conf, so create an empty file there.
We want to redirect all http traffic over to https. To do that, add the following block to gitea_reverse_proxy.conf:
server { listen 80 default_server; listen [::]:80 default_server; server_name your.domain; return 301 https://$server_name$request_uri; }
The 301 status code indicates that the server has permanently moved to the following location, which is our server under https instead of http.
Now add another block below to proxy Gitea. It looks similar, but listens over an ssl http2 connection on port 443:
server { listen 443 ssl http2 default_server; listen [::]:443 ssl http2 default_server; server_name your.domain; # ...
Next add in the path to your SSL certificates:
# ... ssl_certificate "/etc/letsencrypt/live/your.domain/fullchain.pem"; ssl_certificate_key "/etc/letsencrypt/live/your.domain/privkey.pem"; # ...
And follow it up with the default SSL parameters from /etc/nginx/nginx.conf.default. It's recommended that you don't get them from here in case this is untrustworthy/out-of-date, but they should look like this:
# ... # It is *strongly* recommended to generate unique DH parameters # Generate them with: openssl dhparam -out /etc/pki/nginx/dhparams.pem 2048 #ssl_dhparam "/etc/pki/nginx/dhparams.pem"; ssl_session_cache shared:SSL:1m; ssl_session_timeout 10m; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_ciphers HIGH:SEED:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!RSAPSK:!aDH:!aECDH:!EDH-DSS-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA:!SRP; ssl_prefer_server_ciphers on; # ...
The server should work if you don't follow the steps in the comment, but it's good to be safe, so run the command it requests, and uncomment ssl_dhparam line that follows. You may need to run it under sudo.
The last block we'll add is the root location block that will do all the forwarding, as well as tacking on of the headers for Gitea to know how it's being proxied:
# ... location / { proxy_pass http://localhost:3000; proxy_set_header Host $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; } }
In case it's hard to piece together the conf file from these blocks, the files in full are available on my git site.
Reload the server with the following command:
sudo service nginx reload
At this point the reverse proxy should be setup. You'll receive a 502 bad gateway if you try and access the server, but that's because there's no Gitea server behind our gateway yet. We'll fix it by...
Starting up the Docker Gitea service
Before we can run any commands, we need to make sure our ec2-user is part of the docker group. Type:
groups ec2-user
If docker is not one of them, run the following command, and then logout and log back in:
sudo usermod -aG docker ec2-user
If you're properly setup, you should be able to start a swarm by running:
docker swarm init
We'll make use of this swarm when we go to deploy the Gitea compose file. Create a file somewhere called gitea-stack.yml with the following contents:
version: '3.3' services: server: image: gitea/gitea:latest volumes: - ./gitea_data:/data ports: - "3000:3000" - "22:22"
Make sure to create a gitea_data directory next to gitea-stack.yml for it to store data in.
This compose file ensures that we're running Gitea from the latest Docker image, using our gitea_data directory as a storage volume, and forwarding its ssh port, as well as its http port to 3000, the port that our Nginx reverse proxy is listening on.
Make sure that port 3000 is not accessible to the world, only to you. This will be the insecure http connection that Nginx will forward securely, so we want to avoid using it directly.
Now we can run our final terminal command:
docker stack deploy -c gitea-stack.yml gitea
At this point, you should be able to access it from port 3000, and the default https port (thanks to Nginx). If you can only access it on port 3000, then Nginx is not configured properly.
Use the default https access to setup the server, making sure not to change the http port from 3000 or the ssh port from 22.
Finished!
Once done, you should have a fully functional Gitea server at your command!