首页 > 解决方案 > 使用 cron 在 Apline 容器中运行 python aws 上传脚本

问题描述

我制作了一个将文件上传到 s3 存储桶的 python 脚本。我需要脚本从 docker 容器中定期运行。

#!/usr/local/bin/python3

import boto3
from botocore.errorfactory import ClientError
import os
import glob
import json
import time

s3_client = boto3.client('s3')
s3_bucket_name = 'ap-rewenables-feature-data'

uploaded = None
max_mod_time = '0'
file_list = glob.glob('/data/*.json')
file_mod_time = None

# get mod time for all file in data directory
file_info = [{'file': file, 'mod_time': time.strftime(
    '%Y-%m-%d %H:%M:%S', time.gmtime(os.path.getmtime(file)))} for file in file_list]

timestamp_sorted_file_info = sorted(file_info, key = lambda f: f['mod_time'])

if os.path.exists('max_mod_time.json'):
    with open('max_mod_time.json', 'r') as mtime:
        max_mod_time = json.load(mtime)['max_mod_time']

# TODO: fix strange behavior in Docker Container
# upload the files tp s3
for file in timestamp_sorted_file_info:
    file_mod_time = file['mod_time']
    # file_mod_time = '2020-09-19 13:28:53' # for debugging
    file_name = os.path.basename(file['file'])
    uploaded = False

    if file_mod_time > max_mod_time:
        with open(os.path.join('/data/', file_name), "rb") as f:
            s3_client.upload_fileobj(f, s3_bucket_name, file_name)

            # error check - https://stackoverflow.com/a/38376288/7582937
            try:
                s3_client.head_object(Bucket=s3_bucket_name, Key=file_name)
            except ClientError as error:
                # Not found
                if error.response['ResponseMetadata']['HTTPStatusCode'] == 404:
                    raise error

    uploaded = True

# save max mod time to file
# https://stackoverflow.com/a/5320889/7582937
object_to_write = json.dumps(
    {"max_mod_time": file_mod_time})

if uploaded:
    if object_to_write:
        open('max_mod_time.json', 'w').write(str(object_to_write))

crond3.7-alpinepython 容器中使用。我Dockerfile的如下:

FROM python:3.7-alpine

WORKDIR /scripts

RUN pip install boto3

ENV AWS_ACCESS_KEY_ID=############
ENV AWS_SECRET_ACCESS_KEY=###################

COPY s3-file-upload-crontab /etc/crontabs/root
RUN chmod 644 /etc/crontabs/root

COPY s3_upload.py /scripts/s3_upload.py
RUN chmod a+x /scripts/s3_upload.py

ENTRYPOINT crond -f

该脚本假设定期运行并将任何新文件上传到 s3 存储桶中,下面是我的 crontab 文件。

5-10/1 * * * * /bin/pwd; /scripts/s3_upload

我正在使用docker-compose.yml构建容器并将主机目录同步到容器中的目录。

version: '3.8'
services:
  s3-data-transfer:
    image: ap-aws-s3-file-upload 
    build:
      context: ./s3-data-upload/
    volumes:
      - ./data/features:/data

运行后docker-compose builddocker-compose up我得到的输出是这样的:

Creating highspeed_s3-data-transfer_1 ... done
Attaching to highspeed_s3-data-transfer_1

它只是挂在那里,我通过附加到容器、创建文件和运行上传脚本来手动测试脚本。它在手动运行时可以正常工作。

配置/设置似乎有问题crond,我没有看到任何可能导致问题的东西。

我怎样才能解决这个问题?欢迎任何建议。

谢谢你。

标签: pythondockeramazon-s3cronalpine

解决方案


过了一会儿,我能够通过在crobtab中正确设置我的时间来解决问题:

4/10 * * * * /bin/pwd; /scripts/s3_upload

推荐阅读