{"id":13804635,"url":"https://github.com/realshadow/satis-control-panel","last_synced_at":"2026-02-04T20:34:59.627Z","repository":{"id":62534048,"uuid":"48244490","full_name":"realshadow/satis-control-panel","owner":"realshadow","description":"Satis Control Panel (SCP) is a simple web UI for managing your Satis Repository for Composer Packages.","archived":false,"fork":false,"pushed_at":"2019-01-10T12:45:59.000Z","size":1361,"stargazers_count":151,"open_issues_count":8,"forks_count":29,"subscribers_count":7,"default_branch":"master","last_synced_at":"2025-11-02T12:16:33.803Z","etag":null,"topics":["composer","composer-packages","control-panel","proxy","repository-management","satis"],"latest_commit_sha":null,"homepage":null,"language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/realshadow.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-12-18T16:16:21.000Z","updated_at":"2024-04-20T18:08:40.000Z","dependencies_parsed_at":"2022-11-02T16:01:11.541Z","dependency_job_id":null,"html_url":"https://github.com/realshadow/satis-control-panel","commit_stats":null,"previous_names":[],"tags_count":11,"template":false,"template_full_name":null,"purl":"pkg:github/realshadow/satis-control-panel","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/realshadow%2Fsatis-control-panel","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/realshadow%2Fsatis-control-panel/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/realshadow%2Fsatis-control-panel/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/realshadow%2Fsatis-control-panel/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/realshadow","download_url":"https://codeload.github.com/realshadow/satis-control-panel/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/realshadow%2Fsatis-control-panel/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29095444,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-04T20:17:23.003Z","status":"ssl_error","status_checked_at":"2026-02-04T20:16:36.396Z","response_time":62,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["composer","composer-packages","control-panel","proxy","repository-management","satis"],"created_at":"2024-08-04T01:00:51.580Z","updated_at":"2026-02-04T20:34:59.603Z","avatar_url":"https://github.com/realshadow.png","language":"PHP","funding_links":[],"categories":["Packagist-compatible repositories"],"sub_categories":["Satis"],"readme":"[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/realshadow/satis-control-panel/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/realshadow/satis-control-panel/?branch=master) [![Build Status](https://scrutinizer-ci.com/g/realshadow/satis-control-panel/badges/build.png?b=master)](https://scrutinizer-ci.com/g/realshadow/satis-control-panel/build-status/master)\n\n# Satis Control Panel\n\nSatis Control Panel (SCP) is a simple web UI for managing your [Satis Repository](https://github.com/composer/satis) for\n [Composer Packages](https://getcomposer.org/).\n \nSCP backend is written in Laravel and with a React + Typescript combo. \n\n## Features\n\n* simple UI for managing your Satis configuration file for both - private packages and public packages mirrored from [Packagist](https://packagist.org/)\n* no database required - only PHP and optional Nodejs server for automatic generation of Satis configuration file\n* RESTful API for integration with CI services\n* SCP comes with Atlassian plugins for Bamboo and Stash to ease managing package building \n* Cron job for automatic build of public packages mirrored from [Packagist](https://packagist.org/)\n\n## Installation\n\nYou can install SCP directly with Composer by running\n\n```\ncomposer create-project realshadow/satis-control-panel [--stability-dev]\n```\n\nAfter that you can rename `example.env` to `.env` and set required configuration options. \n\n### Building javascript\n```\nnpm run build\n\n// or\n\nnpm run build-win\n```\n\nDuring development you can start Webpack dev server with\n\n```\nnpm start\n```\n\nor run Gulp watcher for `less` files with\n\n```\ngulp watch\n```\n\n### Satis configuration file\n\nIn `resources/` directory you will find `satis.json.dist` file which holds default Satis configuration, copy this file and\nrename it to `satis.json` and edit the `name` and `homepage` property.\n\n```\ncp resources/satis.json.dist resources/satis.json\n```\n\nWhen you are done, you have to set correct permissions for your configuration file for web user. E.g. www-data, should be \nable to read/write this file). More in next *Permissions* section.\n\n### Permissions\n\nFor building to work correctly you have to set correct permissions to few directories/directories:\n\n* bootstrap/cache/\n* storage/\n* public/private/\n* public/public/\n* resources/satis.json\n\nEach directory/file should be readable/writable by web user, e.g. www-data. For example:\n\n```\nchmod -R ug+rwx bootstrap/cache storage public/private public/public\nchmod ug+rwx resources/satis.json\n```\n\n## Webserver setup\n\nYour document root should point to the `public` folder in the root as per default Laravel setup\n\n### Apache - example vhost\n\n```\n\u003cVirtualHost *:80\u003e\n        ServerName satis.example.com\n\n        DocumentRoot /var/www/html/satis.example.com/public\n\u003c/VirtualHost\u003e\n```\n\n### Nginx - example vhost\n\n```\nserver {\n        listen   80 default_server;\n\n        root /var/www/html/satis.example.com/public;\n        index index.php index.html index.htm;\n\n        location / {\n             try_files $uri $uri/ /index.php$is_args$args;\n        }\n\n        # pass the PHP scripts to FastCGI server liste_ning on /var/run/php5-fpm.sock\n        location ~ \\.php$ {\n                try_files $uri /index.php =404;\n                fastcgi_pass unix:/var/run/php5-fpm.sock;\n                fastcgi_index index.php;\n                fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;\n                include fastcgi_params;\n        }\n}\n```\n\n### Visiting your control panel and generated packages\n\nThe control panel is located at `http://{host}/control-panel` and the packages will be generated (after first build of course) at `http://{host}/public`\nand `http://{host}/private` respectively.\n\nSeparating them like this adds a bit more configuration options. If for example you want to only use private packages, \nyou can change the directory of `private_repository` configuration option to `public` instead of `public/private` and have your \npackages generated at `http://{host}` and still have a functioning control panel.\n\n## Configuration options\n\nHere is a list of configuration options that can be set in `config/satis.php` (some of them can be set in `.env` file as well for convenience):\n\n|             Option | Description                                                                                                                                                                            | Default value          | Can be set in `.env` |\n|-------------------:|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------------------|----------------------|\n| config             | Path to satis configuration file                                                                                                                                                       | resources/satis.json   | Yes                  |\n| composer_home      | Composer home directory (thi                                                                                                                                                           | storage/composer       | Yes                  |\n| composer_cache     | Composer cache directory                                                                                                                                                               | storage/composer/cache | Yes                  |\n| memory_limit       | Memory limit that will be set before running Satis build command                                                                                                                       | 2G                     | No                   |\n| build_verbosity    | Verbosity of Satis build command (more info will be stored in logs)                                                                                                                    | vvv                    | No                   |\n| private_repository | Directory where Satis will generate private repository. This also serves as a way to distinguish public and private repositories in repository address, e.g. satis.example.com/private | private                | No                   |\n| public_repository  | Directory where Satis will generate public repository. This also serves as a way to distinguish public and private repositories in repository address, e.g. satis.example.com/public   | public                 | No                   |\n| proxy.http         | Proxy address that will be used by Satis/Composer for HTTP requests                                                                                                                    | null                   | Yes                  |\n| proxy.https        | Proxy address that will be used by Satis/Composer for HTTPS requests                                                                                                                   | null                   | Yes                  |\n| proxy.https        | See https://www.selenic.com/mercurial/hg.1.html#environment-variables for details                                                                                                      | null                   | Yes                  |\n\n**Note:** if you change the default directory, remember to set correct permissions for your new directory.\n\n## How it works\n\nSCP manages a single Satis configuration file which is generated on the fly when specific UI actions are performed. \nDuring each generation cycle the file is split into public and private repository configuration file, because private\npackages use funcionality that doesn't work well with Packagist (it will try to mirror whole Packagist repository).\n\nBesides adding, editing and removing packages/repositories from configuration file, UI allows you to build/rebuild every\npackage or run a complete rebuild of all registered packages/repositories.\n\nBuild process can run synchronously or asynchronously (by redirecting output to `/dev/null` and spawning a new process). By default,\nall builds run asynchronously, except on Windows where they are forced to run synchronously. This can be also forced during during API\nrequest by setting `async_mode` to `false`.\n\n### Missing or broken mirrored configuration files\n\nSince the configuration files mirroring is triggered by any UI action, it is not always the correct behaviour. If you want to manually\ntrigger config generation, for example when you make changes directly on the server, you can trigger the config generation with this\nartisan command\n\n```\nphp artisan satis:make:config\n```\n\n### UI State\n\nDuring build process whole UI is locked. During asynchronous builds UI state is handled by Node server, but running it is completely\noptional. \n\nIt can be started with\n\n```\nnpm run server\n```\n\nand will run on port `9010` by default. This can be changed in `node/config.json` file.\n\nIf for some reason UI will stay locked even though no packages are currently being build, it can be unlocked by running:\n\n```\nphp artisan satis:persister:unlock\n```\n\n### Composer auth\n\nComposer file `auth.json` can be put in `COMPOSER_HOME` directory where you can put your Github token or credentials for\nneeded for private repositories.\n\n### Private packages\n\nPrivate packages are identified by repository URL address. When you will add/edit a new repository you can choose its type.\nBy default, all repositories are considered as `VCS` repository. Building and rebuilding is handled by `partial update` \nfunctionality introduced in [this PR](https://github.com/composer/satis/pull/266) only repositories that have a URL can be\nmanaged in UI. Those include:\n\n* vcs\n* hg\n* pear\n* composer\n* artifact\n* path\n\nAdding support for more repository types is planned in future.\n\nPrivate packages use the `repositories` config key with `require-all` options set to `true`, thus all known packages are\ntaken out of registered repositories, which means that Packagist must be disabled by default. This is handled when configs\nare split into private public part.\n\n### Public (packagist) packages\n\nPublic packages are used for mirroring of existing packages that can be installed from Packagist if you are behind a corporate\nproxy, thus speeding up overall development and deployment time.\n\nAll packages added here are *fully* mirrored with all their dependencies (but we still skip `dev-dependencies`). Currently\nonly one version constraint is used and that's `*` so we can get a complete packagist clone. \n\nAdding support for custom version constraints is planned in future.\n\nSince full rebuild in this case could potentionally take few hours, you can use provided Cron task for a daily rebuild (see *Cron task* section).\n\n**Note though that you should not try to mirror whole Packagist repository!**\n\n## RESTful API\n\nSCP comes with built in API for esier integration with your favorite CI solution. \n\n### Private packages\n\nPrivate packages use `md5` encoded repository url as ID.\n\n* get all repositories\n\n```\nGET control-panel/api/repository\n```\n\n* get one repository\n\n```\nGET control-panel/api/repository/{repository_id}\n```\n\n* add new repository\n\n```\nPOST control-panel/api/repository\n{\n    'url': 'foo',\n    'type: 'bar'\n}\n```\n\n* update existing repository\n\n```\nPUT control-panel/api/repository/{repository_id}\n{\n    'url': 'foo',\n    'type: 'bar'\n}\n```\n\n* delete existing repository\n\n```\nDELETE control-panel/api/repository/{repository_id}\n```\n\n\nAll methods return `HTTP 404` if no repository is found. \n\n**Note:** same API can be used for public packages as well by replacing `repository` by `package`. Although remote control of public packages is not necessary.\n\n### Additional API options\n\nDuring both `POST` and `PUT` requests two additional options can be provided:\n\n* **async_mode** - *true/false* =\u003e if the build should run synchronously or asynchronously (all builds run asynchronously by default) \n* **disable_build** - *true/false* =\u003e if set to `true` Satis build command won't be run\n \n## Logs\n\nAll logs can be found in `storage/logs` directory. Logs are divided into:\n\n* *api_request.log* - logs all API requests\n* *builder_async.log* - logs all builds that run asynchronously, keep in mind that each asynchronous build has its own log file in `async` subdirectory identified by its timestamp\n* *builder_sync.log* - logs all builds that run synchronously\n* *cron.log* - for cron task logs\n\n## Cron task\n\nSince mirroring of public packages can take some time and running full rebuild from UI is not a good idea, because this will lock it during the\nbuild process, SCP comes with a built in cron task that runs daily and will rebuild all repositories. It can be triggered with a cron entry\nsimilar to this:\n\n```\n* * * * * php /path/to/satis-folder/artisan schedule:run \u003e\u003e /dev/null 2\u003e\u00261\n```\n\nAlternatively, you can add this cron entry:\n\n```\n00 00 * * * curl --request POST --header \"Content-Length: 0\" --header \"X-Requested-With: XMLHttpRequest\" http://{scp-url-address}/control-panel/build-public\n```\n\nThis can be used for private packages as well\n\n```\n00 00 * * * curl --request POST --header \"Content-Length: 0\" --header \"X-Requested-With: XMLHttpRequest\" http://{scp-url-address}/control-panel/build-private\n```\n\n## Atlassian plugins\n\nSCP was created in an environment which uses Atlassian Stash and Bamboo as part of CI and thus two plugins were needed to\ncompletely integrate Composer packages into our build process.\n\n* [Stash Satis Build Hook](https://github.com/realshadow/stash-satis-build-hook.git) - a post receive hook that will register and trigger a build/rebuild of your package in SCP (if you want to skip deployment process)\n* [Bamboo Satis Build](https://github.com/realshadow/bamboo-satis-build.git) - a deployment task for rebuilding currently deployed Composer package in Satis repository\n \nBoth use `partial update` functionality which was introduced in [this PR](https://github.com/composer/satis/pull/266).\n\n## TODO\n\n* option to import composer.lock file for public packages\n* option to use more types of private packages\n* option to write custom version constraints for public packages\n* option to see what's going during long running builds of public packages \n* better handling of race conditions during simultaneous writes/reads\n* authentification? (this can be simply handled with htpasswd)\n* ????\n\nPR's are welcome\n\n## Alternatives\n\n* [Satis Go](https://github.com/benschw/satis-go)\n* [Toran proxy](https://toranproxy.com/)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frealshadow%2Fsatis-control-panel","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frealshadow%2Fsatis-control-panel","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frealshadow%2Fsatis-control-panel/lists"}