me-web? skeleton: Avalonia 12 app, server, packaging and CI
Build / Desktop, server and tools (push) Successful in 1m7s
Build / Desktop, server and tools (push) Successful in 1m7s
The first screen (online or not, a Check button, every language with a draft notice), the desktop and Android heads, the server's /api/info and /api/ip, a release tool that builds deb, rpm, a Windows exe, macOS zips, a signed APK and the server, and the Gitea workflows that run it. Rules adapted from passolo; AGPL-3.0. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012CzABvBkbcFqoHdmi8b9WB
This commit is contained in:
commit
7589121846
76 files changed
+3082
No files matched your search
Executable
+65
@@ -0,0 +1,65 @@
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
|
||||
here="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||
site=meweb.arasaka.software
|
||||
names=(meweb.arasaka.software v4.meweb.arasaka.software v6.meweb.arasaka.software)
|
||||
app=/var/www/$site
|
||||
backups=/var/backups/$site
|
||||
etc=/etc/meweb
|
||||
env=$etc/meweb.env
|
||||
unit=/etc/systemd/system/meweb.service
|
||||
sudoers=/etc/sudoers.d/gitea-runner
|
||||
acme=/root/.acme.sh/acme.sh
|
||||
cert=/root/.acme.sh/${site}_ecc/fullchain.cer
|
||||
|
||||
[ "$(id -u)" = 0 ] || { echo "run as root"; exit 1; }
|
||||
|
||||
id meweb >/dev/null 2>&1 || useradd --system --no-create-home --shell /usr/sbin/nologin meweb
|
||||
install -d -o gitea-runner -g gitea-runner -m 755 "$app" "$backups"
|
||||
install -d -o root -g meweb -m 750 "$etc"
|
||||
if [ ! -f "$env" ]; then
|
||||
printf '%s\n' \
|
||||
'ASPNETCORE_ENVIRONMENT=Production' \
|
||||
'ASPNETCORE_URLS=http://127.0.0.1:5480' \
|
||||
'DOTNET_PRINT_TELEMETRY_MESSAGE=false' \
|
||||
'DOTNET_CLI_TELEMETRY_OPTOUT=1' > "$env"
|
||||
chown root:meweb "$env"
|
||||
chmod 640 "$env"
|
||||
echo "wrote $env"
|
||||
fi
|
||||
|
||||
install -m 644 "$here/meweb.service" "$unit"
|
||||
systemctl daemon-reload
|
||||
systemctl enable meweb.service >/dev/null 2>&1
|
||||
|
||||
line="gitea-runner ALL=(root) NOPASSWD: /usr/bin/systemctl start meweb, /usr/bin/systemctl stop meweb, /usr/bin/systemctl restart meweb, /usr/bin/systemctl is-active meweb, /usr/bin/systemctl show meweb*, /usr/bin/systemctl status meweb*"
|
||||
if ! grep -qF "$line" "$sudoers"; then
|
||||
cp "$sudoers" "$sudoers.new"
|
||||
echo "$line" >> "$sudoers.new"
|
||||
visudo -cf "$sudoers.new" >/dev/null
|
||||
install -m 440 "$sudoers.new" "$sudoers"
|
||||
rm -f "$sudoers.new"
|
||||
echo "sudoers: meweb added for gitea-runner"
|
||||
fi
|
||||
|
||||
if [ ! -f "$cert" ]; then
|
||||
install -m 644 "$here/nginx/$site.http.conf" "/etc/nginx/sites-enabled/$site.conf"
|
||||
nginx -t
|
||||
systemctl reload nginx
|
||||
args=()
|
||||
for name in "${names[@]}"; do args+=(-d "$name"); done
|
||||
"$acme" --issue --webroot /var/www/acme "${args[@]}" --keylength ec-256 --reloadcmd "systemctl reload nginx"
|
||||
fi
|
||||
|
||||
install -m 644 "$here/nginx/$site.conf" "/etc/nginx/sites-enabled/$site.conf"
|
||||
nginx -t
|
||||
systemctl reload nginx
|
||||
|
||||
if [ -x "$app/MeWeb.Server" ]; then
|
||||
systemctl restart meweb
|
||||
systemctl is-active meweb
|
||||
else
|
||||
echo "no build in $app yet: the release workflow deploys it"
|
||||
fi
|
||||
echo "setup done"
|
||||
@@ -0,0 +1,24 @@
|
||||
[Unit]
|
||||
Description=me-web? server (meweb.arasaka.software)
|
||||
After=network-online.target mongod.service
|
||||
Wants=network-online.target
|
||||
|
||||
[Service]
|
||||
User=meweb
|
||||
Group=meweb
|
||||
WorkingDirectory=/var/www/meweb.arasaka.software
|
||||
ExecStart=/var/www/meweb.arasaka.software/MeWeb.Server
|
||||
EnvironmentFile=/etc/meweb/meweb.env
|
||||
Restart=always
|
||||
RestartSec=5
|
||||
KillSignal=SIGINT
|
||||
SyslogIdentifier=meweb
|
||||
NoNewPrivileges=true
|
||||
PrivateTmp=true
|
||||
ProtectSystem=strict
|
||||
ProtectHome=true
|
||||
ReadOnlyPaths=/var/www/meweb.arasaka.software
|
||||
MemoryMax=512M
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
@@ -0,0 +1,50 @@
|
||||
server {
|
||||
listen 80;
|
||||
listen [::]:80;
|
||||
server_name meweb.arasaka.software v4.meweb.arasaka.software v6.meweb.arasaka.software;
|
||||
|
||||
location ^~ /.well-known/acme-challenge/ {
|
||||
root /var/www/acme;
|
||||
default_type "text/plain";
|
||||
allow all;
|
||||
}
|
||||
|
||||
location / {
|
||||
return 301 https://$host$request_uri;
|
||||
}
|
||||
}
|
||||
|
||||
server {
|
||||
listen 443 ssl;
|
||||
listen 8444 ssl proxy_protocol;
|
||||
listen [::]:443 ssl;
|
||||
server_name meweb.arasaka.software v4.meweb.arasaka.software v6.meweb.arasaka.software;
|
||||
|
||||
ssl_certificate /root/.acme.sh/meweb.arasaka.software_ecc/fullchain.cer;
|
||||
ssl_certificate_key /root/.acme.sh/meweb.arasaka.software_ecc/meweb.arasaka.software.key;
|
||||
|
||||
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
|
||||
add_header Referrer-Policy "no-referrer" always;
|
||||
add_header X-Content-Type-Options "nosniff" always;
|
||||
add_header X-Frame-Options "DENY" always;
|
||||
|
||||
access_log /var/log/nginx/meweb.arasaka.software.access.log;
|
||||
error_log /var/log/nginx/meweb.arasaka.software.error.log;
|
||||
|
||||
client_max_body_size 128k;
|
||||
|
||||
location ^~ /.well-known/acme-challenge/ {
|
||||
root /var/www/acme;
|
||||
default_type "text/plain";
|
||||
allow all;
|
||||
}
|
||||
|
||||
location / {
|
||||
proxy_pass http://127.0.0.1:5480;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Forwarded-For $remote_addr;
|
||||
proxy_set_header X-Forwarded-Proto https;
|
||||
proxy_set_header Connection "";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
server {
|
||||
listen 80;
|
||||
listen [::]:80;
|
||||
server_name meweb.arasaka.software v4.meweb.arasaka.software v6.meweb.arasaka.software;
|
||||
|
||||
location ^~ /.well-known/acme-challenge/ {
|
||||
root /var/www/acme;
|
||||
default_type "text/plain";
|
||||
allow all;
|
||||
}
|
||||
|
||||
location / {
|
||||
return 301 https://$host$request_uri;
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user