Some Notes Before You Begin Reading
This page is still a work in progress. However, you may find it informative to see what I am up to with my research on project management.
Goals of The AidanMontareDotNet Project Management System
- I want to be able to do development in my free time, and easily share my work with the world through my website. I want others to be able to interact, participate, submit their own code (once I give them permission), and ask questions.
- This system will be based on Git, because that’s what everybody else uses, and because it seems to be a good choice for managing development branches.
- The system must include a way of viewing the code through a web interface, viewing diffs, seeing project history, and downloading different versions of the code.
- The system must also include some basic team management, an issue tracking system, and a way for the average user to get help with their problems.
- As you can see by the things on my site, I have no experience running open source projects. However, I hope to release many of my projects as open source, and I wanted to learn how to manage larger projects before I actually have to deal with any. So that’s why I am doing things in a somewhat awkward order.
- The system must make it easy to share small, new, or experimental code, or else I will quickly get lazy and just leave my projects sitting in a directory somewhere on my computer. Creating new projects should be simple and easy enough that I can share even small little things, sort of like GitHub Gist.
- The system must scale easily to projects that become large. In particular, it should be easy to add other committers, reviewers, etc, and organize these people while maintaining an orderly code base. A good issue tracker and some sort of central communication method should be in place in the event a project becomes large enough to need them.
- The system should be full-featured enough that the developers can use it as their primary means of communication and collaboration.
- Each project should have its own independent space, so that all the repositories are not lumped together.
- A main goal in this site was to learn how to do things independently. Yes, I could easily set up a GitHub account, but then what would I learn? The methods I explain on this page allow most moderately experienced Linux users to create their own, completely independent code management system that requires no outside services and is based on free and open source software. As such, these methods can also be used to create servers for internal projects where a public GitHub repository would not work, or for teams that require intensive customization and scalability for their projects (though doing these things is outside the scope of my advice here, I feel confident that I could do build such a server if a future job required it).
- The system should be efficient for both the developers, the reviewers and the casual users, preferably as efficient as if I had chose to use the aforementioned hosted solutions.
- As with building this site, security must be among the top priorities of the system. Unnecessary access to the server should not be required for any users. I should be able to add commiters to a project and still be able to sleep at night.
- Finally, the system should be lightweight enough that I can run it along with AidanMontareDotNet, and simple enough that one person (me) can manage it.
If your goals are similar to mine, then system may work well for you.
The Components
So what have I come up with? My final system accomplishes all of the goals above (as far as I can tell), and seems pretty manageable and easy to use. It is made up of the following components:
- The AidanMontareDotNet server: on which everything runs.
- GitLab: This is the core of my system. GitLab is an open source repository management application that runs on Linux systems. It includes its own Git server, as well as project wikis, team management, issue tracking, access control, and more. It offers many of the features of GitHub, but unlike GitHub, its code is open source and can be installed on your own Linux server. There is also a hosted version that you can use for free.
- Apache: Apache is the web server I use for this site, so of course I wanted to use it with GitLab. GitLab uses Nginx by default, but it is possible to configure an external web server.
- Ubuntu Build Virtual Machine: While our initial GitLab installation will be from the default package, we will want to make out own customizations to our GitLab. So we will create an Ubuntu VM in VirtualBox and use this to build our own customized GitLab packages. We can then install these packages on our server like we would install a normal GitLab update. This might seem overkill, but it will make things much easier later on (specifically updating the GitLab installation). This guide will also demonstrate how to use this system to customize the look of the front pages of GitLab to make it fit with an existing website. However, this system would allow for even more extensive changes to the GitLab source.
Assumptions
When writing this guide, I assume the following:
- You are reasonably comfortable with Linux system administration from the command line. If not, this might be a little overwhelming.
- You have root privileges on the server you are attempting to install on. Preferably it is your own VPS.
- You are running a 64 bit OS on your server. As far as I can tell, GitLab only has 64 bit packages.
- You’re local computer runs a 64 bit Linux distribution or can run one in a virtual machine. This is necessary to create the build machine, which must be the same distribution and architecture as the server you are deploying on.
As I use this system to host all of my public code projects, it should be well tested. Any issues that come about will be listed on this page.
Installing GitLab
security first
As with most major changes I deploy to my server, I like to lock the system down first. I prevent access by limiting the firewall rules to my IP. This will help to prevent someone from messing things up while we try to install stuff and prevent security compromises before we have a chance to secure things.
edit firewall to only allow connections from your ip
On my server, it goes something like this:
sudo vim /etc/iptables.firewall.rules
add "-s [YOUR_IP]" to the allow statements for ports 80 and 443
sudo iptables-restore < /etc/iptables.firewall.rules
If your server is accessible through IPv6, then also make sure to change those firewall rules.
Also, do the same for your firewall rules for port 22 (for Git SSH).
secure sshd
Chances are you already use SSH to manage your server. You likely don’t want anyone else having access your SSH login. However, GitLab will add a git
user with a limited shell. This will allow users to clone, pull, push, etc (if they have permission within GitLab) to your projects, but will not allow them to actually log into a SSH console.
For GitLab to work, you want anyone to be able to connect to the git
user, but you don’t want to weaken the security of your administration SSH account. we can do this by reconfiguring the ssh daemon:
sudo vim /etc/ssh/sshd_config
Add the following:
# Even if you have SSH on another port for security (good job!), we need to put it on 22 because people who visit your website will want to be able to clone over the normal port Port 22 # Make sure you have the following set for basic security. A more secure server might have more options: PermitRootLogin no PermitUserEnvironment no PasswordAuthentication no # Allow the git user from anywhere: AllowUsers git # Allow the admin user from only your IP: # replace admin with the account you use for administration # replace YOUR_IP with your home IP Match Address YOUR_IP AllowUsers git admin # make sure this is the end of your config file, or you may have problems
Warning: only do this if you have another method of accessing your sever! In the event that your IP changes (mine does so very rarely), you must have another method of getting into your server and changing this rule. Also make a note to yourself somewhere so that if your SSH breaks, you remember to check if your IP has changed.
shutdown apache
sudo service apache2 stop
make a site backup
This is always good practice before you go making big changes to how you do things.
See my WordPress backup script.
configuring your domain
You must now decide under what domain you will be installing GitLab. Mine is at code.aidanmontare.net. I will assume in this guide that you are doing something similar, and that your server already hosts the root of your domain.
If not, there will be some extra work involved to configure a new domain on the server. If you are installing GitLab within a home or office network and will not have a domain, some things will be different as well. However, the general principles listed here should still apply.
configure hosts file
We must configure the hosts file of our server so it knows who it is. Add the following (but with your hostname and domain name):
127.0.0.1 localhost.localdomain localhost 50.116.56.154 AidanMontareDotNetServer.aidanmontare.net AidanMontareDotNetServer code.aidanmontare.net
Some of these may not be necessary, but I have them all in there for redundancy.
now for the install
To start, we basically follow the GitLab installation page.
install dependencies
sudo apt-get install postfix
I will assume you are managing the server over SSH and already have openssh-server, but if not, install that too.
download the latest package
Go to the GitLab installation page and grab the wget command for the latest release. Put the file somewhere convenient.
check the md5 sum
Go to the GitLab download archives page and find the md5 sum of your release. Use the md5sum utility to verify the integrity of the download.
install the package
sudo dpkg -i [PACKAGE_FILE]
Configuring GitLab
We want to use Apache, not the default Nginx, to serve our GitLab installation. That requires some extra configuration.
cleanse the install
For some reason, following the installation instructions as written always seems to give me some difficulties. The fix seems to be to cleanse the install before reconfiguring it, though I don’t know why this is necessary.
sudo gitlab-ctl cleanse
You will get a scary-sounding warning about having 60 seconds to cancel this destructive operation. But of course GitLab has never been configured yet, so you won’t be exactly losing anything. And yes, you really do have to wait the full 60 seconds.
configure GitLab
Now GitLab needs to do its initial configuration. sudo gitlab-ctl reconfigure
edit configuration file
We will disable Nginx and specify what the Apache user is called.
cd /etc/gitlab
sudo vim gitlab.rb
Input the following into that file:
external_url "https://code.YOUR_DOMAIN/" nginx['enable'] = false web_server['external_users'] = ['www-data']
YOUR_DOMAIN is something like aidanmontare.net
or example.com
.
Save the file and run sudo gitlab-ctl reconfigure. This now loads in your configuration changes. GitLab is now installed and ready to go, but you won’t be able to access it yet because we have to configure Apache.
Apache Configuration
give Apache access to the GitLab files
Apache (running as the www-data
user on my system) needs access to the GitLab files to be able to serve them. Thus it, must be a member of the gitlab-www
user group.
sudo usermod -a -G gitlab-www www-data
Additionally, www-data
must be a member of the git
group in order for SSH access to your repositories to work:
sudo usermod -a -G git www-data
configure Apache virtual host
On Debian-based systems, each virtual host is a file within /etc/apache2/sites-available
. We will create a new virtual host for our GitLab installation.
cd /etc/apache2/sites-available
sudo vim gitlab.conf
Modify this template configuration file to your needs.
On my server, I needed to replace /var/log/httpd/logs/
with ${APACHE_LOG_DIR}
. Also, any uses of port 8181
needed to be changed to 8080
.
enable Apache modules
Run the following commands to enable the necessary Apache modules for GitLab to work:
sudo a2enmod rewrite
sudo a2enmod ssl
sudo a2enmod proxy
sudo a2enmod proxy_http
sudo a2enmod headers
enable the Apache virtual host
We need to enable the configuration file we created:
sudo a2ensite gitlab
restart Apache
add apache config (see my config file)
add apache modules
restart apache
Testing the Installation
Go to the address of your new GitLab installation in a browser and see what happens!
If you get a deploy page, run sudo gitlab-ctl deploy-page down and refresh the page several times.
If you get some sort of error, try rechecking that you followed all the configuration steps above. Go through everything slowly and flesh out any errors.
Before we go any further, we will do a more thorough check:
- Open Firefox Developer Tools and select network. Reload a page and make sure none of the resources return errors.
- Add a new test project.
- Upload an SSH key in your profile settings.
- Try cloning the test project.
- Try pushing to the test project.
- Try cloning the test project over HTTPS instead of SSH
- Try pushing over HTTPS
- Try uploading a project icon and see if it appears correctly
If all of that worked, then we will consider GitLab installed correctly (you can obviously remove the test project, if you wish). If not, recheck your configuration or go to the GitLab support page to see various ways of getting help.
Setting Up the Build VM
For now, I am just using default GitLab until I get the build process working. Stay tuned for more updates.
For now:
After each update:
- restore gitlab custom pages
- change permissions on backup directory
Building GitLab
Building a Customized GitLab
At the moment, you can achieve the goal of having a custom GitLab omnibus installation without building a custom package. We will accomplish this by editing files over SSH. The files that you might want to check out are:
/opt/gitlab/embedded/service/gitlab-rails/app/helpers/appearances_helper.rb
/opt/gitlab/embedded/service/gitlab-rails/app/views/layouts/explore.html.haml
/opt/gitlab/embedded/service/gitlab-rails/app/views/layouts/_head.html.haml
/opt/gitlab/embedded/service/gitlab-rails/app/views/layouts/devise.html.haml
/opt/gitlab/embedded/service/gitlab-rails/app/views/layouts/notify.html.haml
/opt/gitlab/embedded/service/gitlab-rails/app/views/dashboard/projects/_zero_authorized_projects.html.haml
/opt/gitlab/embedded/service/gitlab-rails/app/views/explore/_head.html.haml
Before you edit these, read this guide to understand how to set your editor to indent correctly, as mistakes in indenting in haml will break GitLab. Also make sure to back up these files before editing them.
When you are done, run sudo gitlab-ctl restart and the changes should take affect.
Beware that this is a temporary solution, as you will have to re-modify the files after every update to GitLab.
Currently I run the following commands to after each update. After each diff where I see that there were no upstream changes, I copy the file from my home directory its location in /opt/gitlab
. If there are upstream changes, I modify the file in my home directory to reflect those before copying.
sudo diff appearances_helper.rb /opt/gitlab/embedded/service/gitlab-rails/app/helpers/appearances_helper.rb sudo diff ~/explore.html.haml /opt/gitlab/embedded/service/gitlab-rails/app/views/layouts/explore.html.haml sudo diff ~/_head.html.haml /opt/gitlab/embedded/service/gitlab-rails/app/views/layouts/_head.html.haml sudo diff ~/devise.html.haml /opt/gitlab/embedded/service/gitlab-rails/app/views/layouts/devise.html.haml sudo diff ~/notify.html.haml /opt/gitlab/embedded/service/gitlab-rails/app/views/layouts/notify.html.haml sudo diff ~/_zero_authorized_projects.html.haml /opt/gitlab/embedded/service/gitlab-rails/app/views/dashboard/projects/_zero_authorized_projects.html.haml sudo diff ~/explore_head /opt/gitlab/embedded/service/gitlab-rails/app/views/explore/_head.html.haml sudo chmod -R g+rx /var/opt/gitlab/backups/ ; sudo gitlab-ctl restart ; sudo gitlab-ctl deploy-page down
Using Your GitLab on The Server
Going Live With Your GitLab
remove security settings
When we first began, we configured our firewall and Apache to only allow our home IP to connect. Now it is time to undo these settings so that the world can connect to our code repositories.
Only proceed if you are ready to début your GitLab installation.
edit firewall rules
Edit your firewall rules with whatever you use to manage them. Remove the IP restrictions from ports 22, 80, and 443 so that any IP can connect. Then reload the firewall rules.
Congratulations!
Your GitLab installation is now complete. Anyone who can access your server will now be able to view and clone your projects.
GitLab Backups
Once we start using our GitLab server, we will start collecting many different projects. While the distributed nature of Git means that all the clones of each repository will have (mostly) all of the repository’s data, we want to have regular backups of our projects on the server in the event something goes wrong.
I use a backup script to make offsite backups of both aidanmontare.net and code.aidanmontare.net. You can download the script I wrote, but be warned you will need to customize it to your server’s setup.
Updating GitLab
Subscribe to the GitLab blog or find another way of keeping up on GitLab news. As with any large web software, there will be security updates that you need to take care of.
Unmodified GitLab
An unmodified GitLab installation can be upgraded quite rapidly. The GitLab update announcement blog posts usually contain information on updating. Additionally, the GitLab documentation has an upgrading guide for Omnibus Packages. Just follow those guidelines and you’ll be good to go.
Customized GitLab
Updating our customized GitLab will take a little more work, but is still relatively quick.
This will be finished once I am doing describing how to create a custom GitLab package.
Emails for GitLab
https://gitlab.com/gitlab-org/omnibus-gitlab/blob/master/doc/settings/smtp.md
http://docs.gitlab.com/omnibus/common_installation_problems/README.html#emails-are-not-being-delivered
TODO
http://docs.gitlab.com/ce/incoming_email/README.html
Issues
The issues with using this system, as well as notes on managing open source projects, can be found here.
References
These are the resources I consulted in creating this system. You might find them interesting as well.
GitLab Installation
GitLab
GitLab installation page
GitLab Omnibus Readme
GitLab documentation
GitLab and Apache
GitLab Community Guide Recipe for Apache
https://gitlab.com/gitlab-org/gitlab-recipes/tree/master/web-server/apache
GitLab Nginx Settings
GitLab Omnibus
GitLab Customization
building omnibus GitLab
Changing gitlab.yml and application.yml settings
Other References for the Necessary System Configuration
ssh_config man page
sshd_config man page
General Stuff I Consulted
Git Interfaces List
Pro Git Book
Phabricator
how Blender does things
starting an open source project