A self-contained server is a program that does not need another program to run. A PHP script, for example, will run through at least two other programs: PHP (the compiler) and Nginx, Apache, or another HTTP(S) server. A self-contained server such as a Swift application, however, is the only application that needs to run; it answers HTTP(S) requests directly.
Let's look at a small Swift web server:
import Vapor
let app = try Application()
app.get("hello") { req in
return "Hello, world."
}
try app.run()
Without going into much detail, the crucial part is the last line:
try app.run()
The application does not close; it keeps running. What the framework (Vapor) and the network library (SwiftNIO) are hiding here is that the application is actively listening to incoming connections over TCP on a given port (8080 by default). So, incoming requests are answered directly by the application and, by extension, the return statement.
If you have a background in dealing with scripting web applications, you may find a lot of perks in self-contained servers. In scripting languages, every request is usually isolated. Every request is treated individually, and you have no access to the other requests that are coming in. Technologies such as Memcached are designed to bridge this for you to share information between requests.
In Swift servers, however, the process, the running application, is the same for all requests. You can share memory, objects, and instances across requests. It not only allows you to centralize some of your logic (such as the database), it also saves you a lot of memory and CPU power.
Now that you have learned how a self-contained server operates, let's take a look at the hosting operating system: Linux/Ubuntu.