0%

搭建基于Dokku的PaaS平台

服务端安装

快速安装

1
2
3
4
5
6
7
# for debian systems, installs dokku via apt-get

~$ wget https://raw.githubusercontent.com/dokku/dokku/v0.23.8/bootstrap.sh

~$ sudo DOKKU_TAG=v0.23.8 bash bootstrap.sh

# go to your server's IP and follow the web installer

使用ansible安装

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
# 参考位置 http://dokku.viewdocs.io/dokku/getting-started/install/debian/ 改编的文件
- name: 安装Dokku
hosts: DB001
become: yes
# user: root 这里可以直接用root,但是关闭root远程登录后要使用sudo.
tasks:
# 参照文档 https://docs.ansible.com/ansible/latest/modules/apt_module.html
- name: 更新并安装
apt:
name: ['apt-transport-https', 'wget']
allow_unauthenticated: yes
update_cache: yes

- name: 添加公钥
apt_key:
url: https://packagecloud.io/gpg.key
validate_certs: no
state: present

# 参考文档 https://docs.ansible.com/ansible/latest/modules/command_module.html#command-module
- name: 读取系统发行版本号
command: lsb_release -sc
register: result

# https://docs.ansible.com/ansible/latest/modules/stat_module.html?highlight=stat 读取文件的stat
- stat:
path: /etc/apt/sources.list.d/dokku_dokku.list
register: dokku_repo

# https://docs.ansible.com/ansible/latest/user_guide/playbooks_blocks.html
# 把几个任务组合起来,用条件判断.
- block:
# https://docs.ansible.com/ansible/latest/modules/get_url_module.html?highlight=get_url
- name: 下载安装脚本
get_url:
url: https://packagecloud.io/install/repositories/dokku/dokku/script.deb.sh
dest: /tmp/script.deb.sh
validate_certs: no
force: yes
mode: 0755

# https://docs.ansible.com/ansible/latest/modules/script_module.html
# 也可以从这里直接下载deb安装包. https://packagecloud.io/dokku/dokku/
- name: 运行安装Dokku脚本
command: bash /tmp/script.deb.sh
when: dokku_repo.stat.exists is not defined or dokku_repo.stat.size == 0

- name: 安装dokku
apt:
name: ['dokku']
allow_unauthenticated: yes
update_cache: yes

# https://docs.ansible.com/ansible/latest/modules/debconf_module.html
- name: unattended installation of dokku
debconf:
name: dokku
question: dokku/vhost_enable
value: 'true'
vtype: select

- name: 安装Dokku依赖
command: dokku plugin:install-dependencies --core
  • 安装完成后会启动一个http-server提供 web 方式的配置,浏览器输入服务器 ip 打开页面,输入公钥和域名(或者公网 IP)就 OK.

客户端安装

  • dokku-client 这个客户端很久没有更新的了,不支持 python3.

  • 官方客户端,这里基于不同语言有比较全面的客户端介绍.

  • Deploying Django on Dokku

  • 这里使用官方的提供的客户端脚本,如下面所示,运行脚本前,先要确定几个重点,

    • 添加DOKKU_HOST环境变里,或者直接写入$HOME/.dokku/contrib/dokku_client.sh这个脚本里面.
    • 能使用公钥登录目标dokku服务器.
  • dokku服务器端加入一个可信的客户端公钥,操作如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    # 列出本机加入的可信公钥
    ~$ dokku ssh-keys:list
    SHA256:Lr2N48k+1UDb0IxxWm0AhI0fzpdpnEZtalGc+XXXXX NAME="admin1" SSHCOMMAND_ALLOWED_KEYS="no-agent-forwarding,no-user-rc,no-X11-forwarding,no-port-forwarding"
    # 添加一个客户端的公钥
    ~$ sudo dokku ssh-keys:add admin2 /fullpath/id_rsa.pub
    SHA256:diDyzHYBmugZoGkWw1RaqzGkLfdCUpmBOxXFnf/XXXX
    ~$ dokku ssh-keys:list
    SHA256:Lr2N48k+1UDb0IxxWm0AhI0fzpdpnEZtalGc+Pf7Rvo NAME="admin1" SSHCOMMAND_ALLOWED_KEYS="no-agent-forwarding,no-user-rc,no-X11-forwarding,no-port-forwarding"
    SHA256:diDyzHYBmugZoGkWw1RaqzGkLfdCUpmBOxXFnf/XXXX NAME="admin2" SSHCOMMAND_ALLOWED_KEYS="no-agent-forwarding,no-user-rc,no-X11-forwarding,no-port-forwarding"
  • 下载客户端仓库.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    ~$ git clone git@github.com:dokku/dokku.git ~/.dokku

    # optional: make sure that the dokku_client.sh version matches your Dokku version
    ~$ cd ~/.dokku
    ~$ git checkout <tag/branch>

    # add the following to either your
    # .bashrc, .bash_profile, or .profile file
    ~$ alias dokku='$HOME/.dokku/contrib/dokku_client.sh'
  • 正常的客户端运行如下,与heroku的客户端命令极其相似.如果运行dokku无任何输出,你要查看SSH连接信息是否正确,DOKKU_PORT,DOKKU_HOST的的环境变量是否与目标服务器匹配.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    ~$ dokku
    Usage: dokku [--quiet|--trace|--rm-container|--rm|--force] COMMAND <app> [command-specific-options]

    Primary help options, type "dokku COMMAND:help" for more details, or dokku help --all to see all commands.

    Commands:

    apps Manage Dokku apps
    certs Manage Dokku apps SSL (TLS) certs
    checks Manage zero-downtime settings
    config Manages global and app-specific config vars
    docker-options Pass options to Docker the various stages of an app
    domains Manage vhost domains used by the Dokku proxy
    enter Connect to a specific app container
    events Show the last events (-t follows)
    git Manages the git integration for an app
    help Print the list of commands
    logs Output app logs
    network Manages network settings for an app
    nginx Interact with Dokku\'s Nginx proxy
    proxy Manage the proxy used by dokku on a per app
    ps List processes running in app container(s)
    repo Runs commands that interact with the app\'s repo
    run Run a command in a new container using the current application image
    scheduler-docker-local Manages the scheduler-docker-local integration for an app
    shell Spawn dokku shell
    ssh-keys Manage public ssh keys that are allowed to connect to Dokku
    storage Mount local volume / directories inside containers
    tags List all app image tags
    tar Deploy applications via tarball instead of git
    trace Enable dokku tracing
    url Show the first URL for an application (compatibility)
    urls Show all URLs for an application
    version Print dokku\'s version

    ~$ dokku plugin:list
    ! Deprecated: Please use plugin:list
    plugn: 0.3.0
    00_dokku-standard 0.14.1 enabled dokku core standard plugin
    20_events 0.14.1 enabled dokku core events logging plugin
    app-json 0.14.1 enabled dokku core app-json plugin
    apps 0.14.1 enabled dokku core apps plugin
    build-env 0.14.1 enabled dokku core build-env plugin
    certs 0.14.1 enabled dokku core certificate management plugin
    checks 0.14.1 enabled dokku core checks plugin
    common 0.14.1 enabled dokku core common plugin
    config 0.14.1 enabled dokku core config plugin
    docker-options 0.14.1 enabled dokku core docker-options plugin
    domains 0.14.1 enabled dokku core domains plugin
    enter 0.14.1 enabled dokku core enter plugin
    git 0.14.1 enabled dokku core git plugin
    logs 0.14.1 enabled dokku core logs plugin
    network 0.14.1 enabled dokku core network plugin
    nginx-vhosts 0.14.1 enabled dokku core nginx-vhosts plugin
    plugin 0.14.1 enabled dokku core plugin plugin
    proxy 0.14.1 enabled dokku core proxy plugin
    ps 0.14.1 enabled dokku core ps plugin
    repo 0.14.1 enabled dokku core repo plugin
    scheduler-docker-local 0.14.1 enabled dokku core scheduler-docker-local plugin
    shell 0.14.1 enabled dokku core shell plugin
    ssh-keys 0.14.1 enabled dokku core ssh-keys plugin
    storage 0.14.1 enabled dokku core storage plugin
    tags 0.14.1 enabled dokku core tags plugin
    tar 0.14.1 enabled dokku core tar plugin

部署Django工程实例

  • 简化 Django 开发的八个 Python 包

  • Django 使用 Celery 实现异步任务

  • django-allauth 认证模块

  • 下面的环境基于Pyenv+Pipenv.Pyenv: python 版本管理器.Pipenv: python 包管理器,更好用的 pip.

  • pyenv的一些基本操作.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    # pyenv 安装的位置
    ~$ which pyenv
    /home/lcy/.pyenv/bin/pyenv

    # pyenv 可提供的安装版本.
    ~$ pyenv install --list
    Available versions:
    2.1.3
    2.2.3
    2.3.7
    2.4
    2.4.1
    2.4.2
    2.4.3
    2.4.4
    [...]

    # 本机已经安装的版本
    ~$ pyenv versions
    system
    * 3.6.6 (set by /home/lcy/.python-version)
    3.6.6/envs/dokku-py3
    3.6.6/envs/py3dev
    dokku-py3
    py3dev

    # 本机默认使用的版本.
    ~$ pyenv version
    3.6.6 (set by /home/lcy/.python-version)
    # 为这个版本安装pipenv
    ~$ pip install pipenv
    Collecting pipenv
    # 列出当前安装的包.
    ~$ pip list
    Package Version
    ---------------- ----------
    autopep8 1.4
    certifi 2018.11.29
    pip 18.1
    pipenv 2018.11.26
    pycodestyle 2.4.0
    setuptools 39.0.1
    virtualenv 16.2.0
    virtualenv-clone 0.4.0
    yapf 0.23.0
  • 通过上述命令安装了pipenv,下面是它的一些基本操作.官方文档

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    # 创建python3的虚拟环境,也可以用 pipenv --python 3.7 指定具体的版本号.
    ~$ pipenv --three
    Creating a virtualenv for this project…
    Pipfile: /home/lcy/workspace/dokku-test/crm/Pipfile
    Using /home/lcy/.pyenv/versions/3.6.6/bin/python3.6 (3.6.6) to create virtualenv…
    ⠸ Creating virtual environment...Already using interpreter /home/lcy/.pyenv/versions/3.6.6/bin/python3.6
    Using base prefix '/home/lcy/.pyenv/versions/3.6.6'
    New python executable in /home/lcy/.local/share/virtualenvs/crm-GMqHkluo/bin/python3.6
    Also creating executable in /home/lcy/.local/share/virtualenvs/crm-GMqHkluo/bin/python
    Installing setuptools, pip, wheel...
    done.

    ✔ Successfully created virtual environment!
    Virtualenv location: /home/lcy/.local/share/virtualenvs/crm-GMqHkluo
    Creating a Pipfile for this project…
    # 查看环境位置.
    ~$ pipenv --venv
    /home/lcy/.local/share/virtualenvs/crm-GMqHkluo

    ~$ pipenv --py
    /home/lcy/.local/share/virtualenvs/crm-GMqHkluo/bin/python

    # 安装django依赖包.当前工程目录下的Pipfile.lock文件,就等同于传统的requirements.txt文件.
    ~$ pipenv install django django-toolbelt
    Installing django…
    Adding django to Pipfile\'s [packages]…
    ✔ Installation Succeeded
    Installing django-toolbelt…
    Adding django-toolbelt to Pipfile\'s [packages]…
    ✔ Installation Succeeded
    Pipfile.lock not found, creating…
    Locking [dev-packages] dependencies…
    Locking [packages] dependencies…
    ✔ Success!
    Updated Pipfile.lock (c14d8c)!
    Installing dependencies from Pipfile.lock (c14d8c)…
    🐍 ▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉ 8/8 — 00:00:01
    To activate this project\'s virtualenv, run pipenv shell.
    Alternatively, run a command inside the virtualenv with pipenv run.
    # 列出安装包的的依赖.
    ~$ pipenv graph
    django-toolbelt==0.0.1
    - dj-database-url [required: Any, installed: 0.5.0]
    - dj-static [required: Any, installed: 0.0.6]
    - static3 [required: Any, installed: 0.7.0]
    - django [required: Any, installed: 2.1.5]
    - pytz [required: Any, installed: 2018.9]
    - gunicorn [required: Any, installed: 19.9.0]
    - psycopg2 [required: Any, installed: 2.7.6.1]
    # 进入pipenv 虚拟环境shell
    ~$ pipenv shell
    Launching subshell in virtual environment…
    . /home/lcy/.local/share/virtualenvs/cms-uhqZcysp/bin/activate

创建Django的示例项目.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
~$ mkdir dokkutest && cd dokkutest
~$ pipenv --three
Creating a Pipfile for this project…
# 会在本机目录下生成一个Pipfile
~$ cat Pipfile
[[source]]
name = "pypi"
#url = "https://pypi.org/simple"
#使用阿里云源
url = "http://mirrors.aliyun.com/pypi/simple"
verify_ssl = true

# 使用阿里云源必需加这一行.
[install]
trusted-host = mirrors.aliyun.com

[dev-packages]

[packages]

[requires]
python_version = "3.6"
# 安装相应的包.
~$ pipenv install django django-toolbelt
~$ pipenv shell
~$ django-admin.py startproject dokkutest .
~$ echo "web: gunicorn dokkutest.wsgi" > Procfile
~$ echo "venv" > .gitignore
# 新建APP
~$ django-admin.py startapp webui
# 安装APP
~$ sed -i "/django.contrib.staticfiles/ a\ 'webui'," dokkutest/settings.py
# 如果不加这两行,就要设置 dokku config:set DISABLE_COLLECTSTATIC=1,不然会出错,强烈建议加下面一行.
~$ sed -i "/STATIC_URL/ a\STATIC_ROOT = os.path.join(BASE_DIR, 'static')" dokkutest/settings.py
# 本地合并
~$ python manage.py migrate
Operations to perform:
Apply all migrations: admin, auth, contenttypes, sessions
Running migrations:
Applying contenttypes.0001_initial... OK
Applying auth.0001_initial... OK
Applying admin.0001_initial... OK
Applying admin.0002_logentry_remove_auto_add... OK
[....]
# 本的运行测度
$ python manage.py runserver 0.0.0.0:9000
Performing system checks...

System check identified no issues (0 silenced).
January 14, 2019 - 09:03:32
Django version 2.1.5, using settings 'dokkutest.settings'
Starting development server at http://0.0.0.0:9000/
Quit the server with CONTROL-C.
# 收集依赖包的列表,这里会收集当前虚环境的所有包,建议新建工程时新建一个新的虚拟环境,
# 这样可以保证requirements.txt是最小的依赖列表.
~$ pip freeze -l > requirements.txt
# 添加Procfile文件.
~$ echo "web: gunicorn dokkutest.wsgi" > Procfile
# 指定python的版本
~$ echo "python-3.6.7" > runtime.txt
# 加入git版本管理,这里假设我的dokku服务器的<域名>地址是172.16.10.100
~$ git init
~$ git add .
~$ git commit -m 'first commit'
~$ git remote add dokku dokku@172.16.10.100:dokkutest
# push代码后,就触编译与发布.
~$ git push dokku master
Delta compression using up to 6 threads.
Compressing objects: 100% (29/29), done.
Writing objects: 100% (33/33), 8.11 KiB | 0 bytes/s, done.
Total 33 (delta 5), reused 0 (delta 0)
-----> Cleaning up...
-----> Building dokkutest from herokuish...
-----> Adding BUILD_ENV to build environment...
-----> Python app detected
Skipping installation, as Pipfile.lock hasn\'t changed since last deploy.
[....]
DOKKU_APP_RESTORE: 1
=====> Renaming container (b7192f0ff943) dreamy_pascal to dokkutest.web.1
=====> Application deployed:
http://172.16.10.100:51903 # 到此程序的窗口与宿主机的端口映射已经生成了.

To 172.16.10.100:dokkutest
* [new branch] master -> master

~$ dokku apps:list
=====> My Apps
dokkutest
# dokku 服务器里的docker对应的容器运行起来
~$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
b7192f0ff943 dokku/dokkutest:latest "/start web" 23 hours ago Up 23 hours dokkutest.web.1
# 端口映射OK
~$ netstat -tnlp
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN -
tcp 0 0 0.0.0.0:51903 0.0.0.0:* LISTEN -

# 应用在服务器的位置,一些配置文件与变量可以直接进入服务器里的相关app目录下去修改.
~$ tree -L 1 /home/dokku
/home/dokku
├── bazi
├── ENV
├── HOSTNAME
├── phpcms
├── VERSION
└── dokkutest

Dokku其它指南

  • 设置APP域名.如上面所述,app 映射了一个很大端口值http://172.16.10.100:51903,只能通过 IP+端口的方式访问,这有可能不能满足我们的实际应用需求,怎样在同一个IP里使用不同的域名访问不同的应用呢?或者说,同一个服务器里的应用都想通过80端口对外提供服务.这里就要通过nginx代理不同的域名.命令如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
~$ dokku domains:help
Usage: dokku domains[:COMMAND]

Manage vhost domains used by the Dokku proxy.

Additional commands:
domains:add <app> <domain> [<domain> ...] Add domains to app
domains:add-global <domain> [<domain> ...] Add global domain names
domains [<app>] [DEPRECATED] Alternative for domains:report
domains:clear <app> Clear all domains for app
domains:disable <app> Disable VHOST support
domains:enable <app> Enable VHOST support
domains:remove <app> <domain> [<domain> ...] Remove domains from app
domains:remove-global <domain> [<domain> ...] Remove global domain names
domains:report [<app>] [<flag>] Displays a domains report for one or more apps
domains:set <app> <domain> [<domain> ...] Set domains for app
domains:set-global <domain> [<domain> ...] Set global domain names
  • 为 dokkutest  这个应用设置 test.example.com 这个域名,后面就可以通过个域名 80 端就能访问到这个应用了.
1
2
3
4
5
~$ dokku domains:test.example.com  dokkutest
[...]
=====> 734565b29c3d49d4e9ae129b79c8011353300f45380a4b1fdce0df9604c2d31b
=====> Application deployed:
http://test.example.com
  • 访问静态资源.其实上面的部署是一个基本的应用,做一个Restful API服务器是没有问题的.如果做成网页端,它的static下的静态资源是不能访问的.这里要用到一些其它包与设置.具体参照这里 Django and Static Assets.具体解决如下:
1
2
3
4
5
6
7
8
9
# 安装whitenoise
~$ pip install whitenoise
# 下面修改settings.py
MIDDLEWARE_CLASSES = (
# 放在最上层一行.
# https://warehouse.python.org/project/whitenoise/
'whitenoise.middleware.WhiteNoiseMiddleware',
# 添加这一行
STATICFILES_STORAGE = 'whitenoise.storage.CompressedManifestStaticFilesStorage'

Dokku插件应用

letsencrypt

1
2
3
4
# 安装
~$ sudo dokku plugin:install https://github.com/dokku/dokku-letsencrypt.git
# 更新
~$ sudo dokku plugin:update letsencrypt
  • APP安装Lets'Encrypt,这里需要注意,这个app设置了三个域名,其中只有一个是在 DNS 上设置的h5.lcy.wiki,所以才会出现下面的错误.只要把其它两个域名从这个app中删除就可以了.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
~$ dokku letsencrypt h5dev
=====> Let\'s Encrypt h5dev
-----> Updating letsencrypt docker image...
[...]
-----> Enabling ACME proxy for h5dev...
-----> Getting letsencrypt certificate for h5dev...
- Domain 'h5dev.www.lcy.wiki'
- Domain 'h5.lcy.wiki'
- Domain 'h5dev'
[...]
ACME server returned an error: urn:acme:error:malformed ::\n
The request message was malformed :: Error creating new authz :: DNS name does not have enough labels


Debugging tips: -v improves output verbosity. Help is available under --help.
-----> Certificate retrieval failed!
-----> Disabling ACME proxy for h5dev...
done
# 正常应该如下所示

~$ dokku domains:report h5dev
=====> h5dev domains information
Domains app enabled: true
Domains app vhosts: h5.lcy.wiki

~$ dokku letsencrypt:ls
-----> App name Certificate Expiry Time before expiry Time before renewal
h5dev 2019-06-18 18:42:21 89d, 20h, 14m, 52s 59d, 20h, 14m, 52s

# 自动刷新证书
~$ dokku letsencrypt:auto-renew h5dev
h5dev still has 59d, 20h, 12m, 43s days left before renewal

redis插件应用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
~$ sudo dokku plugin:install https://github.com/dokku/dokku-redis.git redis
~$ dokku redis:create dokku-redis
~$ dokku redis:info dokku-redis
=====> Container Information
# 这两行是映射到宿主机的实际目录下面.
Config dir: /var/lib/dokku/services/redis/dokku-redis/config
Data dir: /var/lib/dokku/services/redis/dokku-redis/data
Dsn: redis://dokku-redis:df40bbae8555ab43ff946605e4c@dokku-redis-dokku-redis:6379
Exposed ports: -
Id: e535a815b6bdc6898c9e6615d2e3fe0dd7387598bc6795aaf0529ad998b2f114
Internal ip: 172.17.0.8
Links:
Service root: /var/lib/dokku/services/redis/dokku-redis
Status: running
Version: redis:4.0.11
  • 连接 redis 与容器应用服务
1
2
3
4
5
6
7
8
9
10
11
12
13
~$ dokku redis:link dokku-redis  yfh5
-----> Setting config vars
REDIS_URL: redis://dokku-redis:df40bbae8555ab43ff946605e4c@dokku-redis-dokku-redis:6379
-----> Restarting app yfh5
-----> Releasing yfh5 (dokku/yfh5:latest)...
[...]

~$ dokku redis:info dokku-redis
[...]
Internal ip: 172.17.0.8
Links: yfh5
Service root: /var/lib/dokku/services/redis/dokku-redis
[...]
  • 添加到Django项目中用作Sessiong Cache,修改settings.py的内容如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

CACHES = {
"default": {
"BACKEND":
"django_redis.cache.RedisCache",
"LOCATION":
"redis://dokku-redis:df40bbae8555ab43ff946605e4c@dokku-redis-dokku-redis:6379",
"OPTIONS": {
"DB":
0,
"PASSWORD":
"df40bbae8555ab43ff946605e4c",
"CONNECTION_POOL_KWARGS": {
"max_connections": 65535
},
}
}
}

设置 Settings.py

  • How to deploy Django on Dokku
  • Dokku Environment Variables
  • 因为Django开发测试需要与数据库连接,且开发环境与生产(测试)部署的环境是不一样的,这里可以通过在settings.py判断系统环境变理来做出一些自动化.上面那个链接很有参考意.
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    # We should get this from the environment, never store them in git.
    # 为了安全建义不要SECRET_KEY直接写入settings.py,它会保存在git上面记录.
    # 可以使用 dokku config:set appname SECRET_KEY='xxxxxx'
    SECRET_KEY = os.environ.get("SECRET_KEY", 'secret')

    # Set DEBUG to False if the NODEBUG env var has been set.
    DEBUG = True if os.environ.get("NODEBUG") is None else False

    # Set the allowed hosts based on the environment.
    ALLOWED_HOSTS = ["web", "localhost"] if os.environ.get("NODEBUG") is None else [".yourdomain.com"]

    if os.environ.get("IN_DOCKER"):
    # Stuff for when running in Docker-compose.
    # 使用Docker-compose会有IN_DOCKER这个环境变量

    CELERY_BROKER_URL = 'redis://redis:6379/1'
    CELERY_RESULT_BACKEND = 'redis://redis:6379/1'
    DATABASES = {
    'default': {
    'ENGINE': 'django.db.backends.postgresql_psycopg2',
    'NAME': "postgres",
    'USER': 'postgres',
    'PASSWORD': 'password',
    'HOST': "db",
    'PORT': 5432,
    }
    }
    elif os.environ.get("DATABASE_URL"):
    # Stuff for when running in Dokku.

    # Parse the DATABASE_URL env var.
    regex = "^postgres://(?P<username>.*?)\:(?P<password>.*?)\@(?P<host>.*?)\:(?P<port>\d+)\/(?P<db>.*?)$"
    USER, PASSWORD, HOST, PORT, NAME = re.match(regex, os.environ.get("DATABASE_URL", "")).groups()

    DATABASES = {
    'default': {
    'ENGINE': 'django.db.backends.postgresql_psycopg2',
    'NAME': NAME,
    'USER': USER,
    'PASSWORD': PASSWORD,
    'HOST': HOST,
    'PORT': int(PORT),
    }
    }

    CELERY_BROKER_URL = os.environ.get("REDIS_URL", "") + "/1"
    CELERY_RESULT_BACKEND = os.environ.get("REDIS_URL", "") + "/1"
    else:
    # Stuff for when running locally.

    CELERY_TASK_ALWAYS_EAGER = True
    DATABASES = {
    'default': {
    'ENGINE': 'django.db.backends.sqlite3',
    'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
    }
    }

Mysql插件应用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
~$ sudo dokku plugin:install https://github.com/dokku/dokku-mysql.git mysql
# 创建数据库服务
~$ sudo dokku mysql:create dyt
Waiting for container to be ready
=====> MySQL container created: dyt
=====> Container Information
Config dir: /var/lib/dokku/services/mysql/dyt/config
Data dir: /var/lib/dokku/services/mysql/dyt/data
Dsn: mysql://mysql:42b0d88fb443bab7@dokku-mysql-dyt:3306/dyt
Exposed ports: -
Id: 45171e69490d59524728846297870ca3010d0066e9972f00448b95bf8bbe86d2
Internal ip: 172.17.0.10
Links: -
Service root: /var/lib/dokku/services/mysql/dyt
Status: running
Version: mysql:5.7.12
# 把应用与数库服务连接起来
~$ sudo dokku mysql:link dyt phpenroll
-----> Setting config vars
DATABASE_URL: mysql://mysql:42b0d88fb443bab7@dokku-mysql-dbname:3306/dyt
-----> Restarting app phpenroll

# 备价与恢复
~$ dokku mysql:export [db_name] > [db_name].dump
~$ dokku mysql:import [db_name] < [db_name].dump
# 进入数据库
~$ dokku mysql:connect dyt
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| dyt |
+--------------------+
2 rows in set (0.00 sec)

# 注意,dokku 创建的数据服务,里面只有一个与服务名相同的数据库,同时也不能通过mysql命令进去创建新的数据库,用户与授权.

Persistent Storage

  • 参考链接
  • 这里需要在主机上先建一个目录,供给容器内挂载,官方推荐是/var/lib/dokku/data/storage,这里可以是其它文件系统目录如:cephfs,nfs等. 关于volume与主机共享数据使用,也可以参考http://dokku.viewdocs.io/dokku/advanced-usage/docker-options/.如:dokku docker-options:add node-js-app deploy,run "-v /var/log/node-js-app:/app/logs"
1
2
~$ sudo dokku plugin:install storage
~$ dokku storage:mount node-js-app /var/lib/dokku/data/storage/node-js-app:/storage

常见的错误

1
2
3
~$ -----> Python app detected
! Requested runtime (python-3.6.7) is not available for this stack (heroku-16).
! Aborting. More info: https://devcenter.heroku.com/articles/python-support
  • 如果出现上述错误,请重新安装.

与 WebPack 集成

谢谢支持