#!/bin/bash # Prepare Ubuntu 22.04 VM for Mailcow — run as root on 10.100.1.28 # Set KEEP_DESKTOP=1 to skip desktop purge (Proxmox console UI) set -euo pipefail export DEBIAN_FRONTEND=noninteractive KEEP_DESKTOP="${KEEP_DESKTOP:-0}" log() { echo "[$(date +%H:%M:%S)] $*"; } log "=== 1. Hostname mailserver ===" hostnamectl set-hostname mailserver grep -q '^127.0.1.1' /etc/hosts && sed -i 's/^127.0.1.1.*/127.0.1.1 mailserver sync.geonet.co.id/' /etc/hosts || \ echo '127.0.1.1 mailserver sync.geonet.co.id' >> /etc/hosts grep -q '10.100.1.28' /etc/hosts || echo '10.100.1.28 mailserver sync.geonet.co.id' >> /etc/hosts log "=== 2. Kernel / sysctl (Mailcow) ===" grep -q 'vm.max_map_count' /etc/sysctl.conf || echo 'vm.max_map_count = 262144' >> /etc/sysctl.conf sysctl -w vm.max_map_count=262144 log "=== 3. Disk sdb -> /data/mailcow/vmail ===" if ! blkid /dev/sdb1 &>/dev/null; then parted -s /dev/sdb mklabel gpt parted -s /dev/sdb mkpart primary ext4 0% 100% sleep 2 mkfs.ext4 -F -L mailcow-vmail /dev/sdb1 fi mkdir -p /data/mailcow/vmail UUID=$(blkid -s UUID -o value /dev/sdb1) grep -q "$UUID" /etc/fstab || echo "UUID=$UUID /data/mailcow/vmail ext4 defaults,noatime 0 2" >> /etc/fstab mount -a chown root:root /data/mailcow/vmail chmod 755 /data/mailcow log "=== 4. Swap 4G ===" if [ "$(swapon --show=SIZE --noheadings -n 1 2>/dev/null | tr -d 'G')" != "4" ]; then swapoff -a 2>/dev/null || true rm -f /swapfile fallocate -l 4G /swapfile || dd if=/dev/zero of=/swapfile bs=1M count=4096 chmod 600 /swapfile mkswap /swapfile swapon /swapfile grep -q '/swapfile' /etc/fstab || echo '/swapfile none swap sw 0 0' >> /etc/fstab fi systemctl stop unattended-upgrades 2>/dev/null || true systemctl disable unattended-upgrades 2>/dev/null || true log "=== 5. Desktop (optional) ===" if [ "$KEEP_DESKTOP" = "1" ]; then log "KEEP_DESKTOP=1 — skip purge, keep ubuntu-desktop for Proxmox console" else systemctl stop gdm 2>/dev/null || systemctl stop gdm3 2>/dev/null || true systemctl disable gdm 2>/dev/null || systemctl disable gdm3 2>/dev/null || true log "Desktop purge enabled — set KEEP_DESKTOP=1 to retain GNOME" fi log "=== 6. Stop unneeded services ===" systemctl stop cups cups-browsed avahi-daemon ModemManager bluetooth 2>/dev/null || true systemctl disable cups cups-browsed avahi-daemon ModemManager bluetooth 2>/dev/null || true log "=== 6. Remove snap packages ===" if command -v snap >/dev/null; then for s in $(snap list 2>/dev/null | awk 'NR>1 {print $1}'); do snap remove "$s" 2>/dev/null || true done fi log "=== 7. Purge desktop (skip if KEEP_DESKTOP=1) ===" if [ "$KEEP_DESKTOP" != "1" ]; then apt-get update -qq apt-get purge -y \ ubuntu-desktop ubuntu-desktop-minimal ubuntu-session \ gdm3 gnome-shell gnome-shell-common \ 'gnome-shell-extension-*' yaru-theme-gnome-shell \ snapd gir1.2-snapd-1 libsnapd-glib1 \ cups cups-browsed cups-client cups-common \ avahi-daemon avahi-autoipd \ ModemManager bluetooth bluez \ packagekit packagekit-tools \ libreoffice* thunderbird* rhythmbox* totem* \ 2>/dev/null || true apt-get autoremove -y --purge apt-get autoclean -y else log "Desktop retained for Proxmox console" fi log "=== 8. Base tools for Mailcow ===" apt-get install -y \ ca-certificates curl gnupg lsb-release \ git rsync unzip jq \ apt-transport-https software-properties-common \ net-tools dnsutils log "=== 9. Docker (official) ===" if ! command -v docker >/dev/null; then install -m 0755 -d /etc/apt/keyrings curl -fsSL https://download.docker.com/linux/ubuntu/gpg | gpg --dearmor -o /etc/apt/keyrings/docker.gpg chmod a+r /etc/apt/keyrings/docker.gpg echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu $(. /etc/os-release && echo "$VERSION_CODENAME") stable" \ > /etc/apt/sources.list.d/docker.list apt-get update -qq apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin systemctl enable --now docker fi log "=== 10. Verify ===" echo "HOSTNAME=$(hostname)" echo "DOCKER=$(docker --version)" echo "COMPOSE=$(docker compose version)" docker run --rm hello-world 2>&1 | tail -3 echo "DISK_VMAIL=$(df -h /data/mailcow/vmail | tail -1)" echo "RAM=$(free -h | awk '/^Mem:/{print $2}')" echo "SWAP=$(free -h | awk '/^Swap:/{print $2}')" echo "MAX_MAP=$(sysctl -n vm.max_map_count)" echo "PREPARE_OK"