V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
chuanqirenwu
V2EX  ›  Python

使用 Docker 部署 Django 应用的最佳实践是什么?

  •  
  •   chuanqirenwu · 2017-06-16 22:09:38 +08:00 · 11684 次点击
    这是一个创建于 2715 天前的主题,其中的信息可能已经有所发展或是发生改变。
    我目前的做法是,构建一个容器运行 django,一个容器运行 nginx,把代码所在文件夹挂载到容器里,但是在这种情况下服务器还是需要安装 python 和 django,感觉和用虚拟环境部署没有区别。

    我希望大家的效果是服务器只需要安装 Docker 就行了,然后通过镜像就可以运行整个 django 应用,该怎么做?
    18 条回复    2017-06-17 12:29:25 +08:00
    dalei
        1
    dalei  
       2017-06-16 22:22:26 +08:00 via Android
    你为啥还需要装 python 和 Django?不是都打包进镜像了吗
    billlee
        2
    billlee  
       2017-06-16 22:28:24 +08:00
    首先,大部分发行版都是自带 python 的,你不能不装 python, 否则系统基本服务都跑不起来
    其次,并不需要在 docker 外面装 django
    另外,最好把代码也打包到镜像里
    chuanqirenwu
        3
    chuanqirenwu  
    OP
       2017-06-16 22:41:04 +08:00
    @dalei 是这样的,我是把源代码文件夹通过 volumes 挂载到容器里,那么在此之前,需要运行 manage.py 的一些命令,如迁移数据库,收集静态文件。那么运行这些命令前又要配置一个完整的 django 环境。而如果将这些动作放到容器里执行的话,我又遇到两个问题:

    如何将容器中的数据库挂载到本机?这样保证容器万一挂了数据还在。

    由于 django 和 nginx 运行在不同容器,如何让 nginx 容器访问到 django 的容器已获得静态文件?当然思路肯定是 volumes,但是几天来查了很多文档还是不知道该如何设置。
    chuanqirenwu
        4
    chuanqirenwu  
    OP
       2017-06-16 22:43:45 +08:00
    @billlee 两个问题该如何解决:

    如何将容器中的数据库挂载到本机?这样保证容器万一挂了数据还在。

    由于 django 和 nginx 运行在不同容器,如何让 nginx 容器访问到 django 的容器已获得静态文件?当然思路肯定是 volumes,但是几天来查了很多文档还是不知道该如何设置。
    guyskk
        5
    guyskk  
       2017-06-16 22:54:29 +08:00 via Android
    docker exec 进容器里执行命令,容器间通过 docker network 通信。用 docker-compose 更方便一些,它会自动配置网络。
    yangxuan8282
        6
    yangxuan8282  
       2017-06-16 23:30:27 +08:00
    你可以贴一下你的 Dockerfile

    一般的 volume 挂载,如果本机上没有这些文件,而容器里有的话,可以给 Dockerfile 里加个 `docker-entrypoint.sh` 当 ENTRYPOINT,用脚本先判断一下文件是否存在,不存在的话就复制过来,具体例子可以看下 library 里官方怎么做的

    至于第二个问题,不同容器间的文件的访问,可以在 docker compose 里指定一个 top-level volumes
    ohhe
        7
    ohhe  
       2017-06-16 23:33:55 +08:00
    1、数据库的 data 目录是 volume 挂载的,不怕容器挂啊。
    2、收集静态文件可以容器内执行。也可以本地开发机执行后,git 更新,这样更好,一般是。
    3、数据库迁移可以本地测试通过后,fabric 自动执行。
    chuanqirenwu
        8
    chuanqirenwu  
    OP
       2017-06-16 23:43:55 +08:00
    @ohhe 如果在本地服务器上执行就需要在搭建一套完整的 django 环境,我希望的是能在容器中执行。
    ohhe
        9
    ohhe  
       2017-06-17 00:20:32 +08:00
    @chuanqirenwu 你说的开发机?不是服务器?
    开发还是 virtualenv 好使。部署用 docker。
    ohhe
        10
    ohhe  
       2017-06-17 00:33:57 +08:00
    感觉楼主对 docker 不是很理解。可别在生产上随便用。
    docker 不是虚拟机,设置错误会丢数据的。
    楼主意思应该是:
    docker 1 web(django) : link:db,volume :project
    docker 2 nginx : 反代 web,volume:project_static volume :nginx_config
    docker 3 db volume :data
    django 的一些命令可以通过 docker1 手动执行或启动时自动执行
    darrenfang
        11
    darrenfang  
       2017-06-17 07:34:16 +08:00 via iPhone
    你需要 docker-compose
    franky_xhl
        12
    franky_xhl  
       2017-06-17 09:04:43 +08:00
    可以参考 https://github.com/pydanny/cookiecutter-django 里的 docker 配法
    maikcn
        13
    maikcn  
       2017-06-17 09:31:33 +08:00
    我是 nginx 和 django 放在一个容器里

    # docker run -p 80:80 -p 8000:8000 .........
    # docker exec -it {your container} bash
    # python manange.py runserver 0.0.0.0:8000

    这样就用 80 端口和 8000 端口区分开 nginx 和 django dev server 的访问路径了
    除此以外,就是 Volume 的配置,和 db container link 的配置而已,这些官方文档都有
    chuanqirenwu
        14
    chuanqirenwu  
    OP
       2017-06-17 10:04:01 +08:00
    @franky_xhl 我就是按照这个库配的,按他的配法遇到的问题就是 nginx 没法反代静态文件
    dylanninin
        15
    dylanninin  
       2017-06-17 10:51:19 +08:00
    10 楼已经一针见血指出问题,楼主对 docker 理解不足,所以暂时不用急着用 docker,建议:
    - 先搞清楚在不用 docker 的情况下如何该部署,架构如何,并自动化,这是后续步骤的前提
    - 如果真心想用 docker,先花一些时间进行系统化的学习,看看官方文档、跟着实践等等
    - 在项目中,可以先从 demo 环境开始使用 docker,相信你会遇到一些问题,尝试解决之
    - 对于 production,不要急着用,除非你已经足够自信
    chuanqirenwu
        16
    chuanqirenwu  
    OP
       2017-06-17 11:12:31 +08:00
    @dylanninin 谢谢指出!我确实是刚学 Docker 不久,昨晚根据大家的回答我重新看了一遍 Docker 的 volumes 文档,目前问题基本解决了。虽然不确定是不是好的解决方案。目前 docker-compose.yml 是这样的:

    version: '2'

    services:
    django:
    build:
    context: .
    dockerfile: ./compose/django/Dockerfile
    command: /gunicorn.sh
    volumes:
    - static-file:/app/static
    - sqlite3-db:/app/database

    nginx:
    build: ./compose/nginx
    depends_on:
    - django
    volumes:
    - static-file:/home/app/static
    ports:
    - "0.0.0.0:80:80"

    volumes:
    static-file: {}
    sqlite3-db: {}

    我把静态文件和数据库文件均放到一个数据卷容器里,让 django 和 nginx 共享,这样 nginx 可以代理静态文件了,从新构建容器启动容器数据库也还在了。不知道这样的解决方案是否合理?
    dylanninin
        17
    dylanninin  
       2017-06-17 12:15:29 +08:00   ❤️ 1
    @chuanqirenwu 赞,楼主学习动手能力不错。

    看你的 yml,可以改进的地方:
    - nginx 可以直接使用 docker 上已有的 image,不需要自己 build ;配置文件以 volume 的方式挂在即可
    - 可以试着把 docker-compose 中写死的变量 ENV 化

    12 楼给出了一个参考的链接,很不错,建议楼主也看看。
    chuanqirenwu
        18
    chuanqirenwu  
    OP
       2017-06-17 12:29:25 +08:00
    @dylanninin 嗯,谢谢,我就是参考这个项目做得。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5288 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 29ms · UTC 08:13 · PVG 16:13 · LAX 00:13 · JFK 03:13
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.