API-Docker
view release on metacpan or search on metacpan
.claude/CLAUDE.md view on Meta::CPAN
# API-Docker
Perl client for the Docker Engine API.
## Docker Engine API
- **Unix Socket**: Default transport via `/var/run/docker.sock`
- **TCP**: Remote Docker daemons via `tcp://host:port`
- **TLS**: Optional TLS for secure remote connections
- **Auto-Negotiate**: Detects highest API version from daemon
## Build & Test
```bash
dzil build
dzil test
prove -lv t/
```
over `WebSearch` for any web lookup.
2. **Use `mcp__firecrawl__firecrawl_scrape`** over `WebFetch` for fetching
page content.
3. **Use `context7` for library docs** (CPAN, npm, etc.) â *except* this
distribution itself. For `API::Docker` always read the local source
under `lib/`, never context7.
4. **Untracked files that are not in `.gitignore` belong in the commit.**
`.gitignore` is the source of truth. Only obvious secrets
(`.env`, credentials) are excluded â and even then warn, don't silently
drop them.
5. **Auto-Memory is for personal/user preferences only.** Project
conventions belong in this `CLAUDE.md` or in a skill, never in
auto-memory.
6. **Load the `perl-core` skill before editing any Perl** in this
workspace. It encodes Getty's house rules; the rules below are the
TL;DR.
lib/API/Docker.pm view on Meta::CPAN
=head2 api_version
Docker API version to use (e.g., C<1.41>). If not set, the client will
automatically negotiate the highest API version supported by the daemon.
This attribute is set automatically by L</negotiate_version>.
=head2 tls
Enable TLS for secure connections. Defaults to C<0>. Currently experimental.
=head2 cert_path
Path to TLS certificates. Defaults to C<$ENV{DOCKER_CERT_PATH}>.
=head2 system
Returns L<API::Docker::API::System> instance for system operations like
C<info>, C<version>, C<ping>, and C<events>.
lib/API/Docker/API/Containers.pm view on Meta::CPAN
=item * C<timeout> - Seconds to wait before killing (default 10)
=item * C<signal> - Signal to send (default SIGTERM)
=back
=head2 restart
$containers->restart($id, timeout => 10);
Restart a container. Optionally specify C<timeout> in seconds.
=head2 kill
$containers->kill($id, signal => 'SIGKILL');
Send a signal to a container. Default signal is C<SIGKILL>.
=head2 remove
$containers->remove($id, force => 1, volumes => 1);
lib/API/Docker/API/Images.pm view on Meta::CPAN
=item * C<labels> - HashRef of labels to set on the image
=item * C<memory> - Memory limit in bytes
=item * C<memswap> - Total memory (memory + swap), -1 to disable swap
=item * C<cpushares> - CPU shares (relative weight)
=item * C<cpusetcpus> - CPUs to use (e.g. C<0-3>, C<0,1>)
=item * C<cpuperiod> - CPU CFS period (microseconds)
=item * C<cpuquota> - CPU CFS quota (microseconds)
=item * C<shmsize> - Size of /dev/shm in bytes
=item * C<networkmode> - Network mode during build
=item * C<platform> - Platform (e.g. C<linux/amd64>)
=item * C<target> - Multi-stage build target
=back
lib/API/Docker/API/Images.pm view on Meta::CPAN
my $history = $images->history('nginx:latest');
Get image history (layers). Returns ArrayRef of layer information.
=head2 push
$images->push('myrepo/nginx', tag => 'v1');
$images->push('myrepo/nginx', auth => {
username => 'me',
password => 'secret',
serveraddress => 'https://index.docker.io/v1/',
});
Push an image to a registry. Optionally specify C<tag>.
The Docker Engine requires an C<X-Registry-Auth> header on every push,
even for anonymous attempts; the header is always sent. Pass C<auth> as
a hashref of credentials (typical keys: C<username>, C<password>,
C<serveraddress>, or C<identitytoken>), or as a pre-encoded base64 string.
Without C<auth> the header carries an empty JSON object.
t/containers.t view on Meta::CPAN
unless (is_live()) {
is(scalar @$containers, 2, 'two containers');
my $first = $containers->[0];
is($first->Id, 'abc123def456', 'container id');
is_deeply($first->Names, ['/my-container'], 'container names');
is($first->Image, 'nginx:latest', 'container image');
is($first->State, 'running', 'container state');
ok($first->is_running, 'is_running returns true for running container');
my $second = $containers->[1];
is($second->Id, 'def789ghi012', 'second container id');
is($second->State, 'exited', 'second container state');
ok(!$second->is_running, 'is_running returns false for exited container');
}
};
# --- Write Tests (mock always, live only with WRITE) ---
subtest 'container lifecycle' => sub {
skip_unless_write();
my $docker = test_docker(
'POST /containers/create' => { Id => 'mock123', Warnings => [] },
t/images_push_auth.t view on Meta::CPAN
subtest 'empty/undef auth -> base64url("{}")' => sub {
my $hdr = API::Docker::API::Images::_build_registry_auth_header(undef);
ok length($hdr), 'header is non-empty for undef';
is_deeply(decode_json(b64url_decode($hdr)), {},
'decodes to empty JSON object');
};
subtest 'hashref auth -> JSON-encoded credentials' => sub {
my $auth = {
username => 'me',
password => 'secret',
serveraddress => 'https://index.docker.io/v1/',
};
my $hdr = API::Docker::API::Images::_build_registry_auth_header($auth);
is_deeply(decode_json(b64url_decode($hdr)), $auth,
'header roundtrips through base64url + JSON');
};
subtest 'identitytoken auth' => sub {
my $auth = { identitytoken => 'tok-123', serveraddress => 'ghcr.io' };
my $hdr = API::Docker::API::Images::_build_registry_auth_header($auth);
( run in 1.284 second using v1.01-cache-2.11-cpan-995e09ba956 )