Skip to content

Commit dd0fe7e

Browse files
authored
Merge pull request #12 from marcpaq/self-hosted-homelab
Self hosted homelab
2 parents 15e47a5 + 1819c02 commit dd0fe7e

10 files changed

+217
-0
lines changed

posts/self-hosted-homelab/index.md

Lines changed: 217 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,217 @@
1+
---
2+
title: Run Coder in a self-hosted homelab
3+
date: April 7, 2023
4+
author: Marc Paquette
5+
---
6+
7+
# Run Coder in a self-hosted homelab
8+
9+
I outgrew my little homelab. I have a couple of [ODROID-HC2](https://ameridroid.com/products/odroid-hc2) devices in a closet for serving files and experimenting with ARM assembly. They work great but they’re small, single board computers with matching small capacity.
10+
11+
It was time to expand my homelab to handle my dev projects too.
12+
13+
## My problem: I wasn't getting anywhere
14+
15+
I was spending too much time working around my project's obstacles instead of working on them. They're spread out over several environments and places:
16+
17+
* They run on OpenBSD, Windows, Linux, ARM, python3, browsers, and command-line tools.
18+
* I’m typing right now on an OpenBSD laptop. I sometimes use a Windows laptop. The ODROIDs are almost literally chained to my homelab closet.
19+
* I work from home, a co-work space, and sometimes other time zones.
20+
21+
In other words, my location and the machine I use put a limit on the projects I could work on at any given time.
22+
23+
A good solution would let me self-host my projects and work on them wherever and however I want. A better solution would also let me use an iPad for the [ultimate sofa software development rig](https://coder.com/blog/a-guide-to-writing-code-on-an-ipad).
24+
25+
I put off fixing this because I expected to hack and contort different tools into something that might eventually approach what I wanted. The cure seemed worse than the disease.
26+
27+
## I discovered Coder
28+
29+
It turns out that [Coder](https://coder.com/docs/v2) is a much easier solution. Coder solves big problems for big enterprise dev teams. And I discovered that it can solve my problems:
30+
31+
- An isolated workspace for each project, no matter the environment
32+
- Secure, remote access
33+
- Flexibility of handling cloud and on-prem workspaces
34+
- Administering all these workspaces from a single place
35+
- Easy to install
36+
- Runs on modest hardware
37+
- Bonus: [Open source](https://github.com/coder)!
38+
39+
## First, the hardware
40+
41+
My homelab would need more hardware. I found a used [Lenovo m92P Tiny](https://www.lenovo.com/il/en/desktops/thinkcentre/m-series-tiny/m92p) with 16 GB RAM and upgraded its spinning disk with a 1 TB SSD, all for $200. I named it "Marvin", a character from my favorite movie.
42+
43+
I installed [Debian](https://www.debian.org/intro/why_debian) and crammed Marvin into the homelab closet. Marvin’s only connection to the outside world is an ethernet cable.
44+
45+
![Marvin and the rest of my homelab](./static/marvins-new-home.jpg)
46+
47+
48+
## Install Docker then Coder
49+
50+
I ssh'd into Marvin to get started.
51+
52+
First I installed Docker, before Coder. You'll see why in two paragraphs.
53+
54+
Instead of [Docker Desktop](https://www.docker.com/products/docker-desktop/), I installed [Docker Engine for Debian](https://docs.docker.com/engine/install/debian/) because Marvin is headless. I'm not missing out on Docker Desktop's GUI since Coder does a lot of Docker management for me.
55+
56+
Next was Coder. Its [install script](https://coder.com/docs/v2/latest/install/install.sh) does the right thing. In Marvin’s case it detected Debian to install a `.deb` package. It also recognized Docker so it added the `coder` user to the `docker` group.
57+
58+
```bash
59+
marc@marvin:~$ sudo curl -fsSL https://coder.com/install.sh | sh
60+
[sudo] password for marc:
61+
Debian GNU/Linux 11 (bullseye)
62+
Installing v0.18.1 of the amd64 deb package from GitHub.
63+
# Installation progress...
64+
deb package has been installed.
65+
# Info for next steps, including setting up Coder as a systemd server...
66+
marc@marvin:~$
67+
```
68+
69+
I wanted to dedicate Marvin to hosting my projects, so I followed the installer's suggestion to run Coder [as a system service](https://coder.com/docs/v2/latest/admin/configure#system-packages):
70+
71+
```bash
72+
marc@marvin:~$ sudo systemctl enable --now coder
73+
```
74+
75+
Accessing Coder is straightforward:
76+
77+
- [Command line tool](https://coder.com/docs/v2/latest/cli)
78+
- Web user interface that I can access on my home network with Marvin's local IP address
79+
- Publicly accessible, encrypted tunnel based on [Tailscale](https://coder.com/docs/v2/latest/networking)
80+
- An [API](https://coder.com/docs/v2/latest/api)
81+
82+
I got the [tunnel’s access URL](https://coder.com/docs/v2/latest/admin/configure) (and checked that Coder is up and running):
83+
84+
```bash
85+
marc@marvin:~$ sudo journalctl -u coder.service -b
86+
# Log entries from Coder
87+
Mar 09 14:22:21 marvin coder[617]: Opening tunnel so workspaces can connect to your deployment. For production scenarios, specify an external access URL
88+
Mar 09 14:22:22 marvin coder[617]: View the Web UI: https://marvin-access-url.pit-1.try.coder.app
89+
# More log entries from Coder
90+
```
91+
92+
## Using Coder for the first time
93+
94+
At this point I was able to use my laptop's browser to log in to Coder. I opened a tab with the access URL and was asked to set up an account. This account is only for Marvin's instance of Coder.
95+
96+
![Setting up an account](./static/account-setup.png)
97+
98+
Once logged in, I was ready to set up my first workspace. A Coder [workspace](https://coder.com/docs/v2/latest/workspaces) is a runnable environment that a developer, well, develops in. Each developer has their own workspace (or workspaces).
99+
100+
A developer can connect to a workspace from their [favorite IDE](https://coder.com/docs/v2/latest/ides) and dev tools. That includes browser-based [VS Code](https://coder.com/docs/code-server/latest), [LSP](https://langserver.org/) servers, and local JetBrains or Emacs.
101+
102+
## Create a template
103+
104+
Before I could start a workspace, I needed to create a [template](https://coder.com/docs/v2/latest/templates). A template is the collection of settings that Coder uses to create new workspaces. You only have to set up a template once to create as many workspaces as you need from it.
105+
106+
A Coder template is a [Terraform](https://www.terraform.io/) file. That means that a Coder workspace can be whatever you can provision with Terraform. For big dev teams, that can be as sophisticated as pods in a [Kubernetes](https://coder.com/docs/v2/latest/platforms/kubernetes) cluster.
107+
108+
Or when an ephemeral container won't do, like when a project is more "pet" than "cattle" or the project needs fuller access to the OS and hardware, a template can provision a virtual machine with [Proxmox VE](https://github.com/bpmct/coder-templates/tree/main/proxmox-vm). This way, the developer can treat the workspace like a full computer but still manage it like any other workspace.
109+
110+
Coder comes with a few templates out of the box. These templates include cloud computing like [Fly.io](https://coder.com/blog/remote-developer-environments-on-fly-io), Digital Ocean, Azure, Google Cloud, and AWS.
111+
112+
For Marvin, I'd just be using Docker.
113+
114+
For my first workspace, I wanted to keep things simple with a template that would let me self-host with Docker. I selected **Templates** then **Starter Templates**.
115+
116+
![Selecting Starter Templates](./static/template-starter.png)
117+
118+
In **Starter Templates** I selected [Develop in Docker](https://github.com/coder/coder/tree/main/examples/templates/docker).
119+
120+
![Selecting the Developer in Docker template](./static/template-develop-in-docker.png)
121+
122+
I went back to Marvin's shell to set up my template, starting with authentication:
123+
124+
```bash
125+
marc@marvin:~$ coder login https://marvin-access-url.coder.app
126+
Open the following in your browser:
127+
128+
https://marvin-access-url.coder.app/cli-auth
129+
130+
> Paste your token here:
131+
> Welcome to Coder, marc! You're authenticated.
132+
```
133+
134+
Then I followed the instructions to create a Docker template. This template creates a directory named `docker`:
135+
136+
```bash
137+
marc@marvin:~$ coder templates init
138+
# Follow instructions to choose Develop in Docker...
139+
Create your template by running:
140+
141+
cd ./docker && coder templates create
142+
143+
Examples provide a starting point and are expected to be edited!
144+
```
145+
146+
This starter template uses the vanilla [Ubuntu container image](https://hub.docker.com/_/ubuntu/). Normally at this point, I would have customized the template for a project by editing the Terraform file, `main.tf`, in the `docker` directory:
147+
148+
```bash
149+
marc@marvin:~$ ls docker
150+
main.tf README.md
151+
```
152+
153+
Next, I followed Coder's instructions to create the template:
154+
155+
```bash
156+
marc@marvin:~$ cd ./docker && coder template create
157+
> Upload "~/docker"? (yes/no) yes
158+
# Progress info...
159+
┌────────────────────────────────┐
160+
│ Template Preview │
161+
├────────────────────────────────┤
162+
│ RESOURCE │
163+
├────────────────────────────────┤
164+
│ docker_container.workspace │
165+
│ └─ main (linux, amd64) │
166+
├────────────────────────────────┤
167+
│ docker_image.main │
168+
├────────────────────────────────┤
169+
│ docker_volume.home_volume │
170+
└────────────────────────────────┘
171+
> Confirm create? (yes/no) yes
172+
The docker template has been created at Mar 09 14:28:39! Developers can
173+
provision a workspace with this template using:
174+
175+
coder create --template="docker" [workspace name]
176+
177+
marc@marvin:~/docker$
178+
```
179+
180+
There! The web interface confirmed that the template was ready to go:
181+
182+
![Template is ready to go](./static/template-ready.png)
183+
184+
## Create a workspace
185+
186+
I was then able to create a workspace from my first template. I selected **Workspaces** then **Create from template**:
187+
188+
![Create a workspace from a template](./static/workspace-create.png)
189+
190+
I filled in details about my first workspace then started it:
191+
192+
![Start my first workspace](./static/workspace-start.png)
193+
194+
Marvin took a couple of minutes as Coder prepared the workspace for the first time, including downloading the Docker image. After that starting the workspace would take only a few seconds.
195+
196+
That got me my first workspace, running and ready to use! I could access it in a few ways, including [code-server](https://coder.com/docs/code-server/latest), which lets me use VS Code in the browser.
197+
198+
![Workspace running](./static/workspace-run.png)
199+
200+
Out of curiosity, I went back to Marvin's shell to confirm that Docker was running my workspace:
201+
202+
```bash
203+
marc@marvin:~/docker$ docker ps
204+
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
205+
9fed4695ac59 coder-4868739b-5bc8-421c-123f-59fd8d2581ab "sh -c '#!/usr/bin/e…" 7 minutes ago Up 7 minutes coder-marc-myfirstworkspace
206+
```
207+
208+
## Where to go from here
209+
210+
I can finally go places while my homelab hosts my projects. Coder's public access URL for Marvin lets me work wherever I want. And I can finally work on my projects however I want.
211+
212+
![Ultimate sofa software development rig](./static/sofa-dev-rig.jpg)
213+
214+
For the next step, I'll set up some of my projects as Coder workspaces on my homelab:
215+
216+
* Static web site generator: Create a template with [persistence](https://coder.com/docs/v2/latest/templates/resource-persistence) and add [Pelican](https://getpelican.com/) to the template's Docker image.
217+
* ARM assembly: Create a template that provisions an ODROID.
Loading
Loading
Loading
Loading
Loading
Loading
Loading
Loading

0 commit comments

Comments
 (0)