Using Satis for fast and reliable software deployment


If you're familiar with Composer you know it can be slow and sometimes unreliable when one or more packages are not available.

composer failure example

Every time you run composer update Composer will access Packagist to check for new versions of the packages you use. When it finds new releases it will access GitHub, BitBucket (or wherever the packages are hosted) to download your packages.

We need something reliable and fast! We need Satis.

Satis is basically your own private version of Packagist. It can be used to:

  • define the locations of your private repositories,
  • proxy the locations of public repositories and
  • host the actual packages in your own server environment.

Seeing is believing

Let's install Satis right away!

composer create-project composer/satis --stability=dev --keep-vcs

Now create a Satis repository with the following satis.json:

{
    "name": "Qandidate.com Repository",
    "homepage": "https://satis.qandidate.com",
    "repositories": [
        {
            "type": "vcs",
            "url": "git@github.com:asm89/Rx.PHP.git"
        }
    ],
    "require-all": true
}
  • homepage must be set to the URL of your Satis repository if you want the web interface to generate proper hyperlinks.
  • repositories is where specify your (private) repositories. Besides private repositories you may also want to proxy public 3rd party repositories. For instance if your project uses the Symfony framework why not proxy its repositories so you have quick access the packages you need.
  • require-all whether or not to host all versions or just tagged releases.

Which packages?

You probably know best what package versions you need. So set require-all to false and use the require section to specify your requirements.

{
    "repositories": [
        {
            "type": "vcs",
            "url": "git@github.com:asm89/stack-cors.git"
        },
        {
            "type": "vcs",
            "url": "git@github.com:asm89/twig-cache-extension.git"
        }
    ],
    "require-all": false,
    "require": {
        "asm89/stack-cors": "0.1.0",
        "asm89/twig-cache-extension": "*"
    }
}

Build and publish your repository

Now we can actually build our repository using

satis build satis.json qandidate-satis-dir

It also creates a nice web interface showing all the information of your packages. All you have to do is publish your repository on a webserver. Just use PHP's built-in webserver for now:

php -S localhost:8001 -t qandidate-satis-dir/

The web interface looks like this:

Satis web interface

Hosting your packages

Now it's time to actually host packages on your Satis repo. The archive option allows you to specify where to store downloads and in which format.

"archive": {
    "directory": "dist",
    "format": "tar",
    "skip-dev": true
}

Setting skip-dev to false will prevent downloading of branches. Run the build command again to download the packages. Note that only tagged versions of packages are available for download!

Is it fast?

Yes and no! It is only fast when you can disable Packagist altogether, i.e. when all your dependencies are hosted by Satis. Check the update below on how to do this.

Is it reliable?

Yes! You have full control of the packages and versions you need and when to get them. Now you know they are available when you need to deploy your app!

Final thoughts

Make sure to think about securing your repository. Our repo is hosted on our private network. You can also use SSH or SSL (i.e. HTTPS) to encrypt the connection to your Satis repo. Check the documentation for details.

You can build the repository periodically in a cron job. The user that runs the cron will need a public key to access GitHub. Add the --no-interaction option to build command to use public key authentication instead of prompting for a password:

satis build --no-interaction satis.json qandidate-satis-dir

Update: dependencies

As meadsteve pointed out in the comments there is an option require-dependencies which tells Satis to download all the dependencies of the packages you require.

This makes life a lot easier as you can now disable Packagist without having to specify dependencies!

To wrap it up, my final satis.json looks like this:

{
    "name": "Qandidate.com",
    "homepage": "http://localhost:8001",
    "repositories": [
        { "type": "composer", "url": "https://packagist.org" },
        { "type": "vcs", "url": "git@github.com:asm89/stack-cors.git" }
    ],
    "require-all": false,
    "require": {
        "asm89/stack-cors": "0.1.0",
    },
    "require-dependencies": true,
    "archive": {
        "directory": "dist",
        "format": "tar",
        "skip-dev": true
    }
}

Now create a new project with the following composer.json:

{
    "repositories" : [
        {"packagist" : false},
        {"type" : "composer", "url" : "http://localhost:8001/"}
    ],
    "require": {
        "asm89/stack-cors": "0.1.0"
    }
}

Run composer install and it will complete faster than you've ever seen before!