从C#.Net 4.7运行docker-compose命令

时间:2018-08-12 00:47:47

标签: c# .net runspace

我希望从C#运行命令到通过docker-compose设置的容器。在Powershell中,我运行以下命令并创建文件:

docker-compose exec database sh -c "mysqldump -u((username)) -p((password)) ((databasename)) > /backups/test.sql"

运行以下代码时,即使设置了环境变量,它似乎也会忽略环境变量。它仅创建一个名为backup.sql的文件,并且输出到该文件的SQL表示未选择数据库。我已经验证了通过将最后一个参数字符串输出到控制台来设置环境变量。

var exportPath = $"/backups/backup.sql {DateTime.Now}"; 
using (var runspace = RunspaceFactory.CreateRunspace())
{
    runspace.Open();
    runspace.SessionStateProxy.Path.SetLocation(Path.GetFullPath(".."));
    using (var pipeline = runspace.CreatePipeline())
    {

        var cmd = new Command("docker-compose");
        cmd.Parameters.Add("exec");
        cmd.Parameters.Add("database");
        cmd.Parameters.Add($"sh -c \"mysqldump - u{GetEnv("MYSQL_USERNAME")} " +
            $"-p{GetEnv("MYSQL_PASSWORD")} {GetEnv("MYSQL_DATABASE")} > {exportPath} \"");
        pipeline.Commands.Add(cmd);
        pipeline.Invoke();
    }
}

GetEnv只是Environment.GetEnvironmentVariable

的一种便捷方法

我可以肯定我没有正确设置参数,但是我不知道从这里去哪里。

2 个答案:

答案 0 :(得分:2)

我放弃并使用了CliWrap,因为它更易于调试。我不知道如何设置当前目录,但是幸运的是,我可以修改程序的其余部分以在当前目录中查找内容。

var now = DateTime.Now.ToString().Replace("/", "-").Replace(" ", "-");
var exportPath = $"/backups/backup.sql-{now}";

using (var cli = new CliWrap.Cli("docker-compose"))
{
    var cmd = $"exec -T database sh -c \"mysqldump -u{GetEnv("MYSQL_USER")} " +
        $"-p{GetEnv("MYSQL_PASSWORD")} {GetEnv("MYSQL_DATABASE")} > {exportPath}\"";
    Console.WriteLine(cmd);
    var resp = cli.Execute(cmd);
    Console.WriteLine(resp.StandardOutput);
    Console.WriteLine(resp.StandardError);
}

可以在以下位置找到该库:https://github.com/Tyrrrz/CliWrap

答案 1 :(得分:0)

我遇到了FluentDocker,这似乎是从c#运行docker-compose的好方法。

以下是项目页面中的示例:

using (
        var container =
          new Builder().UseContainer()
            .UseImage("kiasaki/alpine-postgres")
            .ExposePort(5432)
            .WithEnvironment("POSTGRES_PASSWORD=mysecretpassword")
            .WaitForPort("5432/tcp", 30000 /*30s*/)
            .Build()
            .Start())
      {
        var config = container.GetConfiguration(true);
        Assert.AreEqual(ServiceRunningState.Running, config.State.ToServiceState());
      }

免责声明:我与该项目没有任何关系,也尚未尝试使用它。