【问题标题】:Docker Compose - adding volume using Amazon S3Docker Compose - 使用 Amazon S3 添加卷
【发布时间】:2016-07-24 06:43:07
【问题描述】:

我正在使用 docker-compose v2 来构建我的容器(Django 和 Nginx)。

我想知道如何存储静态和媒体文件。一开始我将它们作为卷存储在机器上,但是机器崩溃了,我丢失了数据(或者至少,我不知道如何恢复它)。 我认为最好将其存储在 Amazon S3 上,但没有相关指南(也许这意味着什么 :))。

这是我的 docker-compose 文件: 我尝试添加所需的字段(名称、密钥、秘密……),但到目前为止没有成功。

这是正确的方法吗? 谢谢!

version: '2'
services:
  web:
    build:
      context: ./web/
      dockerfile: Dockerfile
    expose:
      - "8000"
    volumes:
      - ./web:/code
      - static-data:/www/static
      - media-data:/www/media
    env_file: devEnv

  nginx:
    build: ./nginx/
    ports:
      - "80:80"
    volumes:
      - static-data:/www/static
      - media-data:/www/media
    volumes_from:
      - web
    links:
      - web:web


volumes:
  static-data:
    driver: local
  media-data:
    driver: s3

【问题讨论】:

  • 查看 django-storages

标签: django amazon-web-services amazon-s3 docker-compose


【解决方案1】:

这是一个如何从容器上传文件到 S3(用于备份)的示例,但也可以在主机操作系统中进行,因为您在主机操作系统上安装了一个容器卷。 在此脚本中,我将媒体从 S3 下载到本地容器/服务器。之后,我使用pynotify 观察目录static/media,进行修改。如果发生任何更改,则使用命令subprocess.Popen(upload_command.split(" ")) 将文件上传到 S3。 我认为您也可以针对您的问题调整此脚本。 在测试这个脚本之前,你应该在操作系统的环境变量上设置你的AWS_ACCESS_KEY_IDAWS_SECRET_ACCESS_KEY

更多详情S4cmd documentation

#!-*- coding:utf-8 -*-
import pyinotify
import os
import subprocess
from single_process import single_process

# You most have set AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY
# in enviromnet variables

PROJECT_DIR = os.getcwd()
MEDIA_DIR = os.path.join(PROJECT_DIR, "static/media")

AWS_BUCKET_NAME = os.environ.get("AWS_BUCKET_NAME", '')

S4CMD_DOWNLOAD_MEDIA = "s4cmd get --sync-check --recursive s3://%s/static/media/ static/" % (AWS_BUCKET_NAME)
UPLOAD_FILE_TO_S3="s4cmd sync --sync-check %(absolute_file_dir)s s3://"+ AWS_BUCKET_NAME +"/%(relative_file_dir)s"

# Download all media from S3
subprocess.Popen(S4CMD_DOWNLOAD_MEDIA.split(" ")).wait()

class ModificationsHandler(pyinotify.ProcessEvent):
    def process_IN_CLOSE_WRITE(self, event):
        try:
            dir = event.path
            file_name = event.name

            absolute_file_dir=os.path.join(dir, file_name)
            relative_dir=dir.replace(PROJECT_DIR, "")
            relative_file_dir=os.path.join(relative_dir, file_name)

            if relative_file_dir.startswith("/"):
                relative_file_dir = relative_file_dir[1:]

            print("\nSeding file %s to S3" % absolute_file_dir)

            param = {}
            param.update(absolute_file_dir=absolute_file_dir)
            param.update(relative_file_dir=relative_file_dir)         

            upload_command = UPLOAD_FILE_TO_S3 % param
            print(upload_command)
            subprocess.Popen(upload_command.split(" "))
        except Exception as e:
            # log excptions
            print("Some problem:", e.message)

@single_process
def main():
    handler = ModificationsHandler()
    wm = pyinotify.WatchManager()
    notifier = pyinotify.Notifier(wm, handler)
    print("\nListening changes in: " + MEDIA_DIR)
    if MEDIA_DIR:
        wdd = wm.add_watch(MEDIA_DIR, pyinotify.IN_CLOSE_WRITE, auto_add=True, rec=True)
        notifier.loop()

if __name__ == "__main__":
    main()  

【讨论】:

  • 你只是把文件备份到s3,对吧?为什么它比使用 S3 本身来提供文件更好?谢谢!
  • 不,我不仅备份,还将文件从 S3 提供给客户端。我必须将文件保存在磁盘上,因为mezzanine 框架不能很好地工作。我最初的问题是 mezzanine 与 S3 的集成,然后这就是解决方案。
  • 我想将 s3 存储桶定义为 docker 中的卷,因此它对 django 是透明的,文件实际保存在哪里。
  • 以一种或另一种方式,文件应该与 S3 同步。这是一种可能的方式。但是,它对 Django 是透明的。我以工人身份启动此脚本。 Django只上传static/media目录的媒体,然后脚本自动上传文件到S3。
  • 我最终将文件直接上传到 S3 而不使用 django-storages 进行备份,并使用 CDN 处理用户请求
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-01-31
  • 2021-08-19
  • 1970-01-01
  • 1970-01-01
  • 2021-01-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多