-
Notifications
You must be signed in to change notification settings - Fork 421
Expand file tree
/
Copy pathdeploy.yml
More file actions
213 lines (190 loc) · 6.02 KB
/
deploy.yml
File metadata and controls
213 lines (190 loc) · 6.02 KB
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
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
# code: language=ansible
# Deploy Django Material project to a generic Ubuntu host.
# Usage:
# ansible-playbook -u root --ask-vault-pass deploy.yml
# Refresh existing installation (without .env changes):
# ansible-playbook -u root --tags=update deploy.yml
- name: "Django Material stack deployment"
hosts: all
collections:
- community.postgresql
become: true
gather_facts: false
environment:
LANG: "en_US.UTF-8"
LC_ALL: "en_US.UTF-8"
vars:
ansible_ssh_pipelining: 1
ansible_python_interpreter: /usr/bin/python3.12
project_user: material
project_group: caddy
project_dir: /srv/material
venv_path: "{{ project_dir }}/.venv"
handlers:
- name: "Caddy | Restart"
ansible.builtin.service:
name: caddy
state: restarted
- name: "Web | Restart"
ansible.builtin.service:
name: material-web
state: restarted
daemon_reload: true
- name: "Web Socket | Restart"
ansible.builtin.service:
name: material-web.socket
state: restarted
daemon_reload: true
tasks:
- name: "System | Ensure project directory exists"
ansible.builtin.file:
path: "{{ project_dir }}"
state: directory
mode: "0755"
- name: "System | Add caddy repository"
ansible.builtin.apt_repository:
repo: deb [trusted=yes] https://apt.fury.io/caddy/ /
- name: "System | Install system wide dependencies"
ansible.builtin.package:
state: present
name:
- rsync
- postgresql
- caddy
- msmtp-mta
- python3-psycopg2 # Required by ansible to create pg db/user
- python3-setuptools # Required by ansible to use pip
- python3-pip # Actual pip for ansible
- python3-venv # Allows creating virtual environment
- python3-dev # Setup the python dev package
- name: "System | Install uv package manager"
ansible.builtin.shell: "{{ ansible_python_interpreter }} -m pip install uv --break-system-packages"
- name: "System | Create system user"
ansible.builtin.user:
name: "{{ project_user }}"
group: caddy
system: true
create_home: true
home: "{{ project_dir }}"
- name: "System | MSMTP configuration"
ansible.builtin.copy:
src: "config/msmtprc.enc"
dest: "/etc/msmtprc"
decrypt: true
mode: "u+r"
- name: "Database | Create postgresql user"
become: true
become_user: postgres
community.postgresql.postgresql_user:
name: "material"
- name: "Database | Create postgresql database"
become: true
become_user: postgres
community.postgresql.postgresql_db:
name: material
owner: material
- name: "Web | Setup caddyfile"
ansible.builtin.copy:
content: |
import *.caddy
dest: "/etc/caddy/Caddyfile"
mode: "a+r"
notify:
- "Caddy | Restart"
- name: "Web | Caddy configuration"
ansible.builtin.template:
src: config/material-web.caddy.j2
dest: "/etc/caddy/material.caddy"
mode: "a+r"
notify:
- "Caddy | Restart"
- name: "Web | Setup gunicorn socket"
ansible.builtin.template:
src: config/material-web.socket.j2
dest: /etc/systemd/system/material-web.socket
mode: "a+r"
notify:
- "Web Socket | Restart"
- name: "Web | Setup gunicorn service"
ansible.builtin.template:
src: config/material-web.service.j2
dest: /etc/systemd/system/material-web.service
mode: "a+r"
notify:
- "Web | Restart"
- name: "Project | Create runtime directories"
ansible.builtin.file:
path: "/run/material"
state: directory
owner: "{{ project_user }}"
group: "{{ project_group }}"
mode: "0770"
- name: "Project | Create data directories"
ansible.builtin.file:
path: "{{ item }}"
state: directory
owner: "{{ project_user }}"
group: "{{ project_group }}"
mode: "0770"
with_items:
- "{{ project_dir }}/media"
- "{{ project_dir }}/static"
- name: "Project | Synchronize source code"
ansible.posix.synchronize:
src: "./"
dest: "/srv/material"
delete: true
use_ssh_args: true
rsync_opts:
- "--exclude='.*'"
- "--exclude='*.pyc'"
- "--exclude='/config/'"
- "--exclude='/media/'"
- "--exclude='/static/'"
- "--exclude='/.venv/'"
- "--exclude='/node_modules/'"
register: source
notify:
- "Web | Restart"
- "Web Socket | Restart"
tags: update
- name: "Project | Fix ownership"
ansible.builtin.file:
path: "{{ project_dir }}"
owner: "{{ project_user }}"
group: "{{ project_group }}"
recurse: true
when: source.changed
tags: update
- name: "Project | Install python dependencies"
ansible.builtin.shell: "uv sync --group prod"
args:
chdir: "{{ project_dir }}"
become: true
become_user: "{{ project_user }}"
when: source.changed
tags: update
- name: "Django | Create/Update .env file"
ansible.builtin.copy:
src: "config/env.enc"
dest: "{{ project_dir }}/.env"
owner: "{{ project_user }}"
decrypt: true
mode: "u+r"
when: source.changed
- name: "Django | Collect static files"
ansible.builtin.shell: "{{ venv_path }}/bin/python manage.py collectstatic --noinput"
args:
chdir: "{{ project_dir }}"
become: true
become_user: "{{ project_user }}"
when: source.changed
tags: update
- name: "Django | Run migration"
ansible.builtin.shell: "{{ venv_path }}/bin/python manage.py migrate --noinput"
args:
chdir: "{{ project_dir }}"
become: true
become_user: "{{ project_user }}"
tags: update
when: source.changed