Home Server Series Part 6 – Your First Self-Hosted Service

What good is a server that doesn’t have a service? In this post, we’ll look at using Docker to set up a Bitwarden password management service. In subsequent posts, we’ll add the ability to access this service from outside your home network securely and reliably.

Dock What?

If you want to run a single service on a server, you can install it, run it, and forget about it. But what if you want to run a dozen services, several with webpages you can interact with? It can become a mess pretty quickly, and that’s why we’re going to use Docker.

Docker is a free, open source management tool that lets you run separate “containers”, each running its own software. The containers have limited access to your server’s folders and network, and you have control over how that interface works. This means you can run multiple services, each in a separate container, without interference between them.

If you followed the home server series tutorials so far, you already have Docker installed. If you haven’t followed along, there’s a good tutorial here. If you need a crash course before jumping into Linux, check out this earlier article in the series.

Easy Mode

There’s two ways to create a Docker container; you can type all the details out in a command, or you can create a file with those details and run it. For myriad reasons, not the least of which is how easy it is, we’re going to do the latter. For that to work, we need Docker-Compose.

Installing it requires a few commands (if you’re unfamiliar with Linux, note that you don’t type the $ sign):

$ sudo mkdir -p /usr/local/lib/docker/cli-plugins
$ sudo curl -SL https://github.com/docker/compose/releases/download/v2.2.3/docker-compose-linux-x86_64 -o /usr/local/lib/docker/cli-plugins/docker-compose

The first command creates a cli-plugins directory. The second uses curl to transfer data from github – the home of most of the software we’ll eventually download – and sets it up on our server.

You should see something like the above; it will go quick.

Next, you’ll need to grant the right account privileges to docker compose:

$ sudo chmod +x /usr/local/lib/docker/cli-plugins/docker-compose

You can test the installation using the version command:

$ docker-compose version

Bitwarden

Bitwardenis a password manager. When you click “save password” in your browser, it’s saved locally on the computer. A password manager lets you save it to a central spot (your server!) so you can access it from more than one thing. It’s a lot like Lastpass except free (if you host it yourself) and open source.

You can organize your files however you’d like, but I created a docker directory and have separate directories for each service I run.

The next thing we want to do is create the file that tells Docker about Bitwarden. For now, lets keep things really simple.

Create a new file called “docker-compose.yml”. Fill it in with these contents:

version: '3'
services:
  bitwarden:
    image: vaultwarden/server:latest
    container_name: bitwarden
    volumes:
      - ./data:/data
    ports:
      - 8008:80
    restart: unless-stopped

Lets take a look at this, because while simple, it’s got all the parts that make a Docker service work.

First, note the spaces; each indentation is two spaces exactly, and it’s expected by docker-compose.

The version is for this file itself; it’s a “version 3” docker-compose file.

Under services, we define one or more services to run in this container. In our case, it’s just one, and we name it bitwarden.

Under the bitwarden service, we have a few things specified. First, an image. This tells docker-compose the name and version of the container image we’re going to copy to set up the Bitwarden service. This is pulled from dockerhub. The image on dockerhub is called “vaultwarden”, hence the name difference.

The container_name tells docker-compose what to name the container. This is really just for our own ease of use; we could call it anything.

Next, is the list of volumes. Think of a volume as a folder that is shared between your container and your computer itself. On the left is your computer’s directory, in this case, a folder called data inside the directory containing this file (./). On the right is the docker container’s folder that maps to it. Note that this folder is at the Linux root level; it’s /data. Inside the container, there will be a miniature version of Linux running and the /data folder there will be the same as the ./data folder in your directory.

For our purposes, that means instead of the container saving your information inside a container, it will be saved on your server’s file system. This is important, because docker containers are meant to be disposable. You can easily remove and recreate them in a few seconds from this docker-compose.yml when you need to, either to fix one that broke or to update one. But because your data will be stored on your server rather than in the container, via the volume, you don’t have to worry about it.

The next line is the list of shared portsJust as with volumes, this has a mapping between your container’s ports and your server’s ports. And in the same way, the port on the left side is your server’s port, while the port on the right is your container’s port. This isn’t a big deal now, but when you run multiple web services that all require port 80 (or some other hard-coded port), Docker can let you map it to something else so they can all run simultaneously.

The last line, restart, just tells Docker that it can restart this container whenever it turns off. Useful if you don’t want to do it yourself whenever your server goes off.

It’s Alive!

You’re almost there. One simple command, and you’ll have your first service running.

$ sudo docker-compose up -d

This command tells docker-compose to spin your service upand the -d flag tells it to run in “detached” mode. Basically, it will run in the background.

You can test that it’s running by using this command:

$ sudo docker ps -a

This will report all containers you have on Docker as well as their status. You should see Bitwarden listed as well as a status of “Up”.

And… that’s it! Head on over to your server’s URL (remember the port!), in my case, 192.168.0.138:8008, and you should see Bitwarden running!

There are browser plugins for Bitwarden as well as phone apps. For now, unless you know a bit about setting up routers, you will only be able to access this service from your home network. In the next tutorial, we’ll look at making this easier to access from anywhere in the world.

2 thoughts on “Home Server Series Part 6 – Your First Self-Hosted Service

Leave a Reply

Your email address will not be published. Required fields are marked *