DEV Community

How to use a Private git repo as an npm module

There are several reasons why you might wish to use a private git repo as an npm module, but of the top of my head, the topmost would be you wish to share some highly confidential business logic code and for some reason, you can't use a private npm registry.

Well, you are in luck, here is how you go about it.

Setup the repo

For this article, I will use bitbucket as an example since GitHub is fairly easy. So set up a new project using bitbucket or a git provider of your choice.

Setup your project

To start you need a project that contains a minimum of a package.json file. Without the file, the project won't be recognized as a valid package and npm install won't work. You can set that up quickly using the npm command

npm init

The command above will take you through the steps of setting up a new project. Enter all the information as you wish including the repo URL.

Note: After setting up the project, you should add private: true to the package.json file to ensure the project does not get published by mistake.

Now write your code and push your project to the git repo.

Making use of the package

If this were a public repo, you would be done already. But unfortunately it isn't and other steps follow.

SSH

There are other authentication methods for authenticating against your git provider to access the repo. You could use HTTP and include your username and password in the URL, or generate a key that can also be used as part of the URL. Both methods are pretty unsafe, as you will be exposing your credentials out in the open.

The most secure method is, therefore, to authenticate using SSH. Generating an SSH key is out of scope here, but you can take a look at this tutorial

https://confluence.atlassian.com/bitbucket/set-up-an-ssh-key-728138079.html#SetupanSSHkey-ssh2

After generating the ssh key, save using a name you can remember in a location you can remember. I advise you do not create the key using a password, but it's totally up to you.

Setup an ssh config file in your ssh directory. The filename is just config, the content should look like this


Host bitbucket.org
Preferredauthentications publickey
IdentityFile ~/.ssh/bitbucket

Fetch the public key and save to bitbucket as a new ssh key. It is also advisable you use a name that sets the key apart so you know its purpose, In my case, I set up different keys for my different environments. So I used keyname-environment e.g. Payment-server-staging.

Install the repo as a module

Get the ssh URL of the repo that you set up earlier. It usually is in this form

git@bitbucket.org:acmeinc/foo-bar.git

Install using npm i git@bitbucket.org:acmeinc/foo-bar.git

If the SSH setup went well and you added the key successfully to bitbucket, the installation should go smoothly.

Bonus: Using with Docker

In my use case, I needed to use this repo in a container. There are several ways to also accomplish this, but I needed a way that would not copy the key as part of docker layers.

Modify your Dockerfile this way:

`
FROM node:10-alpine

ARG SSH_KEY

RUN apk add git OpenSSH-client

COPY package.json package-lock.json ./

RUN mkdir -p -m 0600 ~/.ssh && ssh-keyscan bitbucket.org >> ~/.ssh/known_hosts

RUN ssh-agent sh -c 'echo $SSH_KEY | base64 -d | ssh-add - ; npm install'
`

The Dockerfile above tells docker to expect a base64 string at build time and read it in a variable called SSH_KEY which we use on the last line of the Dockerfile.

To get a base64 version of your key, you can convert it manually or use the following command.

key=$(echo ~/.ssh/bitbucket | base64)

The above command will copy it key to a variable $key as base64, you can now run your Dockerfile, but the command for running it changes a little

docker build --build-arg SSH_KEY=$key -t private-git .

That's it.

Updating

This is a part that is a bit tricky, updating gave me problems when I first started using this approach. To upgrade its best you create a tag for the repo using a version number, preferably semantic versioning.

Once the tag has been created, you can add the tag name like so

"some-app": "git+ssh://git@bitbucket.org:acmeinc/foo-bar.git#TAG_NAME"

This will install the version from the tag number. This is also a very good practice as you can fall back to older versions.

Conclusion

So that's it, a bit lengthy but worth it in my opinion. Go ahead and write your function, share with colleagues or across projects. Cheers

Top comments (2)

Collapse
 
ondrovic profile image
ondrovic

Awesome write up, for me though I had to do the initial
npm i git+ssh://git@bitbucket.org:acmeinc/foo-bar.git
instead of
npm i git@bitbucket.org:acmeinc/foo-bar.git as it didn't resolve correctly

Collapse
 
push_technology profile image
push_technology

Excelllent!