PHP에서 Composer를 통해 사용할 수 있는 패키지 리포지터리 서비스인 Packagist는 오픈소스로 공개되어 있어서 필요하면 누구든지 받아 사용할 수 있게 되어 있다. 하지만 Solr이라든지 Redis라든지 요구하는 환경이 있어서 Packagist의 모든 기능이 필요한 경우가 아니고서는 또 관리할 거리 하나 늘리는 일이 되는 것 같아 쉽게 마음이 가지 않았다. 그동안 패키지로 만들 만한 개발을 하질 않았었는데 지금 다니는 곳에서는 조금씩 패키지로 갖춰두기 좋은 코드를 작성하고 있어서 찾아보던 중 Satis가 간편했다.

Satis는 Composer에서 사용 가능한 패키지 리포지터리를 생성해주는 도구다. Packagist와는 다른 점이 있는데 바로 정적 파일로 생성한다는 점이다. jekyll이나 hexo, hugo같은 도구처럼 정적 페이지를 만드는데 단지 그 파일이 composer에서 사용할 수 있는 피드라고 생각하면 이해하기 쉬울지도 모르겠다. 패키지 리포지터리 자체에 패키지를 압축이나 바이너리 형태로 갖고 있지 않기 때문에 이런 점에서는 좀 더 유연할 수 있는 것 같다. (물론 포함하는 방식도 가능하다.)

composer로 전역 설치해도 되고 제공하는 docker 이미지를 사용해도 된다. Satis를 기반으로 만들어진 패키지도 여럿 있는데 간단하게 만들어 쓰는 부분까지 넣었다.

전역 설치로 사용하기

Satis는 composer로 쉽게 설치할 수 있다.

$ composer global require composer/satis:dev-master

이제 satis를 사용할 수 있다. 먼저 피드 설정 파일인 satis.json을 생성해야 한다. 이 과정에서 나오는 Home page는 생성된 패키지 리포지터리를 올릴 주소로 입력하면 된다. 나중에 쉽게 바꿀 수 있으니 크게 고민하지 않아도 된다.

$ satis init

  Welcome to the Satis config generator  

This command will guide you through creating your Satis config.

Repository name: hello world
Home page: http://satis.haruair.com/

  Your configuration file successfully created!  


You are ready to add your package repositories
Use satis add repository-url to add them.

프롬프트로 내용을 입력하고 나면 다음과 같은 json 파일이 생성된다.

{
    "name": "hello world",
    "homepage": "http://satis.haruair.com/",
    "repositories": [],
    "require-all": true
}

먼저 동작을 확인하기 위해 별도의 리포지터리 없이 페이지를 생성한다.

$ satis build satis.json output
$ ls output 
include index.html packages.json

설정 파일과 페이지를 생성할 경로와 함께 build 명령에 사용하면 위처럼 페이지가 생성된다. index.html을 열어보면 간단한 인터페이스와 함께 생성된 패키지 리포지터리를 확인할 수 있다.

이제 이 패키지 리포지터리에 등록할 패키지를 추가한다. 물론 해당 패키지는 composer.json 파일이 존재해야 한다. 주소를 등록했으면 다시 빌드를 수행한다.

$ satis add https://github.com/haruair/wattle.git

  Your configuration file successfully updated! It is time to rebuild your repository  

$ satis build satis.json output
Scanning packages
wrote packages to output/include/all$c23b16e038827b7e1083abaa05c5997d7f334d23.json
Writing packages.json
Pruning include directories
Deleted output/include/all$96e5c0926e9d7f87094d1ba307e38ea76cd09c53.json
Writing web view

패키지 정보가 추가되었다. 생성된 json을 열어보면 해당 패키지에 대한 메타데이터를 확인할 수 있다. index.html에서도 확인 가능하다.

Satis

위 스크린샷 상단에 보면 repositories 내용이 있는 json을 확인할 수 있다. 이 리포지터리를 사용할 패키지의 composer.json에 추가해야 하는 내용이다. repositories로 추가하면 새로 추가하는 패키지가 존재하는지 그 경로에서 먼저 확인하고 없는 경우에는 공식 packagist에서 패키지를 받아오는 식으로 동작한다. 이제 output 경로에 있는 파일을 지정했던 Home page 주소로 옮기면 끝난다.

다만 composer에서 리포지터리로 사용할 수 있는 주소는 기본적으로 https로 제한되어 있다. 만약 배포하는 위치가 https를 사용하지 않는다면 0. github pages를 배포처로 쓴다, 1. letsencrypt를 적용한다, 2. cloudflare를 적용한다, 3. self-signing ssl을 사용한다, 5. composer.json에서 config.secure-httpfalse로 지정한다 정도의 해결 방법이 있다. (순서는 추천하는 순서. 5번은 권장 안한다.)

Docker로 사용하기

전역으로 설치하면 늘 찝찝한데 고맙게도 docker 이미지도 공식으로 제공하고 있다.

$ docker pull composer/satis
$ docker run --rm -it -v /path/to/build:/build -v $COMPOSER_HOME:/composer composer/satis

/path/to/buildsatis.json이 위치한 로컬 경로고 $COMPOSER_HOME은 컴포저가 설치된 경로로 기본 설치를 한 경우는 ~/.composer에 해당한다. composer를 지정하면 현재 컴퓨터에 설정된 composer를 사용하기 때문에 auth.json에 저장되어 있는 정보를 그대로 사용할 수 있다.

자세한 내용은 Satis 리포지터리 설명을 참고한다.

조금 유연하게 사용하기

내 경우에는 학교 내 내부망에 위치한 gitlab을 사용하고 있고 내 IP도 특정 주소로 이미 바인딩되어 있었다. 그래서 요청이 왔을 때 새로운 리포지터리를 추가하고 빌드를 수행하도록 php로 작성해서 webhook에 연결했다.

주석에도 썼지만 이 코드는 서두에 접속 권한을 검증하는 부분이 필요하다.

<?php
// Warning: This code is not production-ready!
// Add more validation process, First.

$input = file_get_contents('php://input');
$payload = json_decode($input);

if (json_last_error() === JSON_ERROR_NONE || empty($payload)) {
  echo json_encode([
    'ok' => false,
    'message' => 'A payload is invalid',
  ]);
  exit;
}

exec('satis add ' . $payload->repository->clone_url);
exec('satis build satis.json .');

echo json_encode(['ok' => true]);

Satis를 사용하는 방법을 간단하게 확인했다. Packagist를 설치하거나 Private Packagist를 사용하는 것도 좋지만 설정에 시간을 많이 쓰고 싶지 않다면 Satis도 좋은 선택지다. 정적 블로그 생성기에 익숙하다면 비슷한 접근 방식으로 travis-ci에 연동해서 자동 생성한 패키지 리포지터리를 GitHub pages로 발행하는 등 다양한 방법으로 활용할 수 있을 것 같다.

색상을 바꿔요

눈에 편한 색상을 골라보세요 :)

Darkreader 플러그인으로 선택한 색상이 제대로 표시되지 않을 수 있습니다.