Skip to content

Latest commit

 

History

History
182 lines (128 loc) · 4.05 KB

File metadata and controls

182 lines (128 loc) · 4.05 KB

06 — Bootstrap

Run these steps on both VMs unless noted otherwise. A script version is available at scripts/bootstrap.sh.


1. Initial System Update

sudo apt update && sudo apt upgrade -y
sudo apt install -y \
  curl \
  git \
  htop \
  ufw \
  tmux \
  unattended-upgrades

2. Enable Unattended Security Upgrades

sudo dpkg-reconfigure -plow unattended-upgrades
# Select "Yes" when prompted

This ensures security patches are applied automatically without manual intervention.


3. Configure UFW Firewall

UFW runs at the OS level inside the VM, complementing the OCI NSG.

sudo ufw default deny incoming
sudo ufw default allow outgoing

# Allow SSH (key-based auth only — see step below)
sudo ufw allow 22/tcp

# Allow HTTPS and HTTP (for Caddy ACME challenges)
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp

# Enable UFW
sudo ufw enable

# Verify
sudo ufw status verbose

UFW's port 22 rule is a fallback. The primary SSH restriction is at the OCI NSG level — the SSH ingress rule should be source-restricted to your IP(s) in the NSG, not open to 0.0.0.0/0.


4. Fix OCI iptables Rules

This step is critical. OCI Ubuntu images ship with default iptables rules that include REJECT rules blocking inbound traffic on ports 80 and 443, even after NSG and UFW allow them.

Check current rules:

sudo iptables -L INPUT -n --line-numbers

If you see REJECT or DROP rules for ports 80/443 (often appearing as a blanket REJECT at the end of INPUT chain), fix them:

# Option A: Flush the INPUT chain (nuclear, use carefully)
sudo iptables -F INPUT

# Option B: Delete specific reject rules by line number
# Find the line number from the output above, then:
sudo iptables -D INPUT <line_number>

# Make the change persistent
sudo apt install -y iptables-persistent
sudo netfilter-persistent save

Verify by testing HTTP from your workstation after Caddy is running:

curl -I http://<VM_PUBLIC_IP>
# Should get a redirect, not a connection refused

5. Install Docker Engine

# Remove any old Docker packages
sudo apt remove -y docker docker-engine docker.io containerd runc 2>/dev/null

# Install dependencies
sudo apt install -y ca-certificates curl gnupg lsb-release

# Add Docker GPG key and repository
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg \
  | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo 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 \
  $(lsb_release -cs) stable" \
  | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

# Install Docker Engine + Compose plugin
sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

Verify installation:

docker --version
docker compose version

6. Create a Deploy User

Avoid running containers as root or ubuntu. Create a dedicated non-root user:

sudo useradd -m -s /bin/bash deploy
sudo usermod -aG docker deploy

# Set a password or configure SSH key for this user
sudo passwd deploy
# OR
sudo mkdir -p /home/deploy/.ssh
sudo cp ~/.ssh/authorized_keys /home/deploy/.ssh/
sudo chown -R deploy:deploy /home/deploy/.ssh
sudo chmod 700 /home/deploy/.ssh

Switch to the deploy user for all subsequent operations:

sudo su - deploy

7. Clone the Repository

cd ~
git clone https://github.com/daedalus410/homelab-cloud-stack.git
cd homelab-cloud-stack

8. Verify Docker is Working

docker run --rm hello-world

If this succeeds, Docker is correctly installed and the deploy user has the necessary permissions.


Automated Bootstrap

An automated version of the above is available:

# On each VM, after SSH-ing in:
bash <(curl -fsSL https://raw.githubusercontent.com/daedalus410/homelab-cloud-stack/main/scripts/bootstrap.sh)

Continue Reading

06 — VM1 Stack