Installing a private package with composer

Private PHP packages can be installed using Composer. We need a little extra configuration in the composer.json file and then we setup our SSH key. Follow along with these 3 easy steps, and don't miss the caveat at the end.

1/25 update: provided a safer way to add a host to the known_hosts file. Thanks George for pointing this out!

1. Point to the Git repository

Update composer.json and add a repository:

        "type": "vcs",
        "url": ""

2. Create an SSH key

Create an SSH Key on the machine on which you want to install the package.

If you are working on a development machine, you probably want to add the SSH key to your GitHub/BitBucket/GitLab account. This gives access to all private repositories that your account has access to.

In case you are configuring a deployment server, it would be better to configure an access key or deploy key. An access key only provides access to a single repository and thus allows for more specific access management.

3. Run composer

Now just composer require or composer install the package as usual.

Caveat: add an SSH fingerprint to known hosts

The first time you use an SSH key on a new hostname, it will show you a warning like this:

The authenticity of host ' (' can't be established.
RSA key fingerprint is a1:b2:c3:d4:e5:f6:6f:5e:4d:3c:2b:1a:00:11:22:33.
Are you sure you want to continue connecting (yes/no)?

This serves as an extra layer of protection to prevent you from mistakenly connecting to an unknown host. This does however pose some problems if you want to use SSH keys to automate tasks.

That is why we want to trigger this warning manually and avoid it from popping up in the future. This can be done using the following command:

ssh -T

Naturally, you should replace with the hostname of your private repository. This command will invoke the warning that is listed above. You can verify the fingerprint with the list of fingerprints in your GitHub/BitBucket/GitLab account.

After confirming this warning the SSH fingerprint will be added to the list of known hosts and this will prevent the warning from popping up again.

That's it! You now know how to install a private composer package. Did you like this article? Do you have feedback on how to improve it? Please let me know by posting a comment.

Further reading

Comments (11)

Got a question? Liked the article or got a suggestion? Leave a comment to let us know.

I really fancy the GitHub access tokens for automated tasks, see:

These access tokens can be configured pretty easily to allow only certain actions.

The token can be added to your .gitconfig:
`git config github.accesstoken TOKEN`
Thanks for the suggestion Vdhicts, this could be useful for people that want to have more control!
Caveat to your caveat: blindly accepting the contents of an ssh-keyscan can potentially open you up to man in the middle attacks.
Thanks for your post. I have a problem : my project use git and the private package too. How to manage it without use a git submodule ?
hi, thanks for article. I wonder how you update your vendor folder with private repo when you do changes in remote repo?
Do you have any idea how to get SSH keys to work with azure devops?
This dependency works exactly the same as any other (public) dependency. You update the private package by updating the package to the version you want to use. Maybe this link is helpful for you:

@Mitch Thompson
I don't know because I've never used that before but a quick Google search resulted in this url that might help you:
On windows it should be like this If not it will cause problem and ask authentication.
Tried to follow but do not work
Instead i changed by my repo etc ... all looks fine until i run a composer install. Here the answer is [Composer\Repository\InvalidRepositoryException]
No valid composer.json was found in any branch or tag of, could not load a package from it.
I added then a composer.json in my repo with the following
"name": "myrepo/tester"
Any clue?
Hi Arnaud,

It is hard to say without any code or the latest error message. I would suggest running composer with the `-vvv` argument to get more verbose output. Also make sure that you either require `dev-master` or a version that has been tagged.

Good luck!

It s fine i found out the root cause. For some reason i needed to add ssh://git@ and if you use https you need also to add
And to finish it is missing one part as below
"require": {
"myrepos/tester": "dev-master",
"myrepos/awesome-readme": "dev-master"