NUS Hackers Wiki
NUS Hackers Wiki
  • NUS Hackers Wiki
  • Hackerschool
    • Virtual Machines and Linux
    • Beginners' Guide to the Terminal
      • Introduction to the Terminal
      • Modern Shell Tools
      • Shell Scripting
      • Real World Scripting
      • Resources
    • Self-Hosting: Three Easy Pieces
      • 1. Setting up your server
      • 2. Running Services
      • 3. Monitoring your server
    • Vim
    • Introduction to Zig
      • Language Basics
      • Error Handling
      • Memory Management
      • Working with C
      • Exploring comptime
    • CI/CD with Github Actions
      • Background
      • Basics of Github Actions
        • Target workflow
        • Running unit tests
        • Linting code
        • Deploying to Github Pages
      • Advanced use cases
        • Pollers
        • Github script
        • Executing third-party scripts
        • Reusable workflows
      • Cookbook
    • Lightning Git
      • Git Concepts
      • Getting Started with Git
      • Making your first commit
      • Branching
      • Merge Conflicts
      • Integrating remote repositories
      • Collaborative Workflows
      • Commit Manipulation and Reflog
      • Interactive rebasing
      • filter-repo
  • Orbital
    • JavaScript
      • Browser Developer Tools
      • Getting Started
      • Datatypes
      • Operators and Operations
      • Loops and Conditions
      • Functions
      • Strings
      • Arrays
      • HTML
        • Getting Started
        • Tag Attributes
        • HTML Forms
        • Browser Inspector
      • CSS
        • Selectors
        • Colors in CSS
        • Measurements in CSS
        • The Box Model
        • Adding Styles - Part 1
        • Adding Styles - Part 2
      • Working with the DOM
        • Querying the DOM - Selectors
        • Querying the DOM - Element Attributes
        • Querying the DOM - Element Styles
        • Events with JS and HTML
        • Exercise: Click Counter
        • Editing the DOM
        • Fetch Requests
        • Exercise: The NUSMods API
    • React
      • Setup
      • State
    • React Native
      • Setup
      • Intro to JSX
      • Basic Syntax
      • Handling UI
      • Props
      • State Management
    • Git
      • Setup
      • Command Glossary
      • Fundamental Concepts
        • Getting Started
        • Integrating Remote Repositories
        • Branching
        • Merge Conflicts
      • Collaborative Workflows
        • Fork and PR Workflow
        • Branch and PR Workflow
      • Advanced Concepts
        • Ignoring Files
        • Commit Message Conventions
        • Github Collaborators
        • CI/CD with Github Actions
        • Advanced Git Commands
      • FAQ
    • Telegram Bot
      • Creating a TeleBot
      • API Calls
      • Telebot Basics
      • Integrating API's
    • Relational Database
      • Database Overview
      • Database Design
      • Entity Relationship Diagram
      • SQL Basics & PostgreSQL
    • TypeScript
      • Types and Interfaces
      • Utility Types
      • Typing Component Props, Events, and Hooks
      • Why You Should Avoid Using any (and What to Do Instead)
      • TypeScript Tricks You’ll Use All the Time in React
Powered by GitBook
On this page
  • Running Services
  • Hosting a web page with nginx
  • Running a cron job that sends us a message via telegram
  • Syncing your files with Syncthing
  • Hosting your own VPN over your own server
Edit on GitHub
Export as PDF
  1. Hackerschool
  2. Self-Hosting: Three Easy Pieces

2. Running Services

Previous1. Setting up your serverNext3. Monitoring your server

Last updated 6 months ago

Before we start installing and running our services, it is good to keep our system up to date. To update our system, do:

sudo apt-get update && sudo apt-get upgrade

Running Services

Hosting a web page with nginx

  • nginx is a great web server for these things, but you can pick whatever you want, or are more familiar with

  • On Ubuntu, this is pretty simple: apt install nginx

  • Enable it and start it: sudo systemctl enable nginx, sudo systemctl start nginx

  • Open up your browser and head to — you should see a page there

  • Edit files in /var/www/html/..., etc: try replacing index.html? with "hello world"

  • check again

Here's a pretty cool, simple website. Let's try and deploy it:

Running a cron job that sends us a message via telegram

One of the best things about a server is that it's meant to run 24/7, something that our laptops or desktops aren't great at doing. This means it's really good at running things constantly at a scheduled interval. To do such a thing, we'll use something known as cron jobs.

  • Cron is a scheduling daemon that executes tasks at specified intervals.

  • These tasks are called cron jobs and are mostly used to automate system maintenance or administration.

Cron jobs

The crontab command allows you to install, view , or open a crontab file for editing:

  • crontab -e - Edit crontab file, or create one if it doesn’t already exist.

  • crontab -l - Display crontab file contents.

  • crontab -r - Remove your current crontab file.

  • crontab -i - Remove your current crontab file with a prompt before removal.

  • crontab -u - Edit other user crontab file. This option requires system administrator privileges.

Cron Syntax

  • Syntax:
    * * * * * command(s)
    - - - - -
    | | | | |
    | | | | ----- Day of week (0 - 7) (Sun=0 or 7)
    | | | ------- Month (1 - 12)
    | | --------- Day of month (1 - 31)
    | ----------- Hour (0 - 23)
    ------------- Minute (0 - 59)
    
    Example:
    */5 * * * * /path/to/script.sh # Run every 5 minutes

Creating a telegram bot with cronjob

We have an API that gives us the 24 hour weather forecast in Singapore. We want to:

  • Check this forecast every morning

  • If it's about to rain, send us an alert. For simplicity, lets send a telegram message!

Here's a bash script that sends a telegram message if it's going to rain that day:

#!/bin/bash

# Replace these with your actual Telegram bot token and chat ID
TELEGRAM_BOT_TOKEN="YOUR_BOT_TOKEN"
CHAT_ID="YOUR_CHAT_ID"
TELEGRAM_API_URL="https://api.telegram.org/bot$TELEGRAM_BOT_TOKEN/sendMessage"

# Replace this with your actual curl command that fetches the JSON weather data
response=$(curl -s "https://api.data.gov.sg/v1/environment/24-hour-weather-forecast")

# Define an array of rain-related keywords
rain_keywords=("Rain" "Showers" "Thundery Showers" "Heavy Thundery Showers")

# Extract the general weather forecast without jq
general_forecast=$(echo "$response" | grep -o '"forecast":"[^"]*' | sed 's/"forecast":"//')

# Initialize a flag to check if rain is found
rain_found=0

# Check for rain-related keywords in the general forecast
for keyword in "${rain_keywords[@]}"; do
    if [[ "$general_forecast" == *"$keyword"* ]]; then
        rain_found=1
        break
    fi
done

# If rain is detected, send an alert
if [ "$rain_found" -eq 1 ]; then
    message="Weather Alert: Rain expected! General forecast is '$general_forecast'. Stay prepared!"
    
    # Send the message to the Telegram bot
    curl -s -X POST $TELEGRAM_API_URL \
        -d chat_id=$CHAT_ID \
        -d text="$message" > /dev/null

    echo "Alert sent: $message"
else
    echo "No rain expected. General forecast is '$general_forecast'."
fi
  • To get a telegram bot id, just go to @BotFather, and create a new bot, enter the token we receive inside

  • To get your chat id, just go to @getmyid_bot and copy your chat id there

  • You'll need to start a chat with your bot first, go to your bot and do '/start' before you try running the script

Here are some more local APIs you can try to automate/script!

These should give you a very simple idea of hosting some services on our own servers. There's so much more we can't cover in a 2 hour workshop but here are some resources if you're fast/want to learn more!

Syncing your files with Syncthing

Syncthing is an open-source file synchronization tool that allows you to effortlessly synchronize files across multiple devices. It runs on various platforms, providing a seamless experience for syncing files securely and privately over local networks or the internet.

Hosting your own VPN over your own server

There are plenty of reasons why you should . We can set up our own to ensure that we can browse the internet securely or hide our IP addresses by routing our network traffic through our servers instead.

https://crontab.guru/
never use or trust public VPN providers
http://host/
http://host/
LogoHow to Install Syncthing on Ubuntu 22.04Atlantic.Net
LogoUbuntu 20.04 set up WireGuard VPN servernixCraft
https://github.com/jackveiga/singapore-apis
https://github.com/PaulineLabaisse/Motherfuckingwebsite/blob/master/Motherfuckerwebsite.html

<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    
    <!-- FOR THE CURIOUS: This site was made by @thebarrytone. Don't tell my mom. -->
    
    <title>Motherfucking Website</title>
</head>

<body>
    <header>
        <h1>This is a motherfucking website.</h1>
        <aside>And it's fucking perfect.</aside>
    </header>
        
        <h2>Seriously, what the fuck else do you want?</h2>
        
        <p>You probably build websites and think your shit is special. You think your 13 megabyte parallax-ative home page is going to get you some fucking Awwward banner you can glue to the top corner of your site. You think your 40-pound jQuery file and 83 polyfills give IE7 a boner because it finally has box-shadow. Wrong, motherfucker. Let me describe your perfect-ass website:</p>
        
        <ul>
            <li>Shit's lightweight and loads fast</li>
            <li>Fits on all your shitty screens</li>
            <li>Looks the same in all your shitty browsers</li>
            <li>The motherfucker's accessible to every asshole that visits your site</li>
            <li>Shit's legible and gets your fucking point across (if you had one instead of just 5mb pics of hipsters drinking coffee)</li>
        </ul>
        
        <h3>Well guess what, motherfucker:</h3>
        
        <p>You. Are. Over-designing. Look at this shit. It's a motherfucking website. Why the fuck do you need to animate a fucking trendy-ass banner flag when I hover over that useless piece of shit? You spent hours on it and added 80 kilobytes to your fucking site, and some motherfucker jabbing at it on their iPad with fat sausage fingers will never see that shit. Not to mention blind people will never see that shit, but they don't see any of your shitty shit.</p>
        
        <p>You never knew it, but this is your perfect website. Here's why.</p>
        
        <h2>It's fucking lightweight</h2>
        
        <p>This entire page weighs less than the gradient-meshed facebook logo on your fucking Wordpress site. Did you seriously load 100kb of jQuery UI just so you could animate the fucking background color of a div? You loaded all 7 fontfaces of a shitty webfont just so you could say "Hi." at 100px height at the beginning of your site? You piece of shit.</p>
        
        <h2>It's responsive</h2>
        
        <p>You dumbass. You thought you needed media queries to be responsive, but no. Responsive means that it responds to whatever motherfucking screensize it's viewed on. This site doesn't care if you're on an iMac or a motherfucking Tamagotchi.</p>
        
        <h2>It fucking works</h2>
        
        <p>Look at this shit. You can read it ... that is, if you can read, motherfucker. It makes sense. It has motherfucking hierarchy. It's using HTML5 tags so you and your bitch-ass browser know what the fuck's in this fucking site. That's semantics, motherfucker.</p>
        
        <p>It has content on the fucking screen. Your site has three bylines and link to your dribbble account, but you spread it over 7 full screens and make me click some bobbing button to show me how cool the jQuery ScrollTo plugin is.</p>
        
        <p>Cross-browser compatibility? Load this motherfucker in IE6. I fucking dare you.</p>
        
        <h2>This is a website. Look at it.  You've never seen one before.</h2>
        
        <p>Like the man who's never grown out his beard has no idea what his true natural state is, you have no fucking idea what a website is. All you have ever seen are shitty skeuomorphic bastardizations of what should be text communicating a fucking message. This is a real, naked website. Look at it. It's fucking beautiful.</p>
        
        <h3>Yes, this is fucking satire, you fuck</h3>
        
        <p>I'm not actually saying your shitty site should look like this. What I'm saying is that all the problems we have with websites are <strong>ones we create ourselves</strong>. Websites aren't broken by default, they are functional, high-performing, and accessible. You break them. You son-of-a-bitch.</p>
        
        <blockquote cite="https://www.vitsoe.com/us/about/good-design">"Good design is as little design as possible."<br>
            - some German motherfucker
        </blockquote>
    
    <hr>
    
    <h2>Epilogue</h2>
    <p>From the philosophies expressed (poorly) above, <a href="http://txti.es">txti</a> was created. You should try it today to make your own motherfucking websites.</p>
    
    <!-- yes, I know...wanna fight about it? -->
    <script>
      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
      (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
      m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
      })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
    
      ga('create', 'UA-45956659-1', 'motherfuckingwebsite.com');
      ga('send', 'pageview');
    </script>
    
</body>