06/15 Phase 1 + 2 codes

This commit is contained in:
2026-06-15 11:23:05 -04:00
commit c2064b84b4
62 changed files with 2937 additions and 0 deletions
+12
View File
@@ -0,0 +1,12 @@
[Unit]
Description=Classifieds: expire past-due listings (oneshot)
After=mysql.service
[Service]
Type=oneshot
User=classifieds
Group=classifieds
WorkingDirectory=/opt/classifieds
Environment="PATH=/opt/classifieds/venv/bin"
EnvironmentFile=/opt/classifieds/.env
ExecStart=/opt/classifieds/venv/bin/flask expire-listings
+9
View File
@@ -0,0 +1,9 @@
[Unit]
Description=Run classifieds listing-expiry sweep hourly
[Timer]
OnCalendar=hourly
Persistent=true
[Install]
WantedBy=timers.target
+20
View File
@@ -0,0 +1,20 @@
[Unit]
Description=Classifieds Flask app (Gunicorn)
After=network.target mysql.service redis-server.service
Wants=redis-server.service
[Service]
Type=notify
User=classifieds
Group=classifieds
WorkingDirectory=/opt/classifieds
Environment="PATH=/opt/classifieds/venv/bin"
EnvironmentFile=/opt/classifieds/.env
RuntimeDirectory=classifieds
ExecStart=/opt/classifieds/venv/bin/gunicorn -c deploy/gunicorn.conf.py wsgi:app
ExecReload=/bin/kill -s HUP $MAINPID
Restart=always
RestartSec=3
[Install]
WantedBy=multi-user.target
+12
View File
@@ -0,0 +1,12 @@
"""Gunicorn config. Unix socket behind Nginx."""
import multiprocessing
bind = "unix:/run/classifieds/classifieds.sock"
workers = multiprocessing.cpu_count() * 2 + 1
worker_class = "sync"
timeout = 60
graceful_timeout = 30
keepalive = 5
accesslog = "-"
errorlog = "-"
loglevel = "info"
+36
View File
@@ -0,0 +1,36 @@
server {
listen 80;
server_name classifieds.example.com;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl http2;
server_name classifieds.example.com;
# ssl_certificate /etc/letsencrypt/live/classifieds.example.com/fullchain.pem;
# ssl_certificate_key /etc/letsencrypt/live/classifieds.example.com/privkey.pem;
client_max_body_size 12m; # raise in Phase 2 for image uploads
location /static/ {
alias /opt/classifieds/app/static/;
expires 30d;
access_log off;
}
# Phase 2: user-uploaded media served direct by Nginx
location /media/ {
alias /opt/classifieds/instance/media/;
expires 7d;
access_log off;
}
location / {
proxy_pass http://unix:/run/classifieds/classifieds.sock;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}