I usually like to start my post describing what we will try to accomplish here, but I think I can't do any better than what the title states. So, let's say if I can come up with a convincing excuse. Well, all I can come up with right now is that I think it is wasteful to create an entire VM to run a distributed version control system. At least one that does not have helpful paperclips with eyes and other features requiring you to download crap. And, it is nice to know if the docker host (or cloud) takes a dump, we can bring this service back rather quickly. For this article we will use git; some other time we can talk about svn.
The git server I will be using is gitolite because it is reasonably simple and quick to manage and get going. What I really like on it is that the accounts for the users using git are not accounts in the host itself, so they cannot login to the machine hosting git. By default the git users login using
Since I am lazy, I will store the repositories in a NFS fileshare that is mounted into the container at runtime. We talked about how to do the mounting in a previous article.
Assumptions
- gitolite running off /home/git
- We will connect to the git server on port 2022. I chose that because I need port 22 for to ssh into the docker host. Yes, they are in different IPs (in my case completely different VLANs), but I am weird like that.
- We will use ssh key pair authentication. And will use a different key than the default one. Note you can authenticate against LDAP, but that would go against what I wrote in the name of this article.
- gitolite being run as user git
- I am running this on centos6.
Install
- I created a CNAME for the docker host, gitserver.example.com, so it looks pretty.
- In the NFS server, create a fileshare owned by the user git, which in this example has uid=1201.
- We will need to create a ssh key pair for the gitadmin. I created my pair by doing something like
ssh-keygen -t rsa -C gitadmin -f ~/.ssh/gitadmin
You will need to copy ~/.ssh/gitadmin.pub into the docker host by whatever means you desire.
- I create a directory in the docker host to put all the files (docker-entrypoint.sh and Dockerfile) related to this container. Here is the Dockerfile
############################################################ # Dockerfile to build a gitolite git container image # Based on CentOS ############################################################ # Set the base image to CentOS FROM centos:centos6 # File Author / Maintainer MAINTAINER Mauricio Tavares "raubvogel@gmail.com" ################## BEGIN INSTALLATION ###################### # We need epel RUN rpm -Uvhi http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.no arch.rpm && \ sed -i -e 's/^enabled=1/enabled=0/' /etc/yum.repos.d/epel.repo # We need NFS, openssh, and git # And ssmtp (from Epel) RUN yum update -y && yum install -y \ git \ nfs-utils \ openssh-server && \ yum install -y ssmtp --enablerepo=epel # Configure NFS RUN sed -i -e '/^#Domain/a Domain = example.com' /etc/idmapd.conf ##################### INSTALLATION END ##################### # Create git user RUN adduser -m -u 1201 git # Configure ssmtp # Configure sshd RUN sed -i -e 's/^#Port .*$/Port 2022/' \ -e 's/^#PermitRootLogin .*$/PermitRootLogin no/' \ /etc/ssh/sshd_config && \ sed -i -e \ 's@session\s*required\s*pam_loginuid.so@session optional pam_loginuid.s o@g' \ /etc/pam.d/sshd && \ ssh-keygen -f /etc/ssh/ssh_host_rsa_key -N '' -t rsa && \ ssh-keygen -f /etc/ssh/ssh_host_dsa_key -N '' -t dsa # And a mountpoint for repositories # Note: can't NFS mount from dockerfile, so will do it in an entrypoint script RUN su - git -c 'mkdir repositories' # And now the git server # Gitolite admin: gitadmin (it is based on the name of the pub key file) RUN su - git -c 'mkdir bin' && \ su - git -c 'git clone git://github.com/sitaramc/gitolite' && \ su - git -c 'mkdir -m 0700 .ssh' && \ su - git -c 'echo "ssh-rsa AAAAB3NzaC1yc2EAASLDAQCOOKIEQDehf5hxGq9//34yrsL [...] 7CfSpbiP gitadmin" > .ssh/gitadmin.pub' # The rest will be configured in the entrypoint script # Put the entrypoint script somewhere we can find COPY docker-entrypoint.sh /entrypoint.sh ENTRYPOINT ["/entrypoint.sh"] EXPOSE 2022 # Start service CMD ["/usr/sbin/sshd", "-D"]
Where
- You will need to put the public key gitadmin.pub between the double quotes in the line beginning with su - git -c 'echo "ssh-rsa.
- I am running a lot of things in the Dockerfile as user git.
- The NFS setup was mentioned before, so I will not bother with it right now.
- I forgot to add the setup for ssmtp. I will think about that sometime later.
- You will need to put the public key gitadmin.pub between the double quotes in the line beginning with su - git -c 'echo "ssh-rsa.
- The docker-entrypoint.sh file looks vaguely like this:
#!/bin/sh set -e # Mount git's repositories mount.nfs4 fileserver.example.com:/git /home/git/repositories su - git -c 'gitolite/install -to $HOME/bin' # setup gitolite with yourself as the administrator su - git -c 'gitolite setup -pk .ssh/gitadmin.pub' # And we are out of here exec "$@"
- So far so good? Ok, so let's build the image. I will call it git.
docker build -t git .
If the last build message looks likeSuccessfully built 6fb1ac15b47a
chances are the build was successful and you can go to the next step. Otherwise, figure out what went boink.
- Now start the service. Remember you need to run in priviledge mode because of NFS. Since this is a test, I am calling the contained test-git.
docker run --privileged=true -d -P -p 3306:3306 --name test-git git
Setup and Testing
- Let's start testing by seeing what repositories we can see as an admin:
$ /usr/bin/ssh -i /home/raub/.ssh/gitadmin git@gitserver.example.com info hello gitadmin, this is git@docker running gitolite3 v3.6.2-12-g1c61d57 on git 1.7.1 R W gitolite-admin R W testing
FYI, testing is a repo everyone allowed to use the git server can play with. Think of it as a, as its name implies, test repo. Since that worked we can proceed to the next step.
- Now we should edit your .ssh/config file to access the gitadmin repository.
cat >> ~/.ssh/config << EOF Host gitadmin Hostname gitserver.example.com User git Port 2022 identityfile /home/raub/.ssh/gitadmin protocol 2 compression yes EOF
Yes, you can ask about what to do if you have a script that needs to pull stuff out of a repo, and I will tell you to wait for the next installment. This article deals with getting it to work. - Retrieving the admin repository is now much easier. So, instead of having to do something like
git clone ssh://git@gitserver.example.com:[port]/gitolite-admin
which would also require us to feed the key (or rename it as the default which IMHO is a bad idea), thanks to the previous step we can now lazily dogit clone gituser:/gitolite-admin
- Repository config file is in gitolite-admin/conf/gitolite.conf
- Adding a new user (and perhaps a repository)
- Get user's ssh public key, say raub.pub. How did the user created the ssh key pair? Don't know, don't care.
- Copy raub.pub to gitolite-admin/keydir. NOTE:file must be named after username user will use to connect to the git server; it does not need to have anything to do with the user's normal/real username.
- Create a repository for the user. Let's give it a nice and snuggly name, like somethingawful
cat >> conf/gitolite.conf << EOF repo somethingawful RW = raub EOF
- Commit changes
git add conf keydir git commit -m 'Added new user and config a repo' git push origin master
- Get user's ssh public key, say raub.pub. How did the user created the ssh key pair? Don't know, don't care.
- Now, let's pretend we are the user (i.e. what the user should do/see). Which repos can you/user see? If this looks like a step we did before, it is. Just using a new user.
$ ssh -i /home/raub/.ssh/raub git@gitserver.example.com info hello raub, this is git@docker running gitolite3 v3.6.2-12-g1c61d57 on git 1.7.1 R W somethingawful R W testing
There is somethingswful!
- Let's grab somethingawful
$ git clone gituser:/somethingawful Cloning into 'somethingawful'... warning: You appear to have cloned an empty repository. Checking connectivity... done.
- Edit, commit, and off you go
I will put all those guys in my github account later on. And shall sneakly update this post afterwards.
No comments:
Post a Comment