blob: e561b5d0d1ef9ca38f819fd08fceca08121c0185 (
plain) (
blame)
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
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
|
# Deployment
The default Dockerfile should do a good job at running a solid web server that
automatically adjusts its worker count based on traffic. This is managed by
uWSGI. You need to configure the `DATABASE_URL` and `SECRET_KEY` variables. If
you want to deploy to a different host than the default, configure the
`ALLOWED_HOSTS` variable.
## Static file hosting
You can either collect the static files in the container and use uWSGI to host
them, or put them on your host and manage them through a web server running on
the host like nginx.
## Database migrations
To bring the schema up-to-date, first stop an existing database container, then
start a container that just runs the migrations and exits, and then starts the
main container off the new container again.
## Ansible task
An example Ansible task to deploy the site is shown below, it should read fairly
humanly and give you a rough idea of steps needed to deploy the site.
```yml
- name: ensure the `{{ pysite_pg_username }}` postgres user exists
become: yes
become_user: postgres
postgresql_user:
name: "{{ pysite_pg_username }}"
password: "{{ pysite_pg_password }}"
when: pysite_pg_host == 'localhost'
- name: ensure the `{{ pysite_pg_database }}` postgres database exists
become: yes
become_user: postgres
postgresql_db:
name: "{{ pysite_pg_database }}"
owner: "{{ pysite_pg_username }}"
when: pysite_pg_host == 'localhost'
- name: ensure the `{{ pysite_hub_repository }}` image is up-to-date
become: yes
docker_image:
name: "{{ pysite_hub_repository }}"
force: yes
- name: ensure the nginx HTTP vhosts are up-to-date
become: yes
template:
src: "nginx/{{ item.key }}.http.conf.j2"
dest: "/etc/nginx/sites-available/{{ item.value }}.http.conf"
with_dict: "{{ pysite_domains }}"
notify: reload nginx
- name: ensure the nginx HTTPS vhosts are up-to-date
become: yes
template:
src: "nginx/{{ item.key }}.https.conf.j2"
dest: "/etc/nginx/sites-available/{{ item.value }}.https.conf"
with_dict: "{{ pysite_domains }}"
notify: reload nginx
- name: ensure the nginx HTTP vhosts are symlinked to `/etc/nginx/sites-enabled`
become: yes
file:
src: /etc/nginx/sites-available/{{ item.value }}.http.conf
dest: /etc/nginx/sites-enabled/{{ item.value }}.http.conf
state: link
with_dict: "{{ pysite_domains }}"
notify: reload nginx
- name: ensure we have HTTPS certificates
include_role:
name: thefinn93.letsencrypt
vars:
letsencrypt_cert_domains: "{{ pysite_domains | dict2items | map(attribute='value') | list }}"
letsencrypt_email: "[email protected]"
letsencrypt_renewal_command_args: '--renew-hook "systemctl restart nginx"'
letsencrypt_webroot_path: /var/www/_letsencrypt
- name: ensure the nginx HTTPS vhosts are symlinked to `/etc/nginx/sites-enabled`
become: yes
file:
src: /etc/nginx/sites-available/{{ item.value }}.https.conf
dest: /etc/nginx/sites-enabled/{{ item.value }}.https.conf
state: link
with_dict: "{{ pysite_domains }}"
notify: reload nginx
- name: ensure the web container is absent
become: yes
docker_container:
name: pysite
state: absent
- name: ensure the `{{ pysite_static_file_dir }}` directory exists
become: yes
file:
path: "{{ pysite_static_file_dir }}"
state: directory
owner: root
group: root
- name: collect static files
become: yes
docker_container:
image: "{{ pysite_hub_repository }}"
name: pysite-static-file-writer
command: python manage.py collectstatic --noinput
detach: no
cleanup: yes
network_mode: host
env:
DATABASE_URL: "{{ pysite_pg_database_url }}"
SECRET_KEY: "me-dont-need-no-secret-key"
STATIC_ROOT: "/html"
volumes:
- "/var/www/pythondiscord.com:/html"
- name: ensure the database schema is up-to-date
become: yes
docker_container:
image: "{{ pysite_hub_repository }}"
name: pysite-migrator
detach: no
cleanup: yes
command: python manage.py migrate
network_mode: host
env:
DATABASE_URL: "postgres://{{ pysite_pg_username }}:{{ pysite_pg_password }}@{{ pysite_pg_host }}/{{ pysite_pg_database }}"
SECRET_KEY: "me-dont-need-no-secret-key"
- name: ensure the website container is started
become: yes
docker_container:
image: "{{ pysite_hub_repository }}"
name: pysite
network_mode: host
restart: yes
restart_policy: unless-stopped
ports:
- "127.0.0.1:4000:4000"
env:
ALLOWED_HOSTS: "{{ pysite_domains | dict2items | map(attribute='value') | join(',') }}"
DATABASE_URL: "postgres://{{ pysite_pg_username }}:{{ pysite_pg_password }}@{{ pysite_pg_host }}/{{ pysite_pg_database }}"
PARENT_HOST: pysite.example.com
SECRET_KEY: "{{ pysite_secret_key }}"
```
|