Page Menu
Home
DevCentral
Search
Configure Global Search
Log In
Files
F11724580
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
10 KB
Referenced Files
None
Subscribers
None
View Options
diff --git a/roles/paas-docker/containers/penpot_web.sls b/roles/paas-docker/containers/penpot_web.sls
index 3661565..76b9e30 100644
--- a/roles/paas-docker/containers/penpot_web.sls
+++ b/roles/paas-docker/containers/penpot_web.sls
@@ -1,119 +1,132 @@
# -------------------------------------------------------------
# Salt — Provision Penpot
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# Project: Nasqueron
# License: Trivial work, not eligible to copyright
# -------------------------------------------------------------
{% set has_selinux = salt["grains.get"]("selinux:enabled", False) %}
{% set containers = pillar["docker_containers"] %}
{% for instance, container in containers["penpot_web"].items() %}
{% set flags = salt["convert.to_flags"](container["features"]) %}
# -------------------------------------------------------------
# Storage directory
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
/srv/{{ container["realm"] }}/assets:
file.directory:
- makedirs: True
- user: 1001
- group: 1001
{% if has_selinux %}
selinux_context_penpot_data:
selinux.fcontext_policy_present:
- name: /srv/{{ container["realm"] }}/assets
- sel_type: container_file_t
selinux_context_penpot_data_applied:
selinux.fcontext_policy_applied:
- name: /srv/{{ container["realm"] }}/assets
{% endif %}
# -------------------------------------------------------------
# Front-end assets
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
/srv/{{ container["realm"] }}/public:
file.directory:
- makedirs: True
+/srv/{{ container["realm"] }}/cache:
+ file.directory:
+ - makedirs: True
+
penpot_{{ container["realm"] }}_public_content:
cmd.run:
- name: |
wget https://artifacts.nasqueron.org/penpot/penpot.tar.gz && \
tar xzf penpot.tar.gz --strip 1 && \
rm penpot.tar.gz
- cwd: /srv/{{ container["realm"] }}/public
- creates: /srv/{{ container["realm"] }}/public/version.txt
/srv/{{ container["realm"] }}/public/js/config.js:
file.managed:
- mode: 444
- contents: |
var penpotFlags = "{{ flags }}";
{% if has_selinux %}
selinux_context_penpot_public_data:
selinux.fcontext_policy_present:
- name: /srv/{{ container["realm"] }}/public
- sel_type: container_file_t
selinux_context_penpot_public_data_applied:
selinux.fcontext_policy_applied:
- name: /srv/{{ container["realm"] }}/public
+
+selinux_context_penpot_cache_data:
+ selinux.fcontext_policy_present:
+ - name: /srv/{{ container["realm"] }}/cache
+ - sel_type: httpd_cache_t
+
+selinux_context_penpot_cache_data_applied:
+ selinux.fcontext_policy_applied:
+ - name: /srv/{{ container["realm"] }}/cache
{% endif %}
# -------------------------------------------------------------
# Container
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
{{ instance }}:
docker_container.running:
- detach: True
- interactive: True
- image: penpotapp/backend
- networks:
- {{ container["network"] }}
- binds: /srv/{{ container["realm"] }}/assets:/opt/data/assets
- environment:
PENPOT_FLAGS: {{ flags }}
PENPOT_SECRET_KEY: {{ salt["credentials.get_password"](container["credentials"]["secret_key"]) }}
PENPOT_PREPL_HOST: 0.0.0.0
PENPOT_PUBLIC_URI: https://{{ container["host"] }}
PENPOT_DATABASE_URI: postgresql://{{ container["services"]["postgresql"] }}/penpot
PENPOT_DATABASE_USERNAME: {{ salt["credentials.get_username"](container["credentials"]["postgresql"]) }}
PENPOT_DATABASE_PASSWORD: {{ salt["credentials.get_password"](container["credentials"]["postgresql"]) }}
PENPOT_REDIS_URI: redis://{{ container["services"]["redis"] }}/0
PENPOT_ASSETS_STORAGE_BACKEND: assets-fs
PENPOT_STORAGE_ASSETS_FS_DIRECTORY: /opt/data/assets
# Our privacy policy explicitly states we don't transfer data
# to third parties.
PENPOT_TELEMETRY_ENABLED: "false"
{% if "smtp" in container["features"] %}
PENPOT_SMTP_HOST: {{ container["services"]["smtp"] }}
PENPOT_SMTP_PORT: 25
PENPOT_SMTP_TLS: "false"
{% endif %}
PENPOT_SMTP_DEFAULT_FROM: no-reply@{{ container["host"] }}
PENPOT_SMTP_DEFAULT_REPLY_TO: no-reply@{{ container["host"] }}
{% if "login-with-github" in container["features"] %}
PENPOT_GITHUB_CLIENT_ID: {{ salt["credentials.get_username"](container["credentials"]["github"]) }}
PENPOT_GITHUB_CLIENT_SECRET: {{ salt["credentials.get_password"](container["credentials"]["github"]) }}
{% endif %}
- ports:
- 6060
- port_bindings:
- {{ container['app_port'] }}:6060
{% endfor %}
diff --git a/roles/paas-docker/nginx/files/vhosts/penpot_web.conf b/roles/paas-docker/nginx/files/vhosts/penpot_web.conf
index f957af4..1039689 100644
--- a/roles/paas-docker/nginx/files/vhosts/penpot_web.conf
+++ b/roles/paas-docker/nginx/files/vhosts/penpot_web.conf
@@ -1,106 +1,173 @@
# -------------------------------------------------------------
# Configuration for Docker PaaS front-end nginx
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# Source file: roles/paas-docker/nginx/files/vhosts/penpot_web.conf
# -------------------------------------------------------------
#
# <auto-generated>
# This file is managed by our rOPS SaltStack repository.
#
# Changes to this file may cause incorrect behavior
# and will be lost if the state is redeployed.
# </auto-generated>
+# -------------------------------------------------------------
+# Proxy cache
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+proxy_cache_path /srv/{{ args["realm"] }}/cache levels=2:2 keys_zone=penpot:20m;
+proxy_cache_methods GET HEAD;
+proxy_cache_valid any 48h;
+proxy_cache_key "$host$request_uri";
+
# -------------------------------------------------------------
# Application - {{ fqdn }}
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
server {
listen 80;
listen [::]:80;
server_name {{ fqdn }};
include includes/letsencrypt;
return 301 https://$host$request_uri;
}
server {
server_name {{ fqdn }};
include includes/tls;
ssl_certificate /srv/letsencrypt/etc/live/{{ fqdn }}/fullchain.pem;
ssl_certificate_key /srv/letsencrypt/etc/live/{{ fqdn }}/privkey.pem;
include includes/letsencrypt;
client_max_body_size 100M;
charset utf-8;
proxy_http_version 1.1;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Scheme $scheme;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
etag off;
location @handle_redirect {
set $redirect_uri "$upstream_http_location";
set $redirect_host "$upstream_http_x_host";
set $redirect_cache_control "$upstream_http_cache_control";
proxy_buffering off;
proxy_set_header Host "$redirect_host";
proxy_hide_header etag;
proxy_pass $redirect_uri;
add_header x-internal-redirect "$redirect_uri";
add_header x-cache-control "$redirect_cache_control";
add_header cache-control "$redirect_cache_control";
}
location /assets {
proxy_pass http://localhost:{{ app_port }}/assets;
recursive_error_pages on;
proxy_intercept_errors on;
error_page 301 302 307 = @handle_redirect;
}
+ location /internal/gfonts/css {
+ resolver 8.8.8.8 8.8.4.4;
+ proxy_pass https://fonts.googleapis.com/css?$args;
+ proxy_hide_header Access-Control-Allow-Origin;
+ proxy_hide_header Cross-Origin-Resource-Policy;
+ proxy_hide_header Link;
+ proxy_hide_header Alt-Svc;
+ proxy_hide_header Cache-Control;
+ proxy_hide_header Expires;
+
+ proxy_ignore_headers Set-Cookie Vary Cache-Control Expires;
+
+ proxy_set_header User-Agent "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36";
+ proxy_set_header Host "fonts.googleapis.com";
+ proxy_set_header Accept "*/*";
+
+ proxy_cache penpot;
+
+ add_header Access-Control-Allow-Origin $http_origin;
+ add_header Cache-Control max-age=86400;
+ add_header X-Cache-Status $upstream_cache_status;
+ }
+
location /internal/assets {
internal;
alias /srv/{{ args["realm"] }}/assets;
add_header x-internal-redirect "$upstream_http_x_accel_redirect";
}
location /api/export {
proxy_pass {{ args["services"]["exporter"] }};
}
location /api {
proxy_pass http://localhost:{{ app_port }}/api;
}
location /ws/notifications {
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_pass http://localhost:{{ app_port }}/ws/notifications;
}
location / {
+ location ~ ^/internal/gfonts/font/(?<font_file>.+) {
+ resolver 8.8.8.8 8.8.4.4;
+ proxy_pass https://fonts.gstatic.com/s/$font_file;
+
+ proxy_hide_header Access-Control-Allow-Origin;
+ proxy_hide_header Cross-Origin-Resource-Policy;
+ proxy_hide_header Link;
+ proxy_hide_header Alt-Svc;
+ proxy_hide_header Cache-Control;
+ proxy_hide_header Expires;
+ proxy_hide_header Cross-Origin-Opener-Policy;
+ proxy_hide_header Report-To;
+
+ proxy_ignore_headers Set-Cookie Vary Cache-Control Expires;
+
+ proxy_set_header User-Agent "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36";
+ proxy_set_header Host "fonts.gstatic.com";
+ proxy_set_header Accept "*/*";
+
+ proxy_cache penpot;
+
+ add_header Access-Control-Allow-Origin $http_origin;
+ add_header Cache-Control max-age=86400;
+ add_header X-Cache-Status $upstream_cache_status;
+ }
+
location ~* \.(js|css).*$ {
add_header Cache-Control "max-age=86400" always; # 24 hours
}
location ~* \.(html).*$ {
add_header Cache-Control "no-cache, max-age=0" always;
}
+
+ location ~ ^/(/|css|fonts|images|js|wasm) {
+ }
+
+ location ~ ^/[^/]+/(.*)$ {
+ return 301 " /404";
+ }
+
root /srv/{{ args["realm"] }}/public;
+ try_files $uri /index.html$is_args$args =404;
}
root /var/wwwroot-502/_default;
error_page 502 /502.html;
location /502.html {}
}
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Thu, Sep 18, 16:20 (2 h, 53 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
2991068
Default Alt Text
(10 KB)
Attached To
Mode
rOPS Nasqueron Operations
Attached
Detach File
Event Timeline
Log In to Comment