Flutter Docker管理插件docker_commander的使用

发布于 1周前 作者 nodeper 来自 Flutter

Flutter Docker管理插件docker_commander的使用

docker_commander 是一个用于轻松自动化Docker Daemon或Docker Swarm的Docker管理工具,支持本地和远程管理,并提供了许多实用的功能和内置容器。

安装与运行

拉取Docker镜像

首先需要拉取 docker_commander 的Docker镜像:

docker pull gmpassos/docker_commander

服务器模式 (SERVER MODE)

在服务器模式下运行 docker_commander 镜像,映射端口 8099 和 Docker Host Daemon 套接字文件 (/var/run/docker.sock):

docker run --name docker_commander_server -d -t --rm -v /var/run/docker.sock:/var/run/docker.sock -p 8099:8099 gmpassos/docker_commander --server userx pass123

你需要提供用户名和密码(上面的 userxpass123),以便控制对这个 docker_commander 服务器的访问。如果需要限制地址访问,可以传递参数 --private

查看服务器输出:

docker logs docker_commander_server -f

控制台模式 (CONSOLE MODE)

在控制台模式下运行 docker_commander 镜像,传递 --console 参数:

docker run -it --rm gmpassos/docker_commander --console userx your.server.host 8099

控制台示例:

<CONSOLE MODE>
ARGS: [--console, userx, your.server.host, 8099]

[docker_commander server: your.server.host:8099]
Please, provide the password for user 'userx':
password> pass123
------------------------------------------------------------------------------
DockerCommanderConsole{dockerCommander: DockerCommander{dockerHost: DockerHostRemote{serverHost: your.server.host, serverPort: 8099, secure: false, username: userx}, initialized: false. lastDaemonCheck: null}}
Initializing...
Initialization: true
------------------------------------------------------------------------------

$> ps
------------------------------------------------------------------------------
>> CONTAINER ID   IMAGE                       COMMAND                  CREATED             STATUS             PORTS                    NAMES
>> 0f229773e36f   gmpassos/docker_commander   "/usr/bin/dart run b…"   About an hour ago   Up About an hour   0.0.0.0:8099->8099/tcp   docker_commander_server
------------------------------------------------------------------------------
EXIT_CODE: 0

$> help
...

使用公式 (Formulas)

公式是一种非常简单的方式来安装、卸载和处理容器和服务。以下是一个简单的Dart代码示例,展示如何从标准存储库 (DockerCommanderFormulaRepositoryStandard) 使用公式。

import 'package:docker_commander/docker_commander_vm.dart';

void main() async {
  // 创建一个用于本地主机机器的 `DockerCommander`:
  var dockerCommander = DockerCommander(DockerHostLocal());
  
  // 初始化 `DockerCommander`:
  await dockerCommander.initialize();
  
  // 要使用的公式存储库:
  var repository = DockerCommanderFormulaRepositoryStandard();

  // 获取 `apache` 公式的源:
  var formulaSource = await repository.getFormulaSource('apache');

  // 获取公式实例并进行设置:
  var formula = formulaSource!.toFormula();
  
  formula.setup(dockerCommander: dockerCommander);

  // 安装公式:
  var installed = await formula.install();

  // ...

  // 停止公式:
  var stopped = await formula.stop();

  // ...
  
  // 启动公式:
  var start = await formula.start();

  // ...
  
  // 卸载公式:
  var uninstalled = await formula.uninstall();
  
}

在控制台中使用公式

列出可用公式:

$> list-formulas

------------------------------------------------------------------------------
FORMULAS:

  apache gitlab

------------------------------------------------------------------------------

显示公式信息:

$> show-formula gitlab
------------------------------------------------------------------------------
FORMULA: gitlab

CLASS NAME: GitLabFormula

FIELDS:

  - imageGitlab: gitlab/gitlab-ce
  - imageGitlabRunner: gitlab/gitlab-runner
  - imageRunner: google/dart
  - network: gitlab-net
  - hostGitlabConfigPath: /srv/gitlab-runner/config

FUNCTIONS:

  - getVersion
  - pull
  - pullRunner
  - install
  - installRunner
  - registerRunner
  - start
  - stop
  - startRunner
  - stopRunner
  - uninstall
  - uninstallRunner

------------------------------------------------------------------------------

使用公式示例:

## 拉取镜像:
$> formula-exec gitlab pull
$> formula-exec gitlab pullRunner

## 安装镜像(创建容器并启动):
$> formula-exec gitlab install

## 安装可选的 GitLab Runner,
## 个性化字段 "hostGitlabConfigPath":
$> formula-exec gitlab installRunner --hostGitlabConfigPath /host/path/to/gitlab-config-dir/

## 注册 GitLab Runner,
## 传递主机和令牌以及个性化的字段 "hostGitlabConfigPath":
$> formula-exec gitlab registerRunner 172.30.0.2 zysByxVr9tss18BvLFxj --hostGitlabConfigPath /host/path/to/gitlab-config-dir/

## GitLab Runner注册后启动。
$> formula-exec gitlab startRunner

停止和卸载公式:

$> formula-exec gitlab stop

$> formula-exec gitlab uninstall

Dart 示例

本地Docker

以下是一个简单的本地主机机器Dart使用示例:

import 'package:docker_commander/docker_commander_vm.dart';

void main() async {
  // 创建一个用于本地主机机器的 `DockerCommander`:
  var dockerCommander = DockerCommander(DockerHostLocal());
  
  // 初始化 `DockerCommander`:
  await dockerCommander.initialize();
  // 确保Docker守护进程正在运行。
  await dockerCommander.checkDaemon();

  // 运行Docker镜像 `hello-world`:
  var dockerContainer = await dockerCommander.run('hello-world');

  // 等待容器退出,并获取退出码:
  var exitCode = await dockerContainer.waitExit();
  
  // 获取所有STDOUT作为[String]。
  var output = dockerContainer.stdout.asString;
  
  print(output);
  print('EXIT CODE: $exitCode');
}

远程Docker

以下是另一个用于远程主机机器的使用示例:

服务器端

启动 DockerHostServer

import 'package:docker_commander/docker_commander_vm.dart';

void main() async {
  
  // 一个简单的用户名和密码表:
  var authenticationTable = AuthenticationTable({'admin': '123'});

  // 一个在端口8099上的 `DockerHost` 服务器:
  var hostServer = DockerHostServer(
          (user, pass) async => authenticationTable.checkPassword(user, pass),
      8099);

  // 启动服务器并等待初始化:
  await hostServer.startAndWait();
  
}

客户端

客户端使用 DockerHostRemote。请注意,下面的代码可以在任何平台上运行,如JS(在Web浏览器中)或任何Flutter平台(Android、iOS、Web、Linux、macOS、Windows):

import 'package:docker_commander/docker_commander.dart';

void main() async {

  // 连接到运行在 '10.0.0.52:8099' 的 `DockerHost`:
  var dockerHostRemote = DockerHostRemote('10.0.0.52', 8099, username: 'admin', password: '123');

  // 创建一个用于远程主机机器的 `DockerCommander`:
  var dockerCommander = DockerCommander(dockerHostRemote);
  
  // 初始化 `DockerCommander`(在远程服务器上):
  await dockerCommander.initialize();
  // 确保Docker守护进程正在运行(在远程服务器上):
  await dockerCommander.checkDaemon();

  // 运行Docker镜像 `hello-world`(在远程服务器上):
  var dockerContainer = await dockerCommander.run('hello-world');

  // 行为与使用 `DockerHostLocal` 的示例相同。
  // 内部 `DockerRunner` 将自动同步远程输出(stdout/sdterr)!

  // ...
  
  // 获取所有STDOUT作为[String]。
  var output = dockerContainer.stdout.asString;
  print(output);
  
  // ...
  
}

PostgreSQL容器示例

预配置的PostgreSQL容器示例:

import 'package:docker_commander/docker_commander_vm.dart';

void main() async {

  // 创建一个用于本地主机机器的 `DockerCommander`:
  var dockerCommander = DockerCommander(DockerHostLocal());
  // 初始化 `DockerCommander`:
  await dockerCommander.initialize();
  
  // 启动PostgreSQL容器:
  var dockerContainer = await PostgreSQLContainer().run(dockerCommander);

  // 打印容器的当前STDOUT:
  var output = dockerContainer.stdout.asString;
  print(output);

  // 在容器内执行一个 `psql` 命令:
  var execPsql = await dockerContainer.exec('/usr/bin/psql',
      ['-d','postgres', '-U','postgres', '-c','\\l']);

  // 等待命令执行:
  var execPsqlExitCode = await execPsql.waitExit();

  // 命令输出:
  print( execPsql.stdout.asString );
  
  // 停止PostgreSQL,超时时间为20秒:
  await dockerContainer.stop(timeout: Duration(seconds: 20));

  // 等待PostgreSQL退出并获取退出码:
  var exitCode = await dockerContainer.waitExit();

  // ...

}

Apache HTTPD容器示例

预配置的Apache HTTPD容器示例:

import 'package:docker_commander/docker_commander_vm.dart';
import 'package:mercury_client/mercury_client.dart';

void main() async {
    var dockerCommander = DockerCommander(DockerHostLocal());
    // 初始化 `DockerCommander`:
    await dockerCommander.initialize();
    
    // 映射内部容器端口(httpd在端口80)的主机端口。
    var apachePort = 8081;
    
    var dockerContainer = await ApacheHttpdContainer()
        .run(dockerCommander, hostPorts: [apachePort]);
    
    // 获取HTTPD配置文件:
    var httpdConf = await dockerContainer.execCat('/usr/local/apache2/conf/httpd.conf');

    // 获取Apache HTTPD的主机端口。
    var hostPort = dockerContainer.hostPorts[0];
    // 使用主机端口请求HTTP GET:
    var response = await HttpClient('http://localhost:$hostPort/').get('index.html');
    
    // 响应体
    var content = response.bodyAsString;
    print(content);
    
    // 停止Apache HTTPD:
    await dockerContainer.stop(timeout: Duration(seconds: 5));

}

NGINX容器示例

预配置的NGINX代理服务器容器示例:

import 'package:docker_commander/docker_commander_vm.dart';
import 'package:mercury_client/mercury_client.dart';

void main() async {
  var dockerCommander = DockerCommander(DockerHostLocal());
  // 初始化 `DockerCommander`:
  await dockerCommander.initialize();

  // Docker网络用于Apache HTTPD和NGINX容器:
  var network = await dockerCommander.createNetwork();

  // 启动Apache HTTPD,将端口80映射到4081。
  var apacheContainer = await ApacheHttpdContainer().run(dockerCommander,
      hostPorts: [4081], network: network, hostname: 'apache');

  // 生成一个NGINX配置,将域 `localhost` 映射到
  // Docker主机 `apache` 的端口80(不使用HTTPS)。
  var nginxConfig = NginxReverseProxyConfigurer(
      [NginxServerConfig('localhost', 'apache', 80, false)]).build();

  // 使用生成的配置启动一个NGINX容器。
  var nginxContainer = await NginxContainer(nginxConfig, hostPorts: [4082])
      .run(dockerCommander, network: network, hostname: 'nginx');

  // 通过localhost:4082上的NGINX反向代理请求apache:80(在主机机器上映射到localhost:4081)
  var response = await HttpClient('http://localhost:4082/').get('');

  // Apache HTTPD响应内容:
  var apacheContent = response.bodyAsString;

  print(apacheContent);

  // 停止NGINX:
  await nginxContainer.stop(timeout: Duration(seconds: 5));

  // 停止Apache HTTPD:
  await apacheContainer.stop(timeout: Duration(seconds: 5));

  // 删除Docker网络:
  await dockerCommander.removeNetwork(network);
}

更多详细信息请参考官方文档和示例代码:Docker Commander Example


更多关于Flutter Docker管理插件docker_commander的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter Docker管理插件docker_commander的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是如何在Flutter项目中使用docker_commander插件来管理Docker容器的相关代码示例。docker_commander是一个Flutter插件,允许你通过Flutter应用与Docker引擎进行交互。

首先,确保你已经在你的Flutter项目中添加了docker_commander依赖。在你的pubspec.yaml文件中添加以下依赖:

dependencies:
  flutter:
    sdk: flutter
  docker_commander: ^最新版本号  # 请替换为实际的最新版本号

然后运行flutter pub get来安装依赖。

接下来,你需要在你的Flutter应用中初始化并使用docker_commander。以下是一个简单的示例,展示了如何列出所有Docker容器、启动一个新的容器以及停止一个容器。

import 'package:flutter/material.dart';
import 'package:docker_commander/docker_commander.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  DockerCommander? _dockerCommander;
  List<ContainerInfo>? _containers;

  @override
  void initState() {
    super.initState();
    _initializeDockerCommander();
  }

  Future<void> _initializeDockerCommander() async {
    _dockerCommander = DockerCommander();

    // 获取所有容器信息
    _containers = await _dockerCommander!.listContainers();

    if (mounted) {
      setState(() {});
    }
  }

  Future<void> _startContainer(String image) async {
    try {
      await _dockerCommander!.startContainer(image: image, name: "test_container");
      _containers = await _dockerCommander!.listContainers();

      if (mounted) {
        setState(() {});
      }
    } catch (e) {
      print("Error starting container: $e");
    }
  }

  Future<void> _stopContainer(String containerId) async {
    try {
      await _dockerCommander!.stopContainer(containerId: containerId);
      _containers = await _dockerCommander!.listContainers();

      if (mounted) {
        setState(() {});
      }
    } catch (e) {
      print("Error stopping container: $e");
    }
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Docker Commander Demo'),
        ),
        body: Padding(
          padding: const EdgeInsets.all(16.0),
          child: _containers == null
              ? Center(child: CircularProgressIndicator())
              : Column(
                  children: <Widget>[
                    Text('All Containers:'),
                    SizedBox(height: 16.0),
                    Expanded(
                      child: ListView.builder(
                        itemCount: _containers!.length,
                        itemBuilder: (context, index) {
                          final container = _containers![index];
                          return Card(
                            child: ListTile(
                              title: Text(container.names.first ?? 'No Name'),
                              subtitle: Text(container.state),
                              trailing: Row(
                                mainAxisSize: MainAxisSize.min,
                                children: <Widget>[
                                  IconButton(
                                    icon: Icon(Icons.stop),
                                    onPressed: () => _stopContainer(container.id),
                                  ),
                                ],
                              ),
                            ),
                          );
                        },
                      ),
                    ),
                    SizedBox(height: 16.0),
                    ElevatedButton(
                      onPressed: () => _startContainer('nginx'),
                      child: Text('Start Nginx Container'),
                    ),
                  ],
                ),
        ),
      ),
    );
  }
}

在这个示例中,我们做了以下几件事:

  1. 初始化DockerCommander:在initState方法中初始化DockerCommander实例,并获取所有容器信息。
  2. 显示容器列表:在UI中显示所有容器的名称和状态,并提供一个停止按钮。
  3. 启动新容器:提供一个按钮,当点击时,启动一个新的Nginx容器。
  4. 停止容器:点击停止按钮时,停止指定的容器。

请注意,这个示例假设Docker守护进程正在运行,并且Flutter应用有足够的权限来访问Docker API。你可能需要在Docker设置中配置API访问权限,或者以管理员身份运行你的Flutter应用。

此外,docker_commander插件的具体API可能会随着版本更新而有所变化,因此请参考最新的官方文档以获取最新的使用方法和API信息。

回到顶部