Current section
Files
Jump to
Current section
Files
priv/debian-phoenix-cloudinit.yaml
#cloud-config
# Debian 13 Trixie Phoenix/Elixir Web Server Cloud-init
# Optimized for WebSocket and high-concurrency TCP connections
# 1. Install basic tools
packages:
- curl
- wget
- ca-certificates
- apt-transport-https
- gnupg
- fail2ban
- ufw
# 2. Write installation scripts and config files
write_files:
# Docker installation script
- path: /root/install-docker.sh
content: |
#!/bin/bash
set -e
echo "Starting Docker installation..."
# Install prerequisites
apt-get update
apt-get install -y ca-certificates curl gnupg lsb-release
# Add Docker GPG key
install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/debian/gpg | gpg --dearmor -o /etc/apt/keyrings/docker.gpg
chmod a+r /etc/apt/keyrings/docker.gpg
# Add Docker repository (Debian 13 Trixie)
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/debian trixie stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null
# Install Docker
apt-get update
apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
# Enable and start Docker
systemctl enable --now docker
echo "Docker installation completed"
permissions: '0755'
owner: root:root
# Kernel parameter tuning for Phoenix/WebSocket
- path: /etc/sysctl.d/99-phoenix-optimize.conf
content: |
# ============================================================================
# Phoenix/Elixir Web Server Kernel Parameter Tuning
# Optimized for WebSocket and high-concurrency TCP connections
# ============================================================================
# ============================================================================
# 1. File Descriptor Limits (Critical for WebSocket)
# ============================================================================
# Each WebSocket connection uses one file descriptor.
# With LiveView, connections stay open for long periods.
# Increase system-wide limit for high concurrent connections.
fs.file-max = 524288
# ============================================================================
# 2. TCP Connection Tuning
# ============================================================================
# somaxconn: TCP listen queue length. Default 128 is too small.
# Phoenix/Cowboy uses this for incoming connections.
net.core.somaxconn = 65535
# tcp_max_syn_backlog: SYN queue for burst connections.
# Increase for servers with many simultaneous new connections.
net.ipv4.tcp_max_syn_backlog = 16384
# tcp_fin_timeout: Reduce TIME_WAIT socket hold time.
# Helps free resources faster for high-throughput servers.
net.ipv4.tcp_fin_timeout = 15
# tcp_tw_reuse: Reuse TIME_WAIT sockets for new connections.
net.ipv4.tcp_tw_reuse = 1
# tcp_max_tw_buckets: Limit TIME_WAIT socket count.
net.ipv4.tcp_max_tw_buckets = 200000
# tcp_keepalive: Detect dead connections faster (important for WebSocket).
net.ipv4.tcp_keepalive_time = 300
net.ipv4.tcp_keepalive_intvl = 30
net.ipv4.tcp_keepalive_probes = 5
# ============================================================================
# 3. Socket Buffer Tuning
# ============================================================================
# Increase socket buffer sizes for better throughput.
net.core.rmem_default = 262144
net.core.rmem_max = 16777216
net.core.wmem_default = 262144
net.core.wmem_max = 16777216
# TCP buffer sizes (min, default, max).
# Format: min, default, max
net.ipv4.tcp_rmem = 4096 87380 16777216
net.ipv4.tcp_wmem = 4096 65536 16777216
# ============================================================================
# 4. Connection Tracking (Optional - only if needed)
# ============================================================================
# Increase conntrack table size if using any proxy/forwarding.
# Not typically needed for pure Phoenix apps.
net.netfilter.nf_conntrack_max = 262144
net.netfilter.nf_conntrack_hashsize = 65536
# ============================================================================
# 5. Security: Disable ICMP Redirects
# ============================================================================
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.default.accept_redirects = 0
net.ipv6.conf.all.accept_redirects = 0
net.ipv6.conf.default.accept_redirects = 0
# ============================================================================
# 6. Security: Disable Source Routing
# ============================================================================
net.ipv4.conf.all.send_redirects = 0
net.ipv4.conf.default.send_redirects = 0
# ============================================================================
# 7. IP Local Port Range
# ============================================================================
# Increase ephemeral port range for more outgoing connections.
# Format: low, high
net.ipv4.ip_local_port_range = 10240 65535
owner: root:root
permissions: '0644'
# Increase system file descriptor limits
- path: /etc/security/limits.d/phoenix.conf
content: |
# ============================================================================
# Increase file descriptor limits for Phoenix/Elixir
# Each WebSocket connection uses ~1 FD
# ============================================================================
# Soft limit for max open files
* soft nofile 524288
# Hard limit for max open files
* hard nofile 524288
# For root user (needed for some system operations)
root soft nofile 524288
root hard nofile 524288
# Max processes (Elixir uses many processes)
* soft nproc 65535
* hard nproc 65535
owner: root:root
permissions: '0644'
# Phoenix systemd service limits
- path: /etc/systemd/system/phoenix.service.d/limits.conf
content: |
[Service]
# Increase file descriptor limit for Phoenix application
LimitNOFILE=524288
# Increase max processes (Elixir lightweight processes)
LimitNPROC=65535
owner: root:root
permissions: '0644'
# SSH port change script
- path: /root/ssh-port-change.sh
content: |
#!/bin/bash
sed -i 's/^#Port 22/Port 22022/' /etc/ssh/sshd_config
sed -i 's/^Port 22/Port 22022/' /etc/ssh/sshd_config
# Only listen on new port
echo "ListenAddress 0.0.0.0" >> /etc/ssh/sshd_config
systemctl restart sshd
permissions: '0755'
owner: root:root
# Weekly auto-update script
- path: /root/auto-update.sh
content: |
#!/bin/bash
# Weekly auto-update script for security patches
echo "========== $(date) Starting system update ==========" >> /var/log/auto-update.log 2>&1
apt-get update >> /var/log/auto-update.log 2>&1
apt-get upgrade -y >> /var/log/auto-update.log 2>&1
echo "========== $(date) Update completed ==========" >> /var/log/auto-update.log 2>&1
permissions: '0755'
owner: root:root
# 3. Commands to run on first boot
runcmd:
# Enable and configure UFW firewall
- ufw --force reset
- ufw default deny incoming
- ufw default allow outgoing
- ufw allow 22022/tcp comment 'SSH'
- ufw allow 443/tcp comment 'HTTPS'
- ufw allow 80/tcp comment 'HTTP'
- ufw --force enable
# Enable fail2ban
- systemctl enable --now fail2ban
# Change SSH port to 22022
- /root/ssh-port-change.sh
# Apply kernel parameters
- sysctl -p /etc/sysctl.d/99-phoenix-optimize.conf
# Reload systemd to pick up new limits config
- systemctl daemon-reload
# Install Docker
- /root/install-docker.sh
# Set script permissions
- chmod +x /root/auto-update.sh
# Add cron job: Every Monday at 2:00 AM
- |
echo "0 2 * * 1 /root/auto-update.sh" >> /etc/crontab
# Enable docker service
- systemctl enable docker || true
# 4. Timezone
timezone: Asia/Singapore