3

I've created a private project in Gitlab and I'm trying to write down a simple deployment script to start the project after downloading it from the repository, and I'm using Ubuntu's bash environment to execute the script.

I've done the same with a public project using a simple curl command:

curl -fSL "https://gitlab.com/MyUsername/MyProject/repository/archive.zip?ref=master" -o project.zip

There are answers out there showing how to do the same for a private project using Gitlab's username+password or private_token and the curl command. But I prefer to use the "deploy keys" features provided with Gitlab. So far I've done as it is instructed by Gitlab's documentation:

ssh-keygen -t rsa -C "$your_email"

And then uploading the public key file to deploy keys of my project in Gitlab. My question is: how can I use the private key that I have to download the latest revision of my project? Should I use curl or scp or anything else? Please also include examples for when the project belongs to a group.

Community
  • 1
  • 1
Mehran
  • 15,593
  • 27
  • 122
  • 221

1 Answers1

2

SSH private keys can't be used for HTTPS connections -- thus, you need to use services exposed over SSH. In this case, that means doing a git clone (or, ideally, if you have an existing clone, a git fetch to update it incrementally), followed by a git archive.

#!/bin/bash
#      ^^^^-- /bin/bash, not /bin/sh, or the [[ ]] syntax isn't guaranteed to work

# change or parameterize these
repo_path=git@gitlabhost.com:group/repo.git
repo_dir=/path/to/local-dir
output_path=/path/to/archive.zip

if [[ -d $repo_dir ]]; then
  (cd "$repo_dir" && exec git fetch) || exit
else
  git clone "$repo_path" "$repo_dir" || exit
fi

# and to create the archive
cd "$repo_dir" && git archive --format=zip -o "$output_path" origin/master 

Once you've got the initial clone created, doing a git fetch and a local git archive is actually more bandwidth-efficient than downloading the whole zip file, since it pulls only changes since the last update.


If your private key is saved as ~/.ssh/id_rsa, it will be automatically used. Otherwise, you'll want to create a ~/.ssh/config file entry like this:

Host gitlabhost.com # substituting the real hostname
    User git # use the username "git" connecting to this host by default
    IdentityFile /path/to/your/id_rsa # if not in the default location
Charles Duffy
  • 280,126
  • 43
  • 390
  • 441
  • Thanks but where is the private key used? – Mehran Jul 10 '16 at 17:22
  • If you have it saved as `~/.ssh/id_rsa`, it's automatically used by `git clone` and `git fetch` when they communicate with a server over SSH (or, rather, by the OpenSSH client when it's run by `git`). Otherwise, you can create a `~/.ssh/config` entry telling `gitlabhost.com` to honor a specific key, and those commands will honor that configuration file automatically. – Charles Duffy Jul 10 '16 at 17:23
  • ...I've edited to show an explicit example of a `~/.ssh/config` file entry specifying a non-default `id_rsa` file. – Charles Duffy Jul 10 '16 at 17:32
  • Is there any way I can name the file in `git clone` command as I'm running it? I'm going to use this command in a docker file and it's kind of cumbersome to copy the file somewhere. I prefer just to name if possible. – Mehran Jul 10 '16 at 17:38
  • BTW, shouldn't it be `repo_path=git@gitlabhost.com:group/project/repo.git`? – Mehran Jul 10 '16 at 18:35
  • According to this page: http://docs.gitlab.com/ce/ssh/README.html you are missing this line `RSAAuthentication yes`. I'm not sure if it is necessary or not. – Mehran Jul 10 '16 at 19:08
  • @Mehran, RSAAuthentication is `yes` by default, so that line is only necessary if the defaults have been changed, ie. in `/etc/ssh/ssh_config`. – Charles Duffy Jul 10 '16 at 19:53
  • @Mehran, ...and, re: "naming the file in `git clone`", do you mean the output file, or the storage location for the cloned tree? The latter is what the final `"$repo_dir"` argument is there for. – Charles Duffy Jul 10 '16 at 19:54
  • Doing this efficiently *requires* persistent storage -- in Docker terms, a volume -- since otherwise you're cloning the repository's entire history each run, which wastes a lot of bandwidth for both you and your Gitlab host. Thus, your `repo_dir` variable should point to a volume location. – Charles Duffy Jul 10 '16 at 19:55