Getting Started With the Node Solid Server 
Tags: node, solid, decentralized, federated
Published: 2021-09-10 08:20:41

---
title: Getting Started With the Node Solid Server 
published: true
description: A dive into Solid, including a complete how-to for starting your own Solid server using Node.js.
tags: node, solid, decentralized, federated
cover_image: https://solid.inrupt.com/sites/default/files/2018-09/r_1.png
---

**A dive into Solid, including a complete how-to for starting your own Solid server using Node.js.**

Solid is a [specification](https://solidproject.org/TR/protocol) that lets people store their data in federated data stores called Pods. The information on each Pod is linked through a person's online [identity](https://solidproject.org/TR/protocol#identity). Identity is addressed with a [WebID](https://en.wikipedia.org/wiki/WebID), which is just an HTTP URL that points to a profile.

As depicted in the image below, the personal data pod can include things like pictures, calendar information, and personal contacts. The left side of the image depicts how this information is stored in walled gardens on today's internet platforms. The right shows how the data is stored in a personal data pod. Applications can simply query a Pod to get the information they need to provide their service.

![apps-as-views.svg][nextjournal#file#e456a32c-a4c7-402b-86f0-30aee7af77ba] *Figure: Applications can query a pod to get the data they need. CC-by-4.0 Ruben Verborgh*

Individuals can therefore manage their personal information in whatever place they choose. The Solid standard makes it easy to grant and revoke access to personal information to specific individuals, organizations, and applications. This is a win for personal privacy.

Pods make the web more secure because data is not pooled in a single place. Personal information is spread across a federation of servers. While Solid does not prevent individual targeting, its adoption would curb the massive data breaches that have become commonplace.

Individual Pods can move between servers with very little friction. If a person does not like a server's security practices, terms of service, or notices other forms of abuse, they can simply move their Pod to another server or even *host their Pod on their own server*.

That last sentence is what this article is about. Running the code in this article will stand up a Solid server that can be found on the public internet. I will take you through each step along the way, including how to access the server from [an outside Solid application](https://solidproject.org//apps). Let's get started.

## Ngrok

The Solid server runs locally; Ngrok will provide a public URL for the local Solid server.

I have configured Ngrok to make the Solid server available at `https://btf.ngrok.io`. The full `ngrok.yml` file can be found in the **Appendix**. See the **Ngrok Configuration** section.

A reserved subdomain (`btf` in this case) is only available through the paid plan. If you don't have a paid plan, you'll have to provide Ngrok's generated subdomain to the Solid server before you start it up.

I'll add my authentication token to the `ngrok.yml` configuration file. The token is held in an environmental variable.

```
echo 'authtoken:' $ngrok | cat - ngrok.yml > /tmp/out && mv /tmp/out ngrok.yml
```

Now it's time to `start` the `ngrok` service in the background using `nohup`.

```
nohup ./ngrok start --all --config="/ngrok.yml" --log="/tmp/ngrok.log" &> /tmp/ngrok-run.log & sleep 1
```

The Ngrok tunnel is now live at https://btf.ngrok.io/. The next step is standing up a Solid server at https://localhost:8443.

## Solid

There are two Solid server implementations that run on Node.js. The [Community Solid Server](https://github.com/solid/community-server) ([documentation](https://solidproject.org//self-hosting/css)) is newer, but this article uses the [Node Solid Server](https://github.com/solid/node-solid-server) ([documentation](https://solidproject.org/self-hosting/nss)). Both are open-source Node.js implementations of the same Solid standard, independently maintained.

The Solid server provides the necessary tools to store and manage access to data held in Pods on the sever.

* The server provides the tools to assert your identity (you are who you say you are, **Authentication**)
* The server provides the tools to use your identity (sharing personal information, having conversations on the internet, etc..., **Authorization**)

### Authentication

Once you prove you are in control of your Pod, the authentication is done. This authentication step is not application-specific, it's Pod-specific. Therefore *a person does **not** need a unique name and password for each application they use, they only need a single name and password for the Pod.*

### Authorization

A Solid application will ask you to authorize certain access permissions. The ultimate authority on who has access to your information does not live within the application (which is generally true today), it lives within a person's Pod.

### Install the server

Now that some of the Solid server's functions are clear, it's time to install the server using NPM.

```
npm install -g solid-server
```

### Configure the Server

The server's configuration is held in `config.json` below. A few specific notes.

* The `serverUri` must be set to the reverse proxy's URI, `https://btf.ngrok.io`.
* The `port` is set to serve information over SSL at `8443`. This number matches the port setting of Ngrok's `addr` (address), `https://localhost:8443`. See `ngrok.yml` in the **Appendix** for more context.

Setting `webid` to `true` enables authentication and access control by establishing a relation between the [WebID](https://www.w3.org/2005/Incubator/webid/spec/tls/#dfn-webid) URI and the person's [public key](https://www.w3.org/2005/Incubator/webid/spec/tls/#dfn-public_key)s

```
{ "root": "/solid/data",
  "port": "8443",
  "serverUri": "https://btf.ngrok.io",
  "webid": true,
  "mount": "/",
  "configPath": "./config",
  "configFile": "./config.json",
  "dbPath": "./.db",
  "sslKey": "/keys/privkey.pem",
  "sslCert": "/keys/fullchain.pem",
  "multiuser": false,
  "server": {
    "name": "The Beyond the Frame Solid Server",
    "description": "This is a Solid server experiment.",
    "logo": ""
  }
}
```

The `sslKey` and `sslCert` still need to be generated and added to the environment. This can be done using the `openssl req` command. OpenSSL is a general purpose cryptographic SSL/TLS (Secure Sockets Layer/Transport Layer Security) toolkit, `req` is the specific command to fulfill a X.509 Certificate Signing Request.

Here is the configuration file that provides the necessary cryptographic information and fulfills the *[Distinguished Name](https://www.ibm.com/docs/en/i/7.2?topic=concepts-distinguished-names-dns)* requirements.

```
[ req ]
 default_bits       = 2048
 default_md         = sha256
 prompt             = no
 encrypt_key        = no # do not encrypt the keypair, same as -nodes
 distinguished_name = btf_server
[ btf_server ]
 countryName            = "US"
 stateOrProvinceName    = "Illinois"
 localityName           = "Chicago"
 organizationName       = "Beyond the Frame"
 organizationalUnitName = "None"
 commonName             = "example.com"
 emailAddress           = "example@example.com"
```

Run the `req` command to generate a 2048-bit (`default_bits`) private key (`-keyout /keys/privkey.pem`) and then fulfill a certificate request (`-out /keys/fullchain.pem`).

```
mkdir /keys
openssl req -outform PEM -keyform PEM -new -x509 -keyout /keys/privkey.pem -config openssl.cnf -days 365 -out /keys/fullchain.pem
```

Finally, the Solid server needs a folder to serve. The folder is set by  `root` in the configuration file above. Make the corresponding directory:

```
mkdir -p /solid/data
```

### Run the Server

```
solid start
```

Open another window and load https//btf.ngrok.io. This will be the result:

![Solid server splash screen](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ugv3f4cprggm1gqyeg2f.png)

Some explanation on the magic happening behind the scenes is worthwhile.

Solid requires valid SSL certificates to function properly. They normally cannot be self-signed. The command `solid-test start` can be used to accept self-signed certificates. The command is found in `solid-server/bin` under the `opt/nodejs` folder.

However, this article gets away with self-signed certificates because Ngrok's servers use the registered `ngrok.com` certificates. Ngrok assumes that the server is running privately, so it doesn't need to check our self-signed certificates. If this was production instance, we would want to use our own certificates rather than Ngrok's.

## Working With Pods

### WebID

Click the blue **Register** button at https//btf.ngrok.io to create a WebID. The profile associated with the WebID will be at this URL: https://btf.ngrok.io/profile/card#me. Use this identifier to interact with Solid pods and apps.

Note: if `multiuser` was set to `true` in the `config.yml`, this WebID could be customized with a user's name to differentiate it from other Pods on this Solid server.

### Schema

> Relationships are the stuff of which information is made. Just about everything in the information system looks like a relationship.

\~ *[Data and Reality](https://bookwyrm.social/book/48395)* (87)

Now that the personal datastore is addressable at https://btf.ngrok.io/profile/card#me, web applications can request personal information using a standard schema.

The schema does more than simply address the data, it can describe relationships between bits of information.

For example, you may host a photograph on your Pod that you share through an application. If I sign into the same application using my WebID, I might be able to leave a comment on the photograph. That comment could exist on my Pod because I am the original author, but you could still view it through the application interface. The relationship between the photo and the comment can be depicted by a schema. It may look something like:

```
<https://mypod.solid/comments/36756>
    <http://www.w3.org/ns/oa#hasTarget>
        <https://yourpod.solid/photos/beach>
```

As Ruben Verborgh illustrates in *[Solid: Personal Data Management Through Linked Data](https://genr.eu/wp/solid/)*, the comment on my Pod is linked to the picture on your Pod through a type defined in a schema. We know that my comment is a response to your picture instead of the other way around.

Like the markup standards that ensure a website is displayed correctly, schema standards for the world wide web promised to create semantic relationships between pieces of information on the web. This effort is at least 20 years old and their website at [schema.org](https://schema.org/) just [turned 10](http://blog.schema.org/2021/06/schemaorg-is-ten.html).

Wikidata is one of the most prominent sites built on structured data. They use an [open schema](https://www.w3.org/TR/rdf-schema/) called [RDF](https://www.w3.org/TR/rdf11-primer/). [RDF graphs](https://www.w3.org/TR/rdf11-primer/) are sets of subject-predicate-object triples (e.g. `<Bob>` *subject* `<is a>` *predicate* `<human>` *object*). The schema also provides a data-modelling vocabulary for RDF data (e.g. `<human>` is a `subClassOf` `<mammal>`).

These structures allow programmers to create [vocabularies](https://solidproject.org/developers/vocabularies) - which are essentially rules about what information can and cannot be asserted about a domain. For example, a programmer can build a social graph using the [Friend of a Friend vocabulary](http://xmlns.com/foaf/spec/).

Solid is built to use RDF. [Common vocabularies](https://solidproject.org/developers/vocabularies/well-known) can parallel the power of social networks, shared calendars, document collaboration, music libraries, etc.... These vocabularies describe what interactions are possible between Pods. Since vocabularies are built on open standards, independent data sources and applications don't have to build their own custom API. Interoperability is baked in, [centered on web identity](https://www.w3.org/2005/Incubator/webid/spec/tls/).

## Apps

Solid supports a rich ecosystem of applications that compete on the merits of their service. The best-performing applications will naturally be complimentary with other services that process the data on your pod. As Jacob O'Bryant [opines on Solid](https://jacobobryant.com/p/what-im-trying-to-do/#1-help-build-a-career-path-for-software-inventors):

> There's an interesting analogy to functional programming: it's better to have 100 apps operate on 1 database than 10 apps operate on 10 databases.

Any one of Solid's [official list of apps](https://solidproject.org//apps) can be used to read and write data to this new Pod. For example, *[Notepod](https://notepod.vincenttunru.com/)* is a simple Solid-compatible note-taking app. [Visit the app](https://notepod.vincenttunru.com/), click **Connect**, and add this Pod's URL.

![Notepod Connect to Pod](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4cs636010gpvrlbkz8gr.png)

When asked to authenticate, use the username and password previously created on the Solid server.

![Notepod Login](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zyj71gv2ahpn17vwph1z.png)

Grant the requested permissions and the app is connected. Anything created in the app is stored in the Pod. It's worth re-emphasizing that the app doesn't have its own username and password. Solid not only solves the problem of siloed data, it solves the proliferation of usernames and passwords that plague today's internet users.

## Conclusion

I hope this article helped convey the power of Solid and how easy it is to get started with your own Solid server. The technology will become more powerful and useful as the federated network of servers grow. When working with the configuration files, make sure to configure Ngrok to use your own subdomain (paid Ngrok plan) or dynamically add the generated subdomain to your Solid server configuration (free Ngrok plan).

Find me at my blog where I discuss information science, art, and narrative: [Beyond the Frame](https://schmud.de/). I can also be reached at [Mastodon](https://mastodon.social/@schmudde) and [Twitter](https://twitter.com/dschmudde).

## Appendix

### Federated Servers

If you don't like the server that hosts your Pod, simply move it to another server. Here is a list of current Solid servers:

* [Inrupt Pod Spaces](https://signup.pod.inrupt.com) by [Inrupt, Inc.](https://inrupt.com/terms-of-service) hosted at [Amazon](https://aws.amazon.com) in the USA. I have [a Pod and public profile](https://pod.inrupt.com/schmudde/profile/card#me) on this server.
* [inru](https://pod.inrupt.com/schmudde/profile/card#me)[pt.net](https://inrupt.net) by [Inrupt, Inc.](https://inrupt.com/terms-of-service) hosted at [Amazon](https://aws.amazon.com) in the USA
* [solidcommunity.net](https://solidcommunity.net/) by [Solid Project](https://github.com/solid/solidcommunity.net_operations) hosted at [Digital Ocean](https://www.digitalocean.com) in the UK. I have [a Pod and public profile](https://schmudde.solidcommunity.net/profile/card#me) on this server.
* [solidweb.org](https://solidweb.org) by [Solid Grassroots](https://gitlab.com/groups/solidweb.org/-/group_members) hosted at [Hosteurope](https://www.hosteurope.de) in Germany
* [trinpod.us](https://trinpod.us) by [Graphmetrix, Inc.](https://graphmetrix.com/terms) hosted at [Amazon](https://aws.amazon.com) in the USA
* When this code is running, there is also a Solid server at https://btf.ngrok.io

You can choose a server based for a variety of ethical or technical reasons. Perhaps you disagree with a change in the terms of service, want more storage capacity, or high-speed transfer. This is illustrated in the *data market* section below:

![data-and-app-markets.svg][nextjournal#file#7a55db87-decc-4b99-afae-64d01f3990c9] *Figure: Data and app markets. CC-by-4.0 Ruben Verborgh*

### Ngrok Configuration

If you use the code from this article, you can use the same Ngrok service, but your `subdomain` will be random, rather than `btf`. All other configurations are the same.

When you change the `subdomin`, remember that the full domain, subdomain, domain (`.ngrok`), and TLD (`.io`) must match in three places:

1. This Ngrok configuration file at `subdomain`.
2. The `serverUri` found in Solid's `config.json` above.
3. The URL in your web browser's address bar.

Here is the Ngrok configuration used in this article:

```
region: us
console_ui: true
tunnels:
  btf:
    proto: http
    addr: https://localhost:8443
    subdomain: btf
    bind_tls: true
```

Setting the `https` prefix of `https://localhost:8443` forces Ngrok to speak HTTPS to the local server. The `8443` port suffix directs it to the Solid server's port.

* `proto: http` - the protocol. The `http` protocol covers both HTTP and HTTPS
* `addr: `[`https://localhost:`](https://localhost:3000)`8443` use the full URL to force HTTPS (equivalent to `ngrok http https://localhost:8443` on the command line)
* `bind_tls` - without this setting both HTTP and HTTPS will be available from ngrok
  * `bind_tls: true` - ngrok only listens on an HTTPS tunnel endpoint
  * `bind_tls: false` *-* ngrok only listens on an HTTP tunnel endpoint
* `host_header: localhost` - unused. But some APIs will want to see the host header of your app rather than 'ngrok'

### References

* Kent, William, and Steve Hoberman. 2012. *Data And Reality*. 3rd ed. Westfield, N.J.: Technics Publications.
* ‘Linked Data – Design Issues’. Accessed 19 August 2021. <https://www.w3.org/DesignIssues/LinkedData.html>.
* Verborgh, Ruben. ‘[Solid: Personal Data Management Through Linked Data](https://genr.eu/wp/solid/)’, 2018. <https://doi.org/10.25815/50W4-HK79>.

This work is licensed under a [Creative Commons Attribution 4.0 International License](https://creativecommons.org/licenses/by/4.0/).

![License](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bwk5e444xhjro1c8wqax.png)

[nextjournal#file#e456a32c-a4c7-402b-86f0-30aee7af77ba]:
<https://nextjournal.com/data/QmQ2x8S1AHw3nTQwfGfPmBTABJXLApuow7xNLUqheyg7vG?content-type=image/svg%2Bxml&node-id=e456a32c-a4c7-402b-86f0-30aee7af77ba&filename=apps-as-views.svg&node-kind=file> (<p>Applications can query a pod to get the data they need. © Ruben Verborgh, CC-by-4.0</p>)

[nextjournal#file#7a55db87-decc-4b99-afae-64d01f3990c9]:
<https://nextjournal.com/data/QmXheA4Wepw7hvDMPEwwEbmVH5E4avBFxhpNpJVUTAaYMg?content-type=image/svg%2Bxml&node-id=7a55db87-decc-4b99-afae-64d01f3990c9&filename=data-and-app-markets.svg&node-kind=file> (<p>Figure: Data and app markets © Ruben Verborgh, CC-by-4.0</p>)