Files
bitrix-vps-infra/README.md
T

5.1 KiB

============================================================

bitrix-vps-infra — native Bitrix stack on Ubuntu 24.04 VPS

nginx (static+TLS) → php-fpm → Percona MySQL (unix socket)

+ memcached x2 + fail2ban + CrowdSec + ufw + backups

#docker analogue of paskal/bitrix.infra, without containers.

============================================================

Services

Service What Where
nginx front, static files, urlrewrite, rate-limit zones /etc/nginx/
php8.4-fpm Bitrix runtime, pool bitrix /etc/php/8.4/fpm/pool.d/bitrix.conf
Percona MySQL socket-only (localhost), buffer pool 4G /etc/mysql/conf.d/99-bitrix.cnf
memcached x2 cache 127.0.0.1:11211, sessions 11212 systemd units memcached-cache/-sessions
fail2ban sshd + nginx-http-auth jails /etc/fail2ban/jail.local
CrowdSec parses nginx combined logs + sshd journal /etc/crowdsec/acquis.yaml
cron Bitrix agents CLI, exchange, nightly backup /etc/cron.d/bitrix
ufw OpenSSH/80/443 /etc/ufw/

Quickstart (fresh Ubuntu 24.04)

apt update && apt install -y git
git clone <this repo> /opt/bitrix-vps-infra && cd /opt/bitrix-vps-infra

# 1) edit variables at top of install.sh (DOMAIN first!)
nano scripts/../install.sh          # DOMAIN=..., FPM_MAX_CHILDREN=30, TZ

sudo ./install.sh

# creds printed and saved to /root/bitrix-install-creds.txt (chmod 600)
cat /root/bitrix-install-creds.txt

Migrate site from old server

# on OLD server: dump db
mysqldump --single-transaction --routines --triggers sitemanager | gzip > sitemanager.sql.gz

# copy content
rsync -avz /home/bitrix/www/bitrix newvps:/home/bitrix/www/
rsync -avz /home/bitrix/www/{local,upload} newvps:/home/bitrix/www/

# import on NEW server
gunzip < sitemanager.sql.gz | mysql sitemanager
./scripts/fix-rights.sh /home/bitrix/www

# bitrix app-configs: take examples, insert DB pass from creds file
cp config/bitrix-app/dbconn.php.example /home/bitrix/www/bitrix/php_interface/dbconn.php
cp config/bitrix-app/settings_extra.php.example /home/bitrix/www/bitrix/.settings_extra.php
# then edit .settings.php: host=localhost, add 'session' block from settings_extra comment

After that:

apt-get install -y certbot python3-certbot-nginx
DOMAIN=$(grep '^DOMAIN=' /root/bitrix-install-creds.txt | cut -d= -f2)
certbot --nginx -d "$DOMAIN" -d "www.$DOMAIN"   # upgrades vhost to TLS + redirect
systemctl reload nginx

Verify checklist

curl -I http://DOMAIN                       # 200 or 301
mysqladmin status                           # socket alive, TCP not listening:
ss -tlnp | grep -E '3306|33060'             # expect EMPTY output
free -m                                     # swap ~0 used, available >3G
php-fpm8.4 -tt                              # pool syntax ok
tail -f /var/log/php/bitrix-slow.log        # requests >5s land here
fail2ban-client status sshd                 # jail active
cscli metrics                               # crowdsec parsing access.log
/usr/bin/php -d memory_limit=1024M -f /home/bitrix/www/bitrix/modules/main/tools/cron_events.php
                                            # agents run manually without error

Site smoke: main page → catalog section → cart → admin login. Check exchange via admin or manual flock command from /etc/cron.d/bitrix.

Tuning knobs

Knob File Default When change
pm.max_children fpm pool 30 OOM/slow under peak → raise if RAM free; 503 → lower concurrency
innodb_buffer_pool_size mysql cnf 4G sized for 12GB box
memcached cache MB unit file 1024 raise on cache churn
limit_req rate nginx.conf zone 10 r/s enforce per-location when needed
backup retention backup.sh 14 days disk budget

Restore from backup

gunzip < /var/backups/bitrix/db/<ts>_sitemanager.sql.gz | mysql sitemanager
cd /home/bitrix/www
tar xzf /var/backups/bitrix/code/<ts>_site.tar.gz --strip-components=0 # replaces webroot files except upload/
./scripts/fix-rights.sh

Upload directory is NOT in backups by design (bulky). Sync it separately (e.g. weekly rsync -a /home/bitrix/www/upload /var/backups/bitrix/upload) if size permits.

Notes / trade-offs taken deliberately ("no overskill")

  • No HTTP/3/brotli modules — gzip covers 95% benefit; upgrade path documented below.
  • No composite-site nginx layer yet — enable after basic migration proved stable (add $bx_composite_file map + try_files per paskal/bitrix.infra pattern).
  • No Zabbix/Sentry — CrowdSec metrics + slowlog + system journal are the floor; consider netdata later if growth demands.
  • CrowdSec firewall-bouncer replaces host iptables scripting entirely.

Optional upgrades later

apt install libnginx-mod-http-brotli-filter libnginx-mod-http-brotli-static   # brotli
add brotli line into nginx.conf http{} block after gzips.