stash
This commit is contained in:
parent
419893d93d
commit
dae1528793
4 changed files with 104 additions and 19 deletions
|
|
@ -41,6 +41,10 @@
|
|||
toolshed_backend_port: 8000
|
||||
toolshed_wiki_dist_dir: /var/www/toolshed-wiki
|
||||
toolshed_local_dir: /var/www/toolshed-local
|
||||
# Django's collectstatic output (admin/drf-yasg assets etc.), exported
|
||||
# from the built backend image so nginx can serve it directly instead of
|
||||
# proxying to gunicorn for every asset request.
|
||||
toolshed_static_dir: /var/www/toolshed-static
|
||||
# Domain(s) this server accepts registrations for (the "handle domain" -
|
||||
# see the README's DNS section). Served as a static /local/domains
|
||||
# fixture that the frontend's registration/pairing forms fetch to
|
||||
|
|
@ -73,15 +77,14 @@
|
|||
# header instead.
|
||||
toolshed_x_forwarded_proto: >-
|
||||
{{ '$http_x_forwarded_proto' if (behind_tls_proxy | default(false) | bool) else '$scheme' }}
|
||||
# The web domain (toolshed_domain, mandatory) and the handle domain
|
||||
# (toolshed_handle_domain, optional - defaults to the web domain when
|
||||
# they're the same) both need to be accepted by nginx/Django, since
|
||||
# either may show up as the Host header depending on how the admin set
|
||||
# up DNS for this deployment. Deduplicated so setting them equal
|
||||
# doesn't produce a repeated entry.
|
||||
# Only the web domain (toolshed_domain) - nginx server_name, Django
|
||||
# ALLOWED_HOSTS, and the cert certbot requests. The handle domain
|
||||
# (toolshed_handle_domain) is resolved by clients via its own SRV record
|
||||
# and doesn't necessarily have an A record pointing at this host at all
|
||||
# (see the README's DNS section), so it can't reliably serve an HTTP-01
|
||||
# challenge or ever show up as this nginx's Host header.
|
||||
toolshed_hostnames: >-
|
||||
{{ [toolshed_domain | mandatory('toolshed_domain must be set as a host_var for ' ~ inventory_hostname),
|
||||
toolshed_handle_domain | default(toolshed_domain)] | unique }}
|
||||
{{ [toolshed_domain | mandatory('toolshed_domain must be set as a host_var for ' ~ inventory_hostname)] }}
|
||||
# Generated once per host on the controller and reused on every
|
||||
# subsequent run against that host, keyed by inventory_hostname so
|
||||
# separate deployments never end up sharing a Django SECRET_KEY.
|
||||
|
|
@ -120,6 +123,11 @@
|
|||
proxy_pass http://toolshed_backend;
|
||||
}
|
||||
|
||||
# Django (SignatureAuthentication + per-file friend/owner checks,
|
||||
# see files/media_urls.py) decides whether the request is allowed
|
||||
# at all; it never streams the bytes itself here (SERVE_X_ACCEL_REDIRECT
|
||||
# is on), it just answers with an X-Accel-Redirect to the internal
|
||||
# location below, which nginx follows and serves directly from disk.
|
||||
location /media {
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
|
|
@ -128,6 +136,19 @@
|
|||
proxy_pass http://toolshed_backend;
|
||||
}
|
||||
|
||||
# Only reachable via the X-Accel-Redirect above, never directly by
|
||||
# clients (`internal`) - this is what makes it safe for nginx to
|
||||
# serve these bytes itself without reimplementing the access
|
||||
# checks Django already did in the /media location.
|
||||
location /redirect_media/ {
|
||||
internal;
|
||||
alias {{ toolshed_data_dir }}/userfiles/;
|
||||
# Django would normally set this itself (CORS_ALLOW_ALL_ORIGINS,
|
||||
# see settings.py) but never gets to run for a request nginx
|
||||
# serves directly - see the comment in files/media_urls.py.
|
||||
add_header Access-Control-Allow-Origin * always;
|
||||
}
|
||||
|
||||
location /djangoadmin {
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
|
|
@ -144,8 +165,9 @@
|
|||
proxy_pass http://toolshed_backend;
|
||||
}
|
||||
|
||||
location /static {
|
||||
proxy_pass http://toolshed_backend/static;
|
||||
location /static/ {
|
||||
alias {{ toolshed_static_dir }}/;
|
||||
try_files $uri =404;
|
||||
}
|
||||
|
||||
location /wiki/ {
|
||||
|
|
@ -283,6 +305,20 @@
|
|||
- "{{ toolshed_data_dir }}"
|
||||
- "{{ toolshed_data_dir }}/userfiles"
|
||||
|
||||
# nginx's `location /redirect_media/` (below) reads user-uploaded files
|
||||
# straight off disk as www-data - group membership plus the 0750 mode
|
||||
# above/FILE_UPLOAD_PERMISSIONS (backend/backend/settings.py) is what
|
||||
# makes that readable without loosening it to world-readable.
|
||||
- name: Allow nginx to read backend user files
|
||||
ansible.builtin.user:
|
||||
name: www-data
|
||||
groups: toolshed
|
||||
append: true
|
||||
# New group membership only takes effect for processes started (or
|
||||
# forked) after this - nginx's already-running workers won't see it
|
||||
# until reloaded.
|
||||
notify: reload nginx
|
||||
|
||||
- name: Create frontend static output directory
|
||||
ansible.builtin.file:
|
||||
path: "{{ toolshed_dist_dir }}"
|
||||
|
|
@ -291,6 +327,14 @@
|
|||
group: www-data
|
||||
mode: "0755"
|
||||
|
||||
- name: Create backend static output directory
|
||||
ansible.builtin.file:
|
||||
path: "{{ toolshed_static_dir }}"
|
||||
state: directory
|
||||
owner: www-data
|
||||
group: www-data
|
||||
mode: "0755"
|
||||
|
||||
- name: Write backend environment file
|
||||
ansible.builtin.copy:
|
||||
dest: "{{ toolshed_data_dir }}/backend.env"
|
||||
|
|
@ -306,7 +350,7 @@
|
|||
DEBUG={{ toolshed_debug }}
|
||||
SECRET_KEY={{ toolshed_secret_key }}
|
||||
ALLOWED_HOSTS={{ toolshed_hostnames | join(',') }}
|
||||
SERVE_X_ACCEL_REDIRECT=False
|
||||
SERVE_X_ACCEL_REDIRECT=True
|
||||
TOOLSHED_DB_PATH=/data/db.sqlite3
|
||||
TOOLSHED_USERFILES_PATH=/data/userfiles
|
||||
notify: restart backend
|
||||
|
|
@ -325,6 +369,26 @@
|
|||
changed_when: true
|
||||
notify: restart backend
|
||||
|
||||
# Dockerfile.backend runs collectstatic at build time, baking the result
|
||||
# into the image at /app/staticfiles - copy it out to the host so nginx
|
||||
# can serve it directly instead of proxying every asset request to
|
||||
# gunicorn. No Django settings/DB access needed, so this can run as a
|
||||
# one-off command against the image rather than the container.
|
||||
- name: Export backend static files
|
||||
ansible.builtin.command:
|
||||
cmd: >-
|
||||
docker run --rm -v {{ toolshed_static_dir }}:/output
|
||||
{{ toolshed_backend_image }}:latest
|
||||
sh -c "cp -a /app/staticfiles/. /output/"
|
||||
changed_when: true
|
||||
|
||||
- name: Fix ownership of exported backend static files
|
||||
ansible.builtin.file:
|
||||
path: "{{ toolshed_static_dir }}"
|
||||
owner: www-data
|
||||
group: www-data
|
||||
recurse: true
|
||||
|
||||
- name: Install systemd unit for the backend container
|
||||
ansible.builtin.copy:
|
||||
dest: /etc/systemd/system/toolshed-backend.service
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue