| host-a-temporary-archive | ||
| host-a-website | ||
| README.md | ||
Homelab Workshop Homework
Table of Contents
- Getting Organized
- Clone this repo
- What the hell is Docker?
- Host a website locally with Docker Compose
- Make your website public with a Cloudflare Tunnel
- Run an open source container
- Skip Cloudflare & get noided
- Run your own Temporary Archive
Getting Organized
Some vocab & documentation conventions
- If you ever see guide text inside of these thingies <>, you are not supposed to actually enter those symbols. So below when we say
cd <path/to/folder>we meancd path/to/folder - What's the difference between a folder, a directory, and a repo?
- Folders & Directories: these are the exact same thing, but you might hear the latter a bit more often.
- Repos: repo is short for repository - this is the term we use to describe folders (or directories) which are being tracked by Git. So a folder of code that you're cloning from Github is called a repo.
Command Line
In order to complete this guide, you'll need to use the command line a little bit. You can access this in your Terminal application (called Command Prompt on Windows). It might seem scary, but this glossary of commands includes everything you need to know for the purposes of this guide.
Filesystem navigation
ls: list - shows you the contents of your current working directorycd /path/to/folder: enter a directorypwd: print working directory (tells you where you are)cat path/to/file.txt: concatenate - a way of printing the contents of a file without opening ittouch filename (e.g. 'touch .env'): create a filemkdir directory-name: make a new directoryrm filename: delete a filerm -rf directory-name: delete a folder and all of its contents.nanoopens a pre-installed command line based text editor available on most operating systems.- When editing in nano
ctrl + xto save and exit
- When editing in nano
Docker commands
docker ps: shows all running containersdocker container ls: lists all containers, running or not?docker container stop <name of container>stops running containerdocker prune: remove all non running containers (can sometimes clear up port or container name conflicts, or otherwise clear dangling images)
Docker compose commands
docker compose up: start your containerdocker compose down: stop your containerdocker compose restart: restart your containerdocker compose up -d: start your container & detatch the process from your terminaldocker logs <container name>: shows the logs from inside your container
Software
You'll need to have two key softwares installed: Git and Docker. You'll often use Git to download code online, and you can use Docker to run it.
It's also helpful to have a text editor for writing code. The most commonly used tool is an IDE (integrated development environment) called Visual Studio Code (VSCode for short). This includes a text editor along with an integrated terminal, so you don't need to have a separate command line window. There are tons of options, this is just a popular place to start.
Install Git
You might already have Git installed. Check by typing git --version in your terminal. Installing Git on Windows is generally pretty straightforward, just visit the Windows install page and follow the steps outlined there.
Git is often preinstalled on MacOS, but if it isn't, there are several install approaches on the MacOS Install Page.
- Option 1: install using the MacOS command line package manager called Homebrew, which is also not preinstalled. You can install that here
- Option 2 (easier, but takes up more storage space): install xcode command line tools, which will also install git
By the way: what's the difference between Git and Github?
Git: a version control protocol developed in part by Linus Torvalds (the creator of Linux!) This helps coordinate collaborative software workflows with many contributors, and it also makes it very easy to clone repositories of code, while staying up to date when things change.
Github: a corporate platform for hosting Git repositories which as of a few years ago is owned by Microsoft. There are many other places to host your code that don't sell your data! Our favorite is Codeberg.
The Git protocol is platform agnostic - installing Git allows you to pull repositories from any Git host.
Install Docker
On Windows and Mac, installing Docker's desktop app also preinstalls the other important command line tools, and makes it simple to visualize active containers.
Test that your installation completed successfully by entering
docker run hello-world in your command line. You should receive a message that your installation was completed successfully.
Clone this repo
-
Open your terminal
-
Enter the directory where you want this code to live with
cd <path/to/directory>- Using filepaths can feel clunky at first, but there are some shortcuts.
- On MacOS, if you right click a folder and hold your
Optionkey, it will reveal an option to "Copy As Pathname". - On Windows, right clicking exposes this option without any secret buttons, but unlike sensible operating systems, the slashes go the other way, so your path would be \path\to\directory. You can also right click a directory and select "Open in Terminal."
-
Enter
git clone https://git.secretserver.club/resonant.love/c2i2-homelab-workshop.git -
Type ls, and see that a directory called c2i2-homelab-workshop has been created
-
Enter the directory with
cd c2i2-homelab-workshop- If you don't feel like typing all that, you can use tab completion. Type
c2, then presstab, and it will look for any files beginning with c2, and autocomplete the rest
- If you don't feel like typing all that, you can use tab completion. Type
-
Now that you're inside, type
lsto see what's inside the folder! -
You'll notice we created two subdirectories: host-a-temporary-archive, and host-a-website. Each folder has Docker Compose templates and a few other files you can customize. More on how you'll use them in the coming sections.
But first,
What the hell is Docker?
Docker is a tool that makes it easy to run software in a consistent and isolated way, no matter what kind of computer you have. It does this by using something called containers. You can think of a container as a lightweight, self-contained box that has everything the software needs to run—all its code, files, settings, and even the specific versions of software libraries it relies on.
Docker uses two main concepts: images and containers.
Images are like blueprints. An image describes exactly what goes into a container: the software, the files, and any configuration details (like settings or which parts of the software should be accessible from outside). An image isn’t running software—it’s just the plan.
Containers are running versions based on those images. When you start a container, Docker takes an image and actually runs it—creating a live, isolated environment where the software executes, just as if it were running on its own computer.
Why is this useful? Normally, different computers might have different versions of things installed, which can cause software to work on one machine but not on another. With Docker, containers always use the same setup, so the software works the same way everywhere. This makes it extremely easy to share software: you don’t have to worry about how someone else’s computer is set up.
In fact, there’s a huge library of ready-to-use Docker images called Docker Hub, where you can find all kinds of software to run in containers. Once you get the idea, you’ll find it much easier to try out new projects or tools you discover online.
Host a website locally with Docker Compose
You can run a static website on your own computer using Docker Compose and NGINX, without attaching it to the wider internet. This is a great way to preview or test a website locally, run an application that you don't use outside of your home, or to share a website in a site specific way.
Oh, and what the hell is Docker Compose?
Think of a Docker Compose file like a recipe—it's a reusable document (usually called docker-compose.yml) that defines all the services, dependencies, ports, volumes, and environment settings needed to run a multi-container application. Instead of having to type out a long series of docker run commands with all the options and dependencies included, you can just write them once in the recipe and then start everything with a single, simple command: docker compose up. When you're done, you can remove it all with docker compose down. This makes running complex software much easier and more repeatable.
How Docker Compose relates to images and containers
Remember how we described images as blueprints and containers as running versions of those blueprints? Docker Compose is the tool that orchestrates this relationship at scale. When you write a docker-compose.yml file, you're specifying which images to use (like nginx:alpine in the example below), and Docker Compose automatically creates and manages the containers from those images when you run docker compose up. It handles the entire lifecycle: pulling the images if they don't exist locally, creating containers from them, connecting them together, and managing their shared resources like networks and volumes. So while you could manually run docker run commands to create containers from images one by one, Docker Compose lets you define the whole system—multiple images, multiple containers, and how they relate—in one declarative file, then bring it all to life with a single command.
Quickstart: Local Website with Docker Compose
Assuming you are using VSCode, unless you have a text editing environment that you prefer. Any text editor will do, including nano or vim, but this will be the most convenient.
-
Open VSCode, and open the repo you just cloned by selecting File>Open Folder>C2I2-Workshop-Homework
-
In your left sidebar, you'll see all of the files and folders associated with this project.
-
Click the host-a-website folder, and you'll see three files: docker-compose.yml, index.html, and .env.example. You can ignore all but the docker-compose.yml for now.
-
Select the docker-compose.yml file to edit it. You'll see some grayed out text preceded by # symbols, explaining what each part of the file does.
-
Rename your website container under container_name (remember to remove these <>)
-
Open the VSCode terminal by clicking the "Toggle Panel" button (the square with the horizontal line running across, near the exit button)
-
Enter the host-a-website directory by typing
cd host-a-website -
Make sure that Docker Desktop is running before the next step.
-
Now you can run
docker compose upto deploy your website! You’ll see a bunch of messages. If it worked, when you visit http://localhost:12345 in your browser, you should see your site.- If you got this error:
Error response from daemon: Invalid container name (<your-website-web>), only [a-zA-Z0-9][a-zA-Z0-9_.-] are allowed, you still need to edit your container name in your docker-compose.yml.
- If you got this error:
-
Ahh but how do I turn this thing off!?
- Press
Ctrl + Cin the terminal to kill the running process)
-
But if your container is running and you close your terminal, your site goes down!
-
To keep it running after closing your terminal, add the
-dflag:
docker compose up -d
("-d" stands for "detach" or "daemon" depending on how pedantic you are.) -
If you use Docker Desktop, you’ll now see your container in the dashboard and can start/stop it there if you prefer. You can always see what containers are running in the command line by entering
docker ps -
Edit your HTML file
- A) Edit the existing template
- B) Replace it with your own: delete the existing index.html, drag yours into the host-a-website folder, make sure your homepage is called index.html, and if you are using a separate style.css, make sure that is also added to the folder
- C) Generate a static site with tools like Lichen-Markdown, Hugo, or Jekyll.
-
Refresh the server to see your changes with
docker compose restart
Wait....
You said this would serve on a local network, but when my friend connected to my wifi and tried going to localhost:12345, nothing showed up!
Localhost refers to your own computer. If you want your friends to access your site on a local network, they need to know your public hostname.
On Mac, you can find (and change) your hostname under Settings>General>Sharing, and edit your hostname under Local Hostname.
On Windows, navigate to Settings>System>About, and select the Rename This PC option.
Now your friends can access your site at your-hostname.local:12345
Make your website public with a Cloudflare Tunnel
Cloudflare tunnels are one of the simplest ways to connect websites hosted on your computer to the internet. Cloudflare isn’t perfect, for a lot of reasons (it even went down the day we wrote this), but it’s definitely an accessible way to get started, and if nothing else a chill place to register and manage domains.
Create your tunnel
-
Create a Cloudflare account.
-
If you already own a domain, follow the process to migrate that domain or its DNS management to Cloudflare.
-
If you don’t already have a domain, Cloudflare is not a bad place to get one—unlike Namecheap (which charges a low introductory rate and renews at a higher one), Cloudflare sells domains at cost for a consistent rate. They also make it simple to manage domains and other infrastructure.
-
Once you have a domain in Cloudflare, navigate to Settings>Access (Zero Trust)>Networks>Tunnels, and click to create a new tunnel using Cloudflared.
-
Name your tunnel and continue to the configuration step. Select Docker from the environment options; Cloudflare will give you a docker command that looks like:
docker run cloudflare/cloudflared:latest tunnel --no-autoupdate run --token <your token>- This would be cumbersome to run every time you want to connect your site to the internet! That's why we're using Docker Compose to combine the nginx webserver image, and the Cloudflare tunnel image. The only value we will need to extract from this is the long tunnel token, which we'll paste into our .env file later.
-
Add published application routes to your tunnel.
- Subdomain: optional, can be anything
- Domain: drop down, select from your available domains
- Path: leave blank
- Type: HTTP
- URL: http://localhost:12345 (The http is important, if you type https://, it will not work.)
Upgrade your Docker Compose for Cloudflare
To add Cloudflare tunneling to your setup:
- In the same docker-compose.yml file we used in the previous exercise, uncomment the Cloudflare section by removing the # symbols, and replace all <> bracketed values with your own. All of these values can be pretty arbitrary, but make sure that both entries of "your network" are identical, i.e. "cutiepie-network" for both fields.
- Rename your .env.example file to .env
- Edit .env by adding the token generated during step 5 of the previous section.
- Be sure both your docker-compose and .env files have been saved.
- If your site is currently running, stop the container either by:
- Command line: navigate to the directory where you docker compose file lives, and entering
docker compose downOR - Docker Desktop: Pressing the big stop button next to your container
- Start the container again with
docker compose up - Leave out the -d flag until you have seen the logs, and they don't show any errors. If you see errors, read the errors! If you don't understand the errors, google the errors!
- Within a minute or two, your website should be on the internet!!
Run an open source container!
With all of the docker commands we've just learned, you can now run ALL KINDS of open source software. Docker Hub has an unbelievable amount of software that you can run in containers - personal wikis, photo libraries, or Quake 3 Arena servers. Find an interesting one and see if it runs! Sometimes documentation within Docker Hub is paltry, but often there are guides on the creators websites that are more thorough. See the Awesome Self Hosted list for more ideas.
Skip Cloudflare and get noided
While Cloudflare is a free and accessible tool, which we ourselves used to get started, if you are concerned with privacy, you might be disturbed to know that they decrypt your traffic on their servers, before encrypting it again when it reaches the client. If you don't want them to see your data, or if you want to use infrastructure with a reputation for privacy protection, you can create your own VPS Gateway to route your traffic to the internet without surveillance.
We learned to do this from our friends at Gateway Co-Op. Their approach documented here is a bit different from ours, but the concept is the same.
If you want to skip using corpo infra for domains and servers, you can buy your domain on Njalla, and host a gateway for you AND YOUR FRIENDS on Greenhost.
Run your own Temporary Archive
- Now enter the host-a-temporary-archive directory. If you're currently in host-a-website, you can navigate back up to the c2i2 workshop directory with
cd .., then at this point you should know how to get into the other folder. If you're ever unsure where you are, just typelsorpwd! - Clone the temporary archive repo by entering
git clone https://git.secretserver.club/whisper/social-filesystem.git - Move the Dockerfile and Docker Compose file into the folder that was just created.
- Edit the ports and container name in the docker-compose.yml if you wish
- Run
docker compose build, watch the fun hacker string of text go through all of the steps before hopefully it tells you that it has built successfully - Start the container with
????? - That's right!
docker compose up! - If you didn't modify the docker ports, you'll be able to access your archive at localhost:33333.
- Whenever you upload files, your media library will appear in Public/Library