API-Docker

 view release on metacpan or  search on metacpan

lib/API/Docker/API/Containers.pm  view on Meta::CPAN

  return $self->_wrap($result);
}


sub start {
  my ($self, $id) = @_;
  croak "Container ID required" unless $id;
  return $self->client->post("/containers/$id/start", undef);
}


sub stop {
  my ($self, $id, %opts) = @_;
  croak "Container ID required" unless $id;
  my %params;
  $params{t}      = $opts{timeout} if defined $opts{timeout};
  $params{signal} = $opts{signal}  if defined $opts{signal};
  return $self->client->post("/containers/$id/stop", undef, params => \%params);
}


sub restart {
  my ($self, $id, %opts) = @_;
  croak "Container ID required" unless $id;
  my %params;
  $params{t} = $opts{timeout} if defined $opts{timeout};
  return $self->client->post("/containers/$id/restart", undef, params => \%params);
}


sub kill {
  my ($self, $id, %opts) = @_;
  croak "Container ID required" unless $id;
  my %params;
  $params{signal} = $opts{signal} if defined $opts{signal};
  return $self->client->post("/containers/$id/kill", undef, params => \%params);
}


sub remove {
  my ($self, $id, %opts) = @_;
  croak "Container ID required" unless $id;
  my %params;
  $params{v}     = $opts{volumes} ? 1 : 0 if defined $opts{volumes};
  $params{force} = $opts{force} ? 1 : 0   if defined $opts{force};
  $params{link}  = $opts{link} ? 1 : 0    if defined $opts{link};
  return $self->client->delete_request("/containers/$id", params => \%params);
}


sub logs {
  my ($self, $id, %opts) = @_;
  croak "Container ID required" unless $id;
  my %params;
  $params{stdout}     = defined $opts{stdout} ? ($opts{stdout} ? 1 : 0) : 1;
  $params{stderr}     = defined $opts{stderr} ? ($opts{stderr} ? 1 : 0) : 1;
  $params{since}      = $opts{since}      if defined $opts{since};
  $params{until}      = $opts{until}      if defined $opts{until};
  $params{timestamps} = $opts{timestamps} ? 1 : 0 if defined $opts{timestamps};
  $params{tail}       = $opts{tail}       if defined $opts{tail};
  return $self->client->stream_frames('GET', "/containers/$id/logs",
    params => \%params,
    defined $opts{tty} ? ( tty => $opts{tty} ) : (),
  );
}


sub top {
  my ($self, $id, %opts) = @_;
  croak "Container ID required" unless $id;
  my %params;
  $params{ps_args} = $opts{ps_args} if defined $opts{ps_args};
  return $self->client->get("/containers/$id/top", params => \%params);
}


sub stats {
  my ($self, $id, %opts) = @_;
  croak "Container ID required" unless $id;
  my %params;
  $params{stream}     = 0;
  $params{'one-shot'} = 1;
  return $self->client->get("/containers/$id/stats", params => \%params);
}


sub wait {
  my ($self, $id, %opts) = @_;
  croak "Container ID required" unless $id;
  my %params;
  $params{condition} = $opts{condition} if defined $opts{condition};
  return $self->client->post("/containers/$id/wait", undef, params => \%params);
}


sub pause {
  my ($self, $id) = @_;
  croak "Container ID required" unless $id;
  return $self->client->post("/containers/$id/pause", undef);
}


sub unpause {
  my ($self, $id) = @_;
  croak "Container ID required" unless $id;
  return $self->client->post("/containers/$id/unpause", undef);
}


sub rename {
  my ($self, $id, $name) = @_;
  croak "Container ID required" unless $id;
  croak "New name required" unless $name;
  return $self->client->post("/containers/$id/rename", undef, params => { name => $name });
}


sub update {
  my ($self, $id, %config) = @_;
  croak "Container ID required" unless $id;
  return $self->client->post("/containers/$id/update", \%config);
}


sub prune {
  my ($self, %opts) = @_;
  my %params;
  $params{filters} = $opts{filters} if defined $opts{filters};
  return $self->client->post('/containers/prune', undef, params => \%params);
}



1;

__END__

=pod

=encoding UTF-8

=head1 NAME

API::Docker::API::Containers - Docker Engine Containers API

=head1 VERSION

version 0.003

=head1 SYNOPSIS

    my $docker = API::Docker->new;

    # List containers
    my $containers = $docker->containers->list(all => 1);
    for my $container (@$containers) {
        say $container->Id;
        say $container->Status;
    }

    # Create and start a container
    my $result = $docker->containers->create(
        Image => 'nginx:latest',
        name  => 'my-nginx',
        ExposedPorts => { '80/tcp' => {} },
    );
    $docker->containers->start($result->{Id});

    # Inspect container details
    my $container = $docker->containers->inspect($result->{Id});
    say $container->Name;

    # Stop and remove
    $docker->containers->stop($result->{Id}, timeout => 10);
    $docker->containers->remove($result->{Id});

    # View logs (ArrayRef of { stream => 'stdout'|'stderr'|'raw', data => ... })
    my $frames = $docker->containers->logs($result->{Id}, tail => 100);
    my $text = join '', map { $_->{data} } @$frames;

=head1 DESCRIPTION

This module provides methods for managing Docker containers including creation,
lifecycle operations (start, stop, restart), inspection, logs, and more.

All C<list> and C<inspect> methods return L<API::Docker::Container> objects
for convenient access to container properties and operations.

Accessed via C<< $docker->containers >>.

=head2 client

Reference to L<API::Docker> client. Weak reference to avoid circular dependencies.

=head2 list

    my $containers = $containers->list(%opts);

List containers. Returns ArrayRef of L<API::Docker::Container> objects.

Options:

=over

=item * C<all> - Show all containers (default shows just running)

=item * C<limit> - Limit results to N most recently created containers

=item * C<size> - Include size information

=item * C<filters> - Hashref of filters

=back

=head2 create

    my $result = $containers->create(
        Image => 'nginx:latest',
        name  => 'my-nginx',
        Cmd   => ['/bin/sh'],
        Env   => ['FOO=bar'],
    );

Create a new container. Returns hashref with C<Id> and C<Warnings>.

The C<name> parameter is extracted and passed as query parameter. All other
parameters are Docker container configuration (see Docker API documentation).

Common config keys: C<Image>, C<Cmd>, C<Env>, C<ExposedPorts>, C<HostConfig>.

=head2 inspect

    my $container = $containers->inspect($id);

Get detailed information about a container. Returns L<API::Docker::Container> object.

=head2 start

    $containers->start($id);

Start a container.

=head2 stop

    $containers->stop($id, timeout => 10);

Stop a container.

Options:

=over

=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);

Remove a container.

Options:

=over

=item * C<force> - Force removal (kill if running)

=item * C<volumes> - Remove associated volumes

=item * C<link> - Remove specified link

=back

=head2 logs

    my $frames = $containers->logs($id, tail => 100, timestamps => 1);

    # stdout and stderr, in the order the engine emitted them
    my $text = join '', map { $_->{data} } @$frames;

    # stderr only
    my @errors = grep { $_->{stream} eq 'stderr' } @$frames;

Get container logs. Returns an ArrayRef of frames, each a HashRef with
C<stream> and C<data>:

    [ { stream => 'stdout', data => "OUT\n" },
      { stream => 'stderr', data => "ERR\n" } ]

A container created without a TTY multiplexes stdout and stderr into a single
framed stream, and this method demultiplexes it -- without that, the 8-byte
frame headers end up in the caller's log text. A container created B<with> a
TTY writes to one pty and the engine sends no frame headers, so its whole
output arrives as a single frame with C<< stream => 'raw' >>: with a TTY there
is no stdout/stderr distinction left to report. C<stream> is always a plain
string, so C<< $_->{stream} eq 'stderr' >> is safe on any frame.

Framing is detected from the response bytes, because the engine's
C<Content-Type> cannot be trusted for it -- see
L<API::Docker::Role::HTTP/"Detecting a framed stream"> for the rule and its one
failure mode.

Options:

=over

=item * C<stdout> - Include stdout (default 1)

=item * C<stderr> - Include stderr (default 1)

=item * C<since> - Show logs since timestamp

=item * C<until> - Show logs before timestamp

=item * C<timestamps> - Include timestamps

=item * C<tail> - Number of lines from end (e.g., C<100> or C<all>)

=item * C<tty> - Set to 1 when the container was created with a TTY and its
output is binary, to skip demultiplexing. Not needed for text output. The
container's own setting is C<Config.Tty> from C<< $containers->inspect($id) >>

=back

=head2 top

    my $processes = $containers->top($id, ps_args => 'aux');

List running processes in a container. Returns hashref with C<Titles> and C<Processes> arrays.

=head2 stats

    my $stats = $containers->stats($id);

Get container resource usage statistics (CPU, memory, network, I/O). Returns one-shot statistics.

=head2 wait

    my $result = $containers->wait($id, condition => 'not-running');

Block until container stops, then return exit code. Optional C<condition> parameter.

=head2 pause

    $containers->pause($id);

Pause all processes in a container.

=head2 unpause

    $containers->unpause($id);

Unpause all processes in a container.

=head2 rename

    $containers->rename($id, 'new-name');

Rename a container.



( run in 1.205 second using v1.01-cache-2.11-cpan-2e0ccfb7a10 )