From 0f5343fa17d0e24df3f186dd6e2524c89d25c861 Mon Sep 17 00:00:00 2001 From: sergeych Date: Wed, 22 Apr 2026 12:31:01 +0300 Subject: [PATCH] Add VPS deployment target and Ansible provisioning for lynglang.com - deploy_site now defaults to new VPS (94.130.36.94, /var/www/lynglang); use --old to deploy to d.lynglang.com as before - infra/setup_vps.yml: Ansible playbook installs nginx + certbot, obtains SSL cert for lynglang.com, fixes Debian buster EOL apt sources - infra/inventory.ini and infra/templates/nginx_lynglang.conf.j2 included Co-Authored-By: Claude Sonnet 4.6 --- bin/deploy_site | 25 ++++--- infra/inventory.ini | 2 + infra/setup_vps.yml | 100 +++++++++++++++++++++++++ infra/templates/nginx_lynglang.conf.j2 | 24 ++++++ 4 files changed, 140 insertions(+), 11 deletions(-) create mode 100644 infra/inventory.ini create mode 100644 infra/setup_vps.yml create mode 100644 infra/templates/nginx_lynglang.conf.j2 diff --git a/bin/deploy_site b/bin/deploy_site index 1c8b2ab..97c1f24 100755 --- a/bin/deploy_site +++ b/bin/deploy_site @@ -18,10 +18,12 @@ # upload_only=false +target=vps # default: new server; use --old for d.lynglang.com for arg in "$@"; do if [[ "$arg" == "-u" || "$arg" == "--upload-only" ]]; then upload_only=true - break + elif [[ "$arg" == "--old" ]]; then + target=com fi done @@ -88,19 +90,20 @@ function updateIdeaPluginDownloadLink() { fi } -# default target settings -case "com" in +# target settings (-t com | -t vps) +case "$target" in com) - SSH_HOST=sergeych@d.lynglang.com # host to deploy to - SSH_PORT=22 # ssh port on it - ROOT=/bigstore/sergeych_pub/lyng # directory to rsync to + SSH_HOST=sergeych@d.lynglang.com + SSH_PORT=22 + ROOT=/bigstore/sergeych_pub/lyng + ;; + vps) + SSH_HOST=sergeych@94.130.36.94 + SSH_PORT=22 + ROOT=/var/www/lynglang ;; -# com) -# SSH_HOST=vvk@front-01.neurodatalab.com -# ROOT=/home/vvk -# ;; *) - echo "*** ERROR: target not specified (use deploy com | dev)" + echo "*** ERROR: unknown target '$target' (use -t com | -t vps)" echo "*** stop" exit 101 esac diff --git a/infra/inventory.ini b/infra/inventory.ini new file mode 100644 index 0000000..c1c5d6f --- /dev/null +++ b/infra/inventory.ini @@ -0,0 +1,2 @@ +[vps] +94.130.36.94 ansible_user=sergeych diff --git a/infra/setup_vps.yml b/infra/setup_vps.yml new file mode 100644 index 0000000..bc1dc22 --- /dev/null +++ b/infra/setup_vps.yml @@ -0,0 +1,100 @@ +--- +- name: Setup lynglang.com static site on VPS + hosts: vps + become: yes + vars: + domain: lynglang.com + web_root: /var/www/lynglang + deploy_user: sergeych + certbot_email: real.sergeych@gmail.com + + tasks: + # Debian 10 buster is EOL; security/backports repos moved to archive.debian.org + - name: Fix sources.list for Debian buster EOL + copy: + dest: /etc/apt/sources.list + content: | + deb http://archive.debian.org/debian/ buster main contrib non-free + deb http://archive.debian.org/debian-security/ buster/updates main contrib non-free + deb http://archive.debian.org/debian/ buster-backports main contrib non-free + + - name: Remove stale third-party sources (broken for buster EOL) + file: + path: "/etc/apt/sources.list.d/{{ item }}" + state: absent + loop: + - cassandra.list + - icinga.list + - postgres.list + - salt-stack.list + - yarn.list + + - name: Install nginx, certbot, and python3-certbot-nginx + apt: + name: + - nginx + - certbot + - python3-certbot-nginx + state: present + update_cache: yes + + - name: Create web root directory + file: + path: "{{ web_root }}/release/dist" + state: directory + owner: "{{ deploy_user }}" + group: www-data + mode: "0755" + recurse: yes + + - name: Create distributables directory + file: + path: "{{ web_root }}/release/dist/distributables" + state: directory + owner: "{{ deploy_user }}" + group: www-data + mode: "0755" + + - name: Deploy nginx site config (HTTP, pre-certbot) + template: + src: templates/nginx_lynglang.conf.j2 + dest: /etc/nginx/sites-available/{{ domain }} + notify: reload nginx + + - name: Enable nginx site + file: + src: /etc/nginx/sites-available/{{ domain }} + dest: /etc/nginx/sites-enabled/{{ domain }} + state: link + notify: reload nginx + + - name: Disable default nginx site + file: + path: /etc/nginx/sites-enabled/default + state: absent + notify: reload nginx + + - name: Ensure nginx is started + service: + name: nginx + state: started + enabled: yes + + - name: Reload nginx before certbot + meta: flush_handlers + + - name: Obtain SSL certificate via certbot (--nginx plugin) + command: > + certbot --nginx + -d {{ domain }} -d www.{{ domain }} + --non-interactive --agree-tos + --email {{ certbot_email }} + --redirect + args: + creates: /etc/letsencrypt/live/{{ domain }}/fullchain.pem + + handlers: + - name: reload nginx + service: + name: nginx + state: reloaded diff --git a/infra/templates/nginx_lynglang.conf.j2 b/infra/templates/nginx_lynglang.conf.j2 new file mode 100644 index 0000000..4e016ab --- /dev/null +++ b/infra/templates/nginx_lynglang.conf.j2 @@ -0,0 +1,24 @@ +server { + listen 80; + server_name {{ domain }} www.{{ domain }}; + + root {{ web_root }}/release/dist; + index index.html; + + # SPA fallback + location / { + try_files $uri $uri/ /index.html; + } + + # Distributables served directly + location /distributables/ { + try_files $uri =404; + autoindex on; + } + + # Long-lived cache for hashed assets + location ~* \.(js|css|woff2?|ttf|eot|svg|png|jpg|ico)$ { + expires 1y; + add_header Cache-Control "public, immutable"; + } +}