Lesson 8.5: Practical Exercises

Time to put everything together! These hands-on exercises will solidify your remote access skills by deploying and managing real websites on remote servers.

Learning by Doing: These exercises progress from basic to advanced. Complete them in order for the best learning experience. Each builds on the previous one.

Prerequisites

Before starting these exercises, ensure you have:

No Remote Server? You can practice using localhost! Just SSH to your own machine: ssh username@localhost. It's not quite the same, but you'll learn the commands.

Exercise 1: First SSH Connection

Goal: Successfully connect to a remote server using SSH.

Steps:

  1. Get your server's connection details (IP address or hostname)
  2. Connect using SSH with password authentication
  3. Explore the remote system
  4. Exit properly

Commands:

# Connect to remote server
ssh username@server-ip-address

# Once connected, explore
pwd
ls -la
whoami
df -h

# Exit
exit

Verification:

Exercise 2: SSH Key Setup

Goal: Set up passwordless SSH authentication using keys.

Steps:

  1. Generate a new SSH key pair
  2. Copy your public key to the remote server
  3. Test passwordless authentication
  4. Set up SSH config for convenience

Commands:

# 1. Generate SSH key (if you haven't already)
ssh-keygen -t ed25519 -C "your_email@example.com"
# Press Enter for default location
# Enter a passphrase (recommended)

# 2. Copy key to server
ssh-copy-id username@server-ip-address
# Enter password one last time

# 3. Test passwordless login
ssh username@server-ip-address
# Should connect without password!

# 4. Create SSH config shortcut
nano ~/.ssh/config
# Add:
# Host myserver
#     HostName server-ip-address
#     User username

# 5. Test config shortcut
ssh myserver
# Should work!

Verification:

Exercise 3: First File Transfer with SCP

Goal: Transfer files between local and remote systems using SCP.

Steps:

  1. Upload a test file to the server
  2. Download a file from the server
  3. Transfer multiple files
  4. Copy a directory

Commands:

# 1. Create a test file locally
echo "Hello from $(hostname)" > test.txt

# 2. Upload to remote server
scp test.txt myserver:/home/username/

# 3. Verify it arrived
ssh myserver "cat /home/username/test.txt"

# 4. Download a file
scp myserver:/etc/hostname ./remote-hostname.txt
cat remote-hostname.txt

# 5. Upload multiple files
scp *.txt myserver:/home/username/files/

# 6. Upload a directory
scp -r ~/Documents/projects myserver:/home/username/

Verification:

Exercise 4: Deploy Your Nginx Website

Goal: Deploy your Module 7 nginx website to a remote server.

Prerequisites:

Steps:

  1. Prepare your local website
  2. Install nginx on remote server (if needed)
  3. Upload website files using SCP
  4. Set correct permissions
  5. Start nginx and test

Commands:

# 1. Install nginx on remote server
ssh myserver
sudo apt update
sudo apt install nginx -y
sudo systemctl start nginx
sudo systemctl enable nginx
exit

# 2. Upload website to home directory first (easier permissions)
cd ~/my-website
scp -r * myserver:/home/username/website/

# 3. Move files to web directory (requires sudo on server)
ssh myserver
sudo cp -r /home/username/website/* /var/www/html/
sudo chown -R www-data:www-data /var/www/html/
sudo systemctl restart nginx
exit

# 4. Test your website
curl http://server-ip-address
# Or visit in browser: http://server-ip-address

Verification:

Quick Test: Use curl http://your-server-ip to quickly check if your website is serving correctly without opening a browser.

Exercise 5: Website Updates with Rsync

Goal: Update your deployed website efficiently using rsync.

Steps:

  1. Make changes to your local website
  2. Test rsync with dry-run
  3. Sync changes to server
  4. Verify updates

Commands:

# 1. Make changes to your local website
cd ~/my-website
nano index.html
# Add: 

Updated on $(date)

# 2. Test sync with dry-run (shows what would change) rsync -avzn ~/my-website/ myserver:/home/username/website/ # 3. Actually sync the changes rsync -avz ~/my-website/ myserver:/home/username/website/ # 4. Move to web directory on server ssh myserver "sudo cp -r /home/username/website/* /var/www/html/" # 5. Verify changes curl http://server-ip-address | grep "Updated on"

Challenge:

Create a deployment script that:

  1. Shows what will change (dry-run)
  2. Asks for confirmation
  3. Syncs the files
  4. Restarts nginx
#!/bin/bash
# deploy.sh

echo "=== Website Deployment Script ==="
echo "Checking what will be uploaded..."

rsync -avzn ~/my-website/ myserver:/home/username/website/

read -p "Continue with deployment? (y/n) " -n 1 -r
echo
if [[ $REPLY =~ ^[Yy]$ ]]; then
    echo "Deploying..."
    rsync -avz --progress ~/my-website/ myserver:/home/username/website/
    ssh myserver 'sudo cp -r /home/username/website/* /var/www/html/ && sudo systemctl restart nginx'
    echo "✓ Deployment complete!"
else
    echo "✗ Deployment cancelled"
fi

Verification:

Exercise 6: Backup and Recovery

Goal: Create backups of your remote website and restore them.

Steps:

  1. Create a backup script
  2. Download website backup
  3. Simulate data loss
  4. Restore from backup

Commands:

# 1. Create backup directory locally
mkdir -p ~/backups/website

# 2. Download website backup
rsync -avz myserver:/var/www/html/ ~/backups/website/$(date +%Y-%m-%d)/

# 3. Create backup script
cat > ~/backup-website.sh << 'EOF'
#!/bin/bash
BACKUP_DIR=~/backups/website/$(date +%Y-%m-%d-%H%M)
echo "Backing up website to $BACKUP_DIR..."
rsync -avz --progress myserver:/var/www/html/ "$BACKUP_DIR/"
echo "✓ Backup complete: $BACKUP_DIR"
EOF

chmod +x ~/backup-website.sh

# 4. Run backup script
./backup-website.sh

# 5. Simulate deletion (CAREFUL!)
ssh myserver "sudo rm /var/www/html/index.html"
# Website should now be broken

# 6. Restore from backup
LATEST_BACKUP=$(ls -td ~/backups/website/* | head -1)
rsync -avz "$LATEST_BACKUP/" myserver:/home/username/restore/
ssh myserver "sudo cp -r /home/username/restore/* /var/www/html/"
# Website should work again!

Verification:

Exercise 7: Advanced Rsync Operations

Goal: Master advanced rsync features for efficient deployments.

Steps:

  1. Use --exclude to skip files
  2. Use --delete for mirror sync
  3. Handle large files efficiently
  4. Create exclude patterns file

Commands:

# 1. Exclude development files
rsync -avz \
    --exclude='.git' \
    --exclude='*.log' \
    --exclude='.DS_Store' \
    ~/my-website/ myserver:/home/username/website/

# 2. Create exclude file
cat > ~/rsync-exclude.txt << EOF
.git
node_modules
*.log
.DS_Store
*.tmp
.env
*.swp
EOF

# 3. Use exclude file
rsync -avz --exclude-from=~/rsync-exclude.txt \
    ~/my-website/ myserver:/home/username/website/

# 4. Mirror sync (delete extra files)
# First, dry-run to see what would be deleted!
rsync -avzn --delete ~/my-website/ myserver:/home/username/website/

# If safe, actually delete
rsync -avz --delete ~/my-website/ myserver:/home/username/website/

# 5. Sync with progress for large files
rsync -avzP ~/large-files/ myserver:/home/username/storage/

Challenge:

Create a "production deployment" script that:

Verification:

Exercise 8: Managing Multiple Servers

Goal: Deploy and manage websites across multiple servers.

Steps:

  1. Configure SSH for multiple servers
  2. Deploy to all servers
  3. Check status on all servers
  4. Create a deployment script

Commands:

# 1. Set up SSH config for multiple servers
cat >> ~/.ssh/config << EOF

Host server1
    HostName 192.168.1.100
    User valente

Host server2
    HostName 192.168.1.101
    User valente

Host server3
    HostName 192.168.1.102
    User valente
EOF

# 2. Deploy to all servers
for server in server1 server2 server3; do
    echo "Deploying to $server..."
    rsync -avz ~/my-website/ $server:/home/username/website/
    ssh $server 'sudo cp -r /home/username/website/* /var/www/html/'
done

# 3. Check nginx status on all servers
for server in server1 server2 server3; do
    echo "=== $server ==="
    ssh $server 'sudo systemctl status nginx | grep Active'
done

# 4. Create multi-server deployment script
cat > ~/deploy-all.sh << 'EOF'
#!/bin/bash
SERVERS="server1 server2 server3"

for server in $SERVERS; do
    echo "==== Deploying to $server ===="
    rsync -avz --progress ~/my-website/ $server:/home/username/website/
    ssh $server 'sudo cp -r /home/username/website/* /var/www/html/ && sudo systemctl restart nginx'
    echo "✓ $server deployed"
    echo
done

echo "✓ All servers deployed successfully!"
EOF

chmod +x ~/deploy-all.sh

Verification:

Exercise 9: Log Management

Goal: Download and analyze log files from remote servers.

Steps:

  1. Download nginx access logs
  2. Download error logs
  3. Analyze logs locally
  4. Create automated log collection

Commands:

# 1. Create local logs directory
mkdir -p ~/logs/$(date +%Y-%m-%d)

# 2. Download current logs
scp myserver:/var/log/nginx/access.log ~/logs/$(date +%Y-%m-%d)/
scp myserver:/var/log/nginx/error.log ~/logs/$(date +%Y-%m-%d)/

# 3. Download all nginx logs
scp "myserver:/var/log/nginx/*.log" ~/logs/$(date +%Y-%m-%d)/

# 4. Analyze logs locally
cd ~/logs/$(date +%Y-%m-%d)
# Count requests per IP
cat access.log | awk '{print $1}' | sort | uniq -c | sort -nr

# Find errors
grep "error" error.log

# 5. Create log collection script
cat > ~/collect-logs.sh << 'EOF'
#!/bin/bash
LOG_DIR=~/logs/$(date +%Y-%m-%d)
mkdir -p "$LOG_DIR"

echo "Collecting logs from server..."
rsync -avz myserver:/var/log/nginx/*.log "$LOG_DIR/"
echo "✓ Logs saved to $LOG_DIR"

# Show summary
echo
echo "=== Log Summary ==="
echo "Access log size: $(du -h "$LOG_DIR/access.log" | cut -f1)"
echo "Error log size: $(du -h "$LOG_DIR/error.log" | cut -f1)"
echo "Total requests: $(wc -l < "$LOG_DIR/access.log")"
echo "Errors found: $(grep -c "error" "$LOG_DIR/error.log" 2>/dev/null || echo 0)"
EOF

chmod +x ~/collect-logs.sh

Verification:

Exercise 10: Complete Workflow

Goal: Create a complete professional deployment workflow.

Your Mission:

Build a comprehensive deployment system that includes:

  1. Pre-deployment backup
  2. Dry-run and confirmation
  3. Efficient rsync sync
  4. Post-deployment testing
  5. Log collection
  6. Rollback capability

Sample Complete Script:

#!/bin/bash
# professional-deploy.sh

set -e  # Exit on error

SERVER="myserver"
LOCAL_DIR="$HOME/my-website"
REMOTE_DIR="/home/username/website"
WEB_DIR="/var/www/html"
BACKUP_DIR="$HOME/backups/website"

echo "=== Professional Deployment Script ==="
echo "Server: $SERVER"
echo "Local: $LOCAL_DIR"
echo

# 1. Create backup
echo "Step 1: Creating backup..."
TIMESTAMP=$(date +%Y-%m-%d-%H%M%S)
BACKUP_PATH="$BACKUP_DIR/$TIMESTAMP"
mkdir -p "$BACKUP_PATH"
rsync -avz $SERVER:$WEB_DIR/ "$BACKUP_PATH/"
echo "✓ Backup saved to $BACKUP_PATH"
echo

# 2. Dry run
echo "Step 2: Checking what will change..."
rsync -avzn --delete --exclude-from=rsync-exclude.txt \
    "$LOCAL_DIR/" $SERVER:$REMOTE_DIR/
echo

# 3. Confirmation
read -p "Proceed with deployment? (y/n) " -n 1 -r
echo
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
    echo "✗ Deployment cancelled"
    exit 1
fi

# 4. Deploy
echo "Step 3: Deploying..."
rsync -avz --progress --delete --exclude-from=rsync-exclude.txt \
    "$LOCAL_DIR/" $SERVER:$REMOTE_DIR/

# 5. Move to web directory
echo "Step 4: Installing to web directory..."
ssh $SERVER "sudo cp -r $REMOTE_DIR/* $WEB_DIR/ && sudo systemctl restart nginx"

# 6. Test
echo "Step 5: Testing deployment..."
sleep 2
if curl -s http://$SERVER | grep -q ""; then
    echo "✓ Website is responding correctly"
else
    echo "✗ Website test failed!"
    echo "Rolling back..."
    rsync -avz "$BACKUP_PATH/" $SERVER:$REMOTE_DIR/
    ssh $SERVER "sudo cp -r $REMOTE_DIR/* $WEB_DIR/"
    exit 1
fi

# 7. Summary
echo
echo "=== Deployment Complete ==="
echo "Timestamp: $TIMESTAMP"
echo "Backup: $BACKUP_PATH"
echo "Status: Success"
echo
echo "✓ All steps completed successfully!"

Verification:

Bonus Challenges

Challenge 1: Automated Daily Backups

Create a cron job that backs up your website every day at 2 AM:

# Edit crontab
crontab -e

# Add this line:
0 2 * * * /home/username/backup-website.sh >> /home/username/backup.log 2>&1

Challenge 2: Git Integration

Deploy from a git repository:

# On server
git clone https://github.com/username/my-website.git
cd my-website
sudo cp -r * /var/www/html/

# To update
cd ~/my-website
git pull
sudo cp -r * /var/www/html/

Challenge 3: Zero-Downtime Deployment

Deploy without taking the site offline using a staging directory

Troubleshooting Tips

Connection Issues

Permission Issues

Rsync Issues

Key Takeaways

Congratulations!

You've completed Module 8 and mastered remote access and file transfer! You can now:

Real-World Ready: These skills are exactly what you'll use in professional web development. You're now equipped to manage production servers!