Skip to content

aniongithub/DockerClient

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

27 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

C++ Docker Client

A C++ client library for the Docker Engine API.

Using in Your Project

Recommended: Using FetchContent (CMake 3.14+)

The easiest way to use this library in your project is with CMake's FetchContent:

cmake_minimum_required(VERSION 3.14)
project(my_docker_app)

include(FetchContent)

# Fetch DockerClient library
FetchContent_Declare(
    DockerClient
    GIT_REPOSITORY https://github.com/aniongithub/DockerClient.git
    GIT_TAG        main  # or specific tag/commit
)
FetchContent_MakeAvailable(DockerClient)

# Create your executable
add_executable(my_app main.cpp)
target_link_libraries(my_app docker-cpp)

Alternative: Manual Installation

If you prefer system-wide installation:

git clone https://github.com/aniongithub/DockerClient.git
cd DockerClient
mkdir build && cd build
cmake ..
make -j$(nproc)
sudo make install

Then in your CMake project:

find_package(docker-cpp REQUIRED)
target_link_libraries(your_target docker-cpp::docker-cpp)

Development

Build Requirements

  • CMake 3.14 or higher
  • C++11 compatible compiler
  • Git (for fetching dependencies)

Dependencies

All dependencies are automatically downloaded and built using CMake's FetchContent:

  • libcurl - For HTTP communication with Docker API
  • RapidJSON - For JSON parsing (header-only)

Building from Source

git clone https://github.com/aniongithub/DockerClient.git
cd DockerClient
mkdir build && cd build
cmake ..
make -j$(nproc)

CMake Options

The build system will automatically:

  • Download and compile libcurl with OpenSSL support
  • Download RapidJSON headers
  • Build the shared library (libdocker-cpp.so)
  • Build the test executable

Example

See the example/ directory for a complete working example that demonstrates:

  • Connecting to Docker daemon
  • High-level container execution with run_container_async()
  • Attaching and detaching log streams
  • Real-time stdout/stderr callbacks
  • Integration with low-level API methods
  • Proper cleanup and error handling

To build and run the example:

# From the build directory
make
./example/docker-example

API Usage

Low-Level API (Docker Engine REST API)

The library provides direct access to Docker's REST API:

#include "docker.h"
int main(){
    Docker client = Docker();

    // List containers
    JSON_DOCUMENT doc = client.list_containers(true); 
    std::cout << jsonToString(doc) << std::endl;

    // Create and start container manually
    JSON_DOCUMENT create_params(rapidjson::kObjectType);
    create_params.AddMember("Image", "ubuntu:latest", create_params.GetAllocator());
    
    JSON_DOCUMENT result = client.create_container(create_params, "my-container");
    std::string container_id = result["data"]["Id"].GetString();
    
    client.start_container(container_id);
    client.wait_container(container_id);
    client.delete_container(container_id);

    return 0;
}

High-Level API (Container Execution & Log Streaming)

For common use cases, the library provides convenient high-level methods:

#include "docker.h"
int main(){
    Docker client = Docker();

    // 1. Start container asynchronously
    std::string container_id = client.run_container_async(
        "ubuntu:latest",
        {"echo", "Hello World!"},
        "my-container"
    );

    if (!container_id.empty()) {
        // 2. Attach log stream with callbacks
        auto stdout_callback = [](const std::string& data) {
            std::cout << "Container output: " << data;
        };
        
        auto stderr_callback = [](const std::string& data) {
            std::cerr << "Container error: " << data;
        };

        client.attach_log_stream(container_id, stdout_callback, stderr_callback);

        // 3. Wait for completion using low-level API
        client.wait_container(container_id);

        // 4. Detach logs and cleanup
        client.detach_log_stream(container_id);
        client.delete_container(container_id, false, true);
    }

    return 0;
}

Capturing Output to Strings

std::string captured_stdout, captured_stderr;

auto capture_stdout = [&captured_stdout](const std::string& data) {
    captured_stdout += data;
};

auto capture_stderr = [&captured_stderr](const std::string& data) {
    captured_stderr += data;
};

std::string container_id = client.run_container_async("ubuntu", {"echo", "test"});
client.attach_log_stream(container_id, capture_stdout, capture_stderr);
client.wait_container(container_id);

std::cout << "Captured output: " << captured_stdout << std::endl;

Return of Each Methods

Every return type is JSON_OBJECT (alias of rapidjson::Document)

Refer to RapidJSON for the detailed usage

Object o;
 - success        [bool]                  : if succeeded to request
 - data           [Object/Array/string]   : actual data by server
 - code(optional) [int]                   : http status code if 'success' is false

Data type of 'data' depends on API, but it would be Object if 'success' is false.

e.g.

{
  "success": false,
  "code": 404,
  "data": {
      "message": "No such container: 5d271b3a52263330348b71948bd25cda455a49f7e7d69cfc73e6b2f3b5b41a4c" 
  }
} 
{
  "success": true ,
  "data": {
      "Architecture": "x86_64",
      "SystemTime": "2018-05-23T19:26:54.357768797+09:00" 
 }
}

Accessing Remote Docker Server

For remote access, you sould first bind Docker Server to a port. You can bind by adding -H tcp://0.0.0.0:<port> in service daemon.

# cat /lib/systemd/system/docker.service
....
[Service]
Type=notify
ExecStart=/usr/bin/docker daemon -H fd:// -H tcp://0.0.0.0:4000
....
#include "docker.h"
int main(){
    Docker client = Docker("http://<ip>:<port>");

    JSON_DOCUMENT doc = client.list_containers(true); 
    std::cout << jsonToString(doc) << std::endl;

    return 0;
}

API List

High-Level Container Execution

  • run_container_async - Create and start container, returns container ID
  • attach_log_stream - Attach callbacks to container logs (stdout/stderr)
  • detach_log_stream - Detach log callbacks from container

Low-Level Docker Engine API

System

  • system_info
  • docker_version

Image

  • list_images

Containers

  • list_containers
  • inspect_container
  • top_container
  • logs_container
  • create_container
  • start_container
  • get_container_changes
  • stop_container
  • kill_container
  • pause_container
  • wait_container
  • delete_container
  • unpause_container
  • restart_container
  • attach_to_container

Design Philosophy

This library provides both low-level and high-level APIs:

  • Low-level API: Direct mapping to Docker Engine REST API for full control
  • High-level API: Convenient methods for common container execution patterns
  • Composable: Mix and match both APIs as needed
  • Separated concerns: Container lifecycle separate from log streaming
  • Docker-native: Follows Docker's design patterns and workflows

About

C++ Docker Client Using HTTP API

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages

  • C++ 84.3%
  • CMake 15.7%