Current Goal: Making Websites

Running a Server

What it is

Up until now, you have been working on websites by opening the HTML file directly in your browser. This shortcut is limiting in the long term, so it is time to start using a real web server. We’ll talk about why it is necessary and set up a simple python HTTP server on your local machine.

Why it matters

Opening the HTML file right in the browser was working fine. Why do you need a local server?

Long term

All of the sites we are working on in this section are entirely static. They are not interactive in any way and are more like a newspaper than an app. Static sites are great for many products, like blogs and company websites. However, the difference between a website and a web app (static vs dynamic) is blurry.

Even the simplest static sites generally have some form of basic interaction. For example, If you want to add the ability to leave comments on your static blog, you’ll need a server to do something with that comment once the user hits the submit button, such as put the comment in a database.


Still, the toy sites we'll make to practice CSS layout don’t have any interactivity, so why bother with this now? This is a valid question that you should get in the habit of asking. A big part of being a software developer is evaluating the costs and benefits of investing time in new tools. Even for something as fundamental as running a server, it pays to get into a skeptical mindset and ask yourself, is this really necessary?

Downloading and figuring out how to use a server is going to take all afternoon and make your workflow more complicated than just opening a file, so what exactly are you gaining from it? Pragmatically, it doesn’t make sense to spend time learning a new thing until you have a concrete need for it. This sentiment is commonly referred as YAGNI, or You Aren’t Gonna Need It.

Short Term

Point taken! Strictly speaking, for this section, you could get by without using a web server. However, even for completely static sites, there is a concrete upside to using a local web server. By default, if you open an HTML file directly in your browser, the browser’s security settings will prevent it from loading additional files (images, CSS, JS, etc) from anywhere but your hard drive.

However, it is very common for static websites to load some of their resources, such as 3rd party CSS libraries and web fonts, from external servers instead of saving them locally. Using google’s highly optimized servers to provide the fonts for you website causes the site to load faster and prevents you from needing to figure out how to host them yourself.

Without a sever, the browser will block these libraries and web fonts, so your page will appear to be broken when you open the file directly.

What you'll learn

  • How to host a static website with a local HTTP server
  • URLS and TCP ports

How to learn it

For context, first read through the Mozilla guide: What is a web server?

So how do you run a web server? A web server is a program just like anything else. Just like any other application, you can download and install one off of the internet and run it with a double click. The most famous web server is called Apache and is available for free as an open source project.

However, since we’ve learned about the command line and interpreters, there’s a better way. Fortunately, most programming languages designed to be used for the web will have some form of web server packaged with the language. From the shell, you can generally run the web server with a simple one line command. There’s a lot of languages, so there’s lots of web servers to choose from.

If you’ve followed along with setting up your development environment, you should already have the python interpreter installed. In that case, running a static HTTP server is exceedingly easy.

At the end of the command line lesson, you should have used your new shell skills to move your Google site into a projects folder. Change into that directory on the command line and run the python SimpleHTTPServer command to launch your server.

# On Mac and Linux
python -m SimpleHTTPServer

Now, in your browser, the site should be available at localhost:8000.

localhost:8000/styles.css will bring up just your CSS file.

Why ‘localhost:8000’?

Remember that a website like ‘’ is really just a nickname (DNS name) for an IP address. In this case, the server is running on your local machine. ‘localhost’ is a special name reserved for the IP address that points a computer back to itself, ‘’. This is also called the 'loopback interface.’

8000 is the TCP port number.

What's a TCP port?

Imagine that you have many different servers running on a single computer. If I connect to that computer, how do I know which server will respond? The solution is to have multiple ‘ports’ and let the applications claim the port they want to use.

This python server arbitrarily uses port 8000 by default, but you can run it on whatever port you want. If we run it on port 8001, the URL will be localhost:8001 instead. Give it a try:

$ python -m SimpleHTTPServer 8001
Serving HTTP on port 8001 ...

Every URL we type connects to a specific port, even if it isn’t explicitly stated. By convention, web servers bind port 80, the HTTP port.

Kill your server and run it again on port 80.

sudo python -m SimpleHTTPServer 80

Notice you need to use the sudo command and enter your password to do this, because by default programs aren’t allowed to use this special reserved port without permission. Many TCP ports are reserved for specific applications by convention. For example, SMTP (email) servers use port 25 and HTTPS (encrypted HTTP) servers use port 443.

Assuming it started without error, now you can see that your website is available in your browser at localhost. This is analagous to localhost:80. We’ll cover ports and all of this in more detail when we talk about TCP, the protocol that makes all of this work.


If you aren’t familiar with the pieces of a URL, read the mozilla guide What is a URL?

The main takeaway for now should be that each URL maps to a specific file on the internet. That is why it is called a “uniform resource locator”, because it uniformly identifies a single file, or resource, on a particular server.

The URL has two parts. The first part, tells the browser:

  • the protocol (http)
  • the IP address (or DNS name, here, and
  • the port number (80) of the web server containing the files.

The second part, /path/to/myfile.html, identifies the specific file in the web server’s file system.

Web servers generally never host the computer's entire filesystem, but just a specified public directory. By default, our python server will host whatever directory the shell was in when the server was launched. If we ran it while the shell was sitting in (for example) /Users/MyUser/Projects/GoogleHomepage/, localhost:8000/styles.css will serve the file /Users/MyUser/Projects/GoogleHomepage/styles.css.


  • How do you run a local web server?
  • Why bother with a local web server?
  • What is YAGNI?
  • What is the difference between a static and dynamic web server?
  • What is HTTP?
  • What does it mean that HTML is textual and stateless?
  • What is Apache?
  • What is the shell command to run a static web server with python?
  • What is localhost? What IP address does it correspond to?
  • What are TCP ports for?
  • What is special about TCP port 80?
  • What is a URL? What does it stand for and why?
  • What are the parts of a URL?


Follow along and run a local python web server to host your first project. If you skipped the Google homepage project, make a project folder and create a dummy index.html file to test the server with.

The server will host the entire folder that you were in when you ran the command from the shell. Try adding a new folder to experiment with URLs. From the shell, create a new folder in your project called ‘test’ and place a copy of your index.html into it. Now, in the browser, you can access that copy at localhost:8000/test/index.html. Makes sense?

What's Next?

This site relies on your feedback! These lessons are free. Please take this 2 minute survey when you finish each lesson so I can make them better.

Current Goal: Making WebsitesNext Lesson: Git Basics