Setting up a personal packagist, part 1


While I was reading the composer docs looking for a way to speed up our setup, I discovered Satis. It allows you to generate a private package repository. Here's how I got it setup.

I work on a Symfony project for work. One of the pain points in developing it was any time we needed to add or update a dependency. Like most PHP projects, we use Composer for managing our dependencies. The problem was that instead of using packages from Packagist, most of our packages are internal and hosted in bitbucket so any time we did ran composer update, composer would visit each repo and do a git fetch then have to parse all of the versions in that repo. It took forever.

Getting Started

To start off with, I created a new folder for this project:

mkdir satis-server
cd satis-server
git init
git ci --allow-empty -m "Initial commit"

Setup Satis composer.json

Satis is configured through a composer.json file just like a regular PHP project. The format looks pretty similar. Here's an example:

    "name": "work/satis-repo",
    "homepage": "",
    "repositories": [
        { "type": "vcs", "url": "ssh://" }
    "require": {
        "99designs/phumbor": "*"
    "require-dependencies": true,
    "require-dev-dependencies": true,
    "archive": {
        "directory": "dist",
        "format": "zip"

Let's go over what each of these sections mean.

Building your server

Now that we've got a composer.json setup for satis, we need to build our server. I'm using Docker to do that but you can also install satis locally.

cp ~/.ssh/id_rsa .
cp ~/.ssh/ .
docker run --rm --init -it \n  -e GIT_SSH_COMMAND="ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no" \n  --volume ${PWD}:/build \n  --volume "${COMPOSER_HOME:-$HOME/.composer}:/composer" \n  --volume ${PWD}/id_rsa:/root/.ssh/id_rsa \n  --volume ${PWD}/ \n  composer/satis --no-ansi -v build /build/composer.json /build/output
rm id_rsa

You'll note that I'm mounting in my personal ssh credentials. This is only required because the repos that I use at work aren't public. If all of the repos that you use are public, you probably don't need to do that.

Once you run that, it'll take a while to download everything but at the end you should have a new folder called output with contents like this:

😎  λ ~/projects/satis-server/ master* ls -havl output
total 192K
drwxr-xr-x 6 chrisj chrisj  204 Sep 11 10:46 .
drwxr-xr-x 7 chrisj chrisj  238 Sep 11 10:46 ..
drwxr-xr-x 3 chrisj chrisj  102 Sep 11 10:46 dist
drwxr-xr-x 3 chrisj chrisj  102 Sep 11 10:46 include
-rw-r--r-- 1 chrisj chrisj 186K Sep 11 10:46 index.html
-rw-r--r-- 1 chrisj chrisj  192 Sep 11 10:46 packages.json

That's a fully functioning satis repo! Throw those files into the root of your favorite server and you'll be able to point any PHP projects to it.

In the next post of this series, we'll explore how to dockerize this project.