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)
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 correctlyExcelllent!