Linux Patterns
systemd Service Unit
[Unit]
Description=MyApp Service
After=network.target postgresql.service
Requires=postgresql.service
[Service]
Type=simple
User=myapp
Group=myapp
WorkingDirectory=/opt/myapp
ExecStart=/opt/myapp/bin/myapp --config /etc/myapp/config.yaml
ExecReload=/bin/kill -HUP $MAINPID
Restart=on-failure
RestartSec=5s
StandardOutput=journal
StandardError=journal
SyslogIdentifier=myapp
Environment=LOG_LEVEL=info
EnvironmentFile=-/etc/myapp/env
# Security hardening
NoNewPrivileges=yes
PrivateTmp=yes
ProtectSystem=full
ReadOnlyPaths=/
[Install]
WantedBy=multi-user.target
systemctl daemon-reload
systemctl enable --now myapp
journalctl -u myapp -f --since "10 min ago"
cron (with flock to prevent overlap)
# /etc/cron.d/myapp
# Run report every hour, skip if previous run still active
0 * * * * myapp /usr/bin/flock -n /tmp/myapp-report.lock /opt/myapp/bin/report.sh >> /var/log/myapp/report.log 2>&1
Performance Diagnostics
# CPU — who's using it
top -b -n 1 -o %CPU | head -20
pidstat -u 1 5 # per-process CPU usage over 5s
# Memory
free -h
vmstat 1 5 # memory, swap, I/O
cat /proc/meminfo | grep -E "MemAvailable|Cached|Buffers"
# Disk I/O
iostat -xz 1 5 # per-device utilization
iotop -o # which process is doing I/O
# Network
ss -tunapl # all TCP/UDP with process info
netstat -s | grep -E "failed|error|reset"
sar -n DEV 1 5 # per-interface throughput
# Load average context
uptime # 1/5/15 min load averages
nproc # number of CPU cores (load > nproc = overloaded)
File Descriptor and Connection Limits
# Check current limits
ulimit -n
cat /proc/sys/fs/file-max
# Increase for a process (in systemd unit)
[Service]
LimitNOFILE=65536
# System-wide (sysctl)
sysctl -w fs.file-max=2097152
echo "fs.file-max = 2097152" >> /etc/sysctl.d/99-myapp.conf
sysctl -p /etc/sysctl.d/99-myapp.conf
Security Hardening
# UFW firewall
ufw default deny incoming
ufw default allow outgoing
ufw allow 22/tcp comment 'SSH'
ufw allow 443/tcp comment 'HTTPS'
ufw enable
# fail2ban for SSH
apt install fail2ban
cat > /etc/fail2ban/jail.local << 'EOF'
[sshd]
enabled = true
port = 22
maxretry = 5
bantime = 3600
findtime = 600
EOF
systemctl enable --now fail2ban
# Disable root SSH login
sed -i 's/^PermitRootLogin yes/PermitRootLogin no/' /etc/ssh/sshd_config
sed -i 's/^#PasswordAuthentication yes/PasswordAuthentication no/' /etc/ssh/sshd_config
systemctl reload sshd
Log Rotation
# /etc/logrotate.d/myapp
/var/log/myapp/*.log {
daily
rotate 14
compress
delaycompress
missingok
notifempty
postrotate
systemctl kill -s HUP myapp.service
endscript
}
Key Rules
- Use
journalctlfor systemd services — not raw log files ssreplacesnetstaton modern Linux (faster, same syntax)- Always set resource limits in unit files:
LimitNOFILE,MemoryMax nohupandscreen/tmuxfor long-running manual tasks; prefer systemd for daemons- Run
logwatchorlynisweekly for security audit baseline