Setting up a Private Git Server using Gogs

Sep 4, 2017
•
Jason Raimondi

1. Cloning the Starter Project

Lets start with my base project found on github here, starter-docker-gogs. This project is meant to be a kicking off point and I would assume if anyone uses it they are just nuking the .git directory at project root and starting their own history.

Be Aware of your Environment Configurations (.env)

MYSQL_ROOT_PASSWORD = This variable is mandatory and specifies the password that will be set for the MySQL root superuser account. In the above example, it was set to ‘gogs’.

MYSQL_DATABASE = This variable is optional and allows you to specify the name of a database to be created on image startup. If a user/password was supplied (see below) then that user will be granted superuser access (corresponding to GRANT ALL) to this database.

MYSQL_USER, MYSQL_PASSWORD = These variables are optional, used in conjunction to create a new user and to set that user’s password. This user will be granted superuser permissions (see above) for the database specified by the MYSQL_DATABASE variable. Both variables are required for a user to be created.

Update the Makefile Command generate-ssl-cert with Domain Info

Inside of our main Makefile, you will find a command called generate-ssl-cert with some defaults still in there.

2. Getting Your Server Configured with Docker and Docker Compose

Any VPS will do; Digital Ocean, Linode, AWS… whatever. We just need to have a domain with your DNS pointing your domain correctly to the server. We need to be hitting an actual domain and not an IP address that Let’s Encrypt can directly ping.

Install Docker

If you have not installed Docker yet, it is pretty easy, just follow the install guide for your distro. You are going to want to install the CE version, this is the Community Edition.

Familiarize Yourself with our docker-compose.yml

The docker-compose.yml is what is bootstrapping this project. It may seem like our make commands are doing this, but if you look inside of our Makefile, all of our makefiles are just wrapping docker-compose commands.

Both MySQL and Gogs section, we are directly referencing the official image. You can see under the nginx section, we are defining a build directory of nginx-ssl. This is because we need to add some SSL certificates and keys inside of this container to get it ready to serve our Gogs instance over https.

The Three Containers

We will have a Gogs instance running with MySQL as our database and Nginx to reverse proxy and serve our private Git repo over SSL.

All three of our containers will be using the official containers as our base. Our Gogs and MySQL containers are going to be used without the need to add additional layers to them. Our Nginx container is going to need some very minor additions added into the base container.

3. Using Let’s Encrypt to Generate SSL Certificates with make install

First before running our make install, we need to set up our production .env file so our production Mysql instance is secure. Please generate a random secure password for both the MYSQL_ROOT_PASSWORD and the MYSQL_PASSWORD.

Set Up Production .env File.

We are using a .env file to maintain our environment variables. Right now, our variables are pretty limited, we really only have the settings for our MySQL container.

Go ahead and run the following command:

make copy-env

This is going to copy our .env.sample to .env without worry about overwriting an existing copy.

copy-environment:cp-n .env.sample .env

Using the make install Command

I have bundled a simple helper that will basically chain together everything that needs to be done in order to generate your Let’s Encrypt certificates on a new server with Docker and Docker Compose installed.

install:generate-dhparam pull build start generate-ssl-cert

What the make install command is doing is basically chaining together and running the following commands consecutively:

make generate-dhparam
make pull
make build
make start
make generate-ssl-cert

Part A make install: generate-dhparam

Before we are able to generate an SSL certificate using Let’s Encrypt, we need to first generate a your Diffie-Hellman key. There is little risk if this key is exposed, but you probably want to keep this key private.

If you already have openssl installed on your machine, from the root of our starter-docker-gogs project, run the command:

openssl dhparam -out dhparam.pem 2048

If you do not already have openssl installed on your machine, do not fret, you should definitely have Docker installed on your machine. We can generate this file using a super slim (3M) container I built as a helper. So, still from the root of our starter-docker-gogs project, run make generate-dhparam to run the following command in our Makefile:

What we are doing is opening our server to port 80 to allow the Let’s Encrypt tool, certbot, to ping our server and generate certificates for us.

Part E make install: generate-ssl-cert

This should only take a second or two, it is going to hit Let’s Encrypt servers and then ping back to us. Since we already have the two flags --email and --agree-tos, we should not get any subsequent prompts (although recently I have noticed the certbot tool asking to share your email with the EFF to build their mailing list).

4. Update the Nginx Server Block in gogs-ssl.conf to Listen for SSL Traffic

After we run Certbot the first time, we can delete the small Let’s Encrypt block and uncomment the two blocks below.

For our final file at ./nginx-ssl/conf.d/gogs-ssl.conf should look exactly like the following, but with YOUR_DOMAIN of course replaced with yours.

We have two server blocks in this file; the first is listening to traffic to your domain on port 80, catching any non-ssl traffic, and redirecting it through the same domain over SSL on port 443.

One interesting thing about this is the proxy_pass http://gogs:3000. Typically, you’d proxy pass to the same machine you are on (i.e. proxy_pass 127.0.0.1:3000), but since Gogs is running in a container, it is not technically running on 127.0.0.1, but instead, it is sort of inside a subnet on your local machine. This is a Docker thing; one way two Docker containers can talk to each other is by the literal machine name. In our case, this is as defined in our docker-compose.yml, our container running Gogs is simply named gogs.

gogs:image:gogs/gog...

5. Restart the Containers

After you’ve updated your gogs-ssl.conf we can go ahead and restart our

make stop clean build start

This is basically just going to run the commands, stop -> clean -> build -> start, in a series without having to type them out one by one.

Ideally you should see something similar to the following (note the up state):

6. Configure Gogs

Now we are getting to the home stretch, really all we have left to do is set up our Gogs settings now. First, we will set up Gogs using the GUI installer, and then we are going to move on and do some further settings in our main Gogs config file located in your project at data/gogs/gogs/conf/app.ini.