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.
Prerequisites
Before starting these exercises, ensure you have:
- Access to a remote Linux server (cloud VM, local VM, or test server)
- SSH access to that server
- Your nginx website from Module 7
- Basic familiarity with all commands from this module
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:
- Get your server's connection details (IP address or hostname)
- Connect using SSH with password authentication
- Explore the remote system
- Exit properly
Commands:
# Connect to remote server
ssh username@server-ip-address
# Once connected, explore
pwd
ls -la
whoami
df -h
# Exit
exit
Verification:
- ✓ Successfully connected without errors
- ✓ Saw remote server's command prompt
- ✓ Executed basic commands remotely
- ✓ Exited cleanly
Exercise 2: SSH Key Setup
Goal: Set up passwordless SSH authentication using keys.
Steps:
- Generate a new SSH key pair
- Copy your public key to the remote server
- Test passwordless authentication
- 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:
- ✓ SSH key generated in ~/.ssh/
- ✓ Can connect without entering password
- ✓ SSH config shortcut works
- ✓ Understand public vs private key
Exercise 3: First File Transfer with SCP
Goal: Transfer files between local and remote systems using SCP.
Steps:
- Upload a test file to the server
- Download a file from the server
- Transfer multiple files
- 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:
- ✓ File successfully uploaded to server
- ✓ File successfully downloaded from server
- ✓ Multiple files transferred correctly
- ✓ Directory copied with all contents
Exercise 4: Deploy Your Nginx Website
Goal: Deploy your Module 7 nginx website to a remote server.
Prerequisites:
- Remote server with nginx installed
- Your website from Module 7 ready locally
- Permissions to write to web directory
Steps:
- Prepare your local website
- Install nginx on remote server (if needed)
- Upload website files using SCP
- Set correct permissions
- 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:
- ✓ Nginx installed and running on remote server
- ✓ Website files uploaded successfully
- ✓ Correct file permissions set
- ✓ Website accessible via browser
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:
- Make changes to your local website
- Test rsync with dry-run
- Sync changes to server
- 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:
- Shows what will change (dry-run)
- Asks for confirmation
- Syncs the files
- 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:
- ✓ Dry-run showed expected changes
- ✓ Rsync only transferred modified files
- ✓ Website updated successfully
- ✓ Deployment script created and works
Exercise 6: Backup and Recovery
Goal: Create backups of your remote website and restore them.
Steps:
- Create a backup script
- Download website backup
- Simulate data loss
- 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:
- ✓ Backup script created and executable
- ✓ Website backed up with dated directory
- ✓ Successfully restored from backup
- ✓ Website functional after restore
Exercise 7: Advanced Rsync Operations
Goal: Master advanced rsync features for efficient deployments.
Steps:
- Use --exclude to skip files
- Use --delete for mirror sync
- Handle large files efficiently
- 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:
- Excludes development files
- Shows progress
- Tests with dry-run first
- Creates a backup before deploying
- Restarts nginx after deployment
Verification:
- ✓ Excluded unwanted files from sync
- ✓ Successfully used --delete (after dry-run)
- ✓ Handled large file transfers
- ✓ Created reusable exclude patterns
Exercise 8: Managing Multiple Servers
Goal: Deploy and manage websites across multiple servers.
Steps:
- Configure SSH for multiple servers
- Deploy to all servers
- Check status on all servers
- 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:
- ✓ SSH config set up for multiple servers
- ✓ Website deployed to all servers
- ✓ Status checked across all servers
- ✓ Multi-server deployment script works
Exercise 9: Log Management
Goal: Download and analyze log files from remote servers.
Steps:
- Download nginx access logs
- Download error logs
- Analyze logs locally
- 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:
- ✓ Logs downloaded successfully
- ✓ Local log analysis performed
- ✓ Log collection script created
- ✓ Can identify issues in logs
Exercise 10: Complete Workflow
Goal: Create a complete professional deployment workflow.
Your Mission:
Build a comprehensive deployment system that includes:
- Pre-deployment backup
- Dry-run and confirmation
- Efficient rsync sync
- Post-deployment testing
- Log collection
- 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:
- ✓ Complete deployment script created
- ✓ Backup created before deployment
- ✓ Dry-run tested successfully
- ✓ Deployment completed and verified
- ✓ Rollback works if needed
- ✓ Script is professional and reusable
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
- Test basic SSH first:
ssh myserver - Use verbose mode:
ssh -v myserver - Check SSH keys:
ssh-add -l
Permission Issues
- Upload to home directory first, then sudo copy
- Check file ownership:
ls -la /var/www/html/ - Fix ownership:
sudo chown -R www-data:www-data /var/www/html/
Rsync Issues
- Always test with
-n(dry-run) first - Use
-vfor verbose output - Check trailing slashes on paths
Key Takeaways
- SSH keys make authentication secure and convenient
- SCP is simple for one-time file transfers
- Rsync is efficient for synchronizing directories
- Always backup before deploying
- Test with dry-run before making changes
- Scripts automate repetitive tasks
- Professional workflows include testing and rollback
Congratulations!
You've completed Module 8 and mastered remote access and file transfer! You can now:
- ✓ Connect securely to remote Linux systems
- ✓ Set up passwordless authentication
- ✓ Transfer files efficiently between systems
- ✓ Deploy and manage websites remotely
- ✓ Create professional deployment workflows
- ✓ Handle backups and recovery
Linux 101