从Docker容器将CSV文件写入本地主机

6
我正在尝试建立一个非常基本的数据处理项目,其中我使用docker在EC2上创建Ubuntu环境,安装Python,获取输入的CSV文件,执行一些简单的数据操作,然后将结果输出到输入文件所在的文件夹中的一个新的CSV文件中。我已经成功地在本地运行了Python代码,也在EC2上运行过,但当我在docker容器中运行它时,数据似乎被处理了(我的脚本打印出了数据),但结果不会保存在运行结束时。是否有我在Dockerfile中缺失的命令导致结果无法保存?或者,是否有一种方式可以直接将输出保存到S3存储桶中?
编辑:输入文件的路径为”/home/ec2-user/docker_test/data”,代码的路径为”/home/ec2-user/docker_test/code”。处理数据之后,我想要将结果作为一个新文件写入主机上”/home/ec2-user/docker_test/data”目录中。
Dockerfile:
FROM ubuntu:latest

RUN apt-get update \
    && apt-get install -y --no-install-recommends software-properties-common \
    && add-apt-repository -y ppa:deadsnakes/ppa \
    && apt-get update \
    && apt-get install -q -y --no-install-recommends python3.6 python3.6-dev python3-pip python3-setuptools \
    && apt-get clean \
    && rm -rf /var/lib/apt/lists/*

VOLUME /home/ec2-user/docker_test/data
VOLUME /home/ec2-user/docker_test/code

WORKDIR /home/ec2-user/docker_test/

COPY requirements.txt ./

RUN cat requirements.txt | xargs -n 1 -L 1 python3.6 -m pip install --no-cache-dir

COPY . .

ENV LC_ALL C.UTF-8
ENV LANG=C.UTF-8

CMD python3.6 main.py

Python脚本:

import pandas as pd
import os
from code import processing

path = os.getcwd()

def main():
    df = pd.read_csv(path + '/data/table.csv')
    print('input df: \n{}'.format(df))
    df_out = processing.processing(df)
    df_out.to_csv(path + '/data/updated_table.csv', index = False)
    print('\noutput df: \n{}'.format(df_out))


if __name__ == '__main__':
    main()

编辑: 我一直在使用“docker run docker_test”运行dockerfile。


请问您能否包括您的 docker run 命令? - bluescores
我一直在使用"docker run docker_test"。 - Sky Blue
你期望处理后的输出csv文件出现在哪里?在主机上?容器内部?无论哪种情况,它的文件路径是什么? - bluescores
输入文件的路径为“/home/ec2-user/docker_test/data”,代码的路径为“/home/ec2-user/docker_test/code”。数据处理完成后,我希望将结果作为新文件写入主机上“/home/ec2-user/docker_test/data”目录中。 - Sky Blue
你希望通过在Docker中运行它,相比于创建一个已安装有先决条件的AMI或使用像Ansible这样的自动化工具来配置EC2主机,获得什么? - David Maze
我最终希望使用Docker和AWS ECS来运行数据处理作业,但我想先从一个简单的例子开始学习Docker。 - Sky Blue
2个回答

1

好的,我明白了,在关于 CSV 输出到 主机 的期望方面进行编辑后,我们在设置方面确实存在问题。

您在 Dockerfile 中声明了两个 VOLUME,这很好。这些是 命名卷,对于在单个主机上启动和关闭容器时持久化数据非常有用,但您无法轻松地像访问普通文件系统一样从主机访问它们。

如果您希望文件显示在主机上,可以在运行时创建一个 绑定挂载卷,将主机文件系统中的路径映射到 Docker 容器文件系统中的路径。

docker run -v $(pwd):/home/ec2-user/docker_test/data docker_test 将执行此操作。$(pwd) 是一个表达式,如果您正在运行该命令的 *nix 系统上,则会计算为当前工作目录。请注意并根据需要进行调整(例如,如果您的主机使用 Windows)。

通过这种方式设置卷后,当在容器文件系统中创建 CSV 位于您打算的位置时,它将在相对于您映射的位置的主机上可访问。

阅读有关容量的内容。它们对于使用Docker非常重要,一开始不难理解,但在细节方面有一些需要注意的地方。


关于上传到S3,我建议使用boto3库,并在您的Python脚本中完成。如果您觉得更简单,也可以使用类似s3cmd的工具。


非常感谢您详细的回复!这对我非常有帮助,我一定会开始阅读关于卷的内容。然而,当我尝试运行新的docker run命令时,脚本似乎仍然可以正确运行,但是在“/home/ec2-user/docker_test/data”目录中仍未创建输出文件。也许Dockerfile有问题吗?顺便说一下,我在EC2上使用的是Ubuntu AMI。 - Sky Blue
编辑:没关系,我需要刷新我的SFTP浏览器,文件确实已经正确创建了。谢谢! - Sky Blue
1
另外还有两个相关的提示:Docker容器和主机中的文件路径不需要匹配,我可能会在容器内使用类似于/data的东西;而且你不需要一个VOLUME声明来使用docker run -v,鉴于它的微妙副作用,我建议不要在Dockerfile中包含它。 - David Maze

0

你可以在你的docker容器中使用S3FS Fuse将S3桶挂载为驱动器。这基本上创建了一个文件夹,实际上是S3桶。您在该文件夹中保存/修改的任何内容都会反映在S3桶中。

如果删除docker容器或卸载驱动器,您仍然拥有完整的S3桶,因此您不需要过分担心通过正常docker使用删除S3桶中的文件。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接