2024-10-27 20:04:13 +00:00
|
|
|
+++
|
2024-10-28 20:42:31 +00:00
|
|
|
title = 'My Setup - p1'
|
2024-10-30 15:46:43 +00:00
|
|
|
subtitle = 'Containers!'
|
|
|
|
summary = "I go over the things I've learned about docker, and how I've used it to host my website."
|
2024-10-27 20:04:13 +00:00
|
|
|
date = 2024-10-25T23:11:17+03:00
|
2024-10-27 21:11:31 +00:00
|
|
|
draft = false
|
2024-10-27 20:04:13 +00:00
|
|
|
+++
|
|
|
|
|
2024-10-28 20:51:06 +00:00
|
|
|
# My Setup
|
2024-10-27 20:04:13 +00:00
|
|
|
|
2024-10-28 20:42:31 +00:00
|
|
|
In this 'series' I will be walking you through my process of how I
|
2024-10-27 20:04:13 +00:00
|
|
|
host everything on this server.
|
|
|
|
|
2024-10-28 20:51:06 +00:00
|
|
|
I'm currently running, on top of [my blog](https://emin.software), a [gogs
|
|
|
|
instance](https://git.emin.software).
|
|
|
|
|
2024-10-28 20:42:31 +00:00
|
|
|
When first creating this website, I just had my blog. I generated this blog
|
|
|
|
using [hugo](https://hugo.io): a static site generator. Hugo allowed me to
|
|
|
|
focus on writing whatever I wanted in Markdown format, it would take care of
|
|
|
|
converting my writing into HTML and CSS.
|
2024-10-27 20:04:13 +00:00
|
|
|
|
2024-10-28 20:42:31 +00:00
|
|
|
I had a small issue with how I wrote my code and deployed it though: whenever I
|
|
|
|
made a small change to the page, I had to manually rebuild it, then upload the
|
|
|
|
updated version to my server and put it in the web directory.
|
|
|
|
|
|
|
|
This is a cumbersome process. The whole point of using hugo is to *focus on the
|
2024-10-30 15:18:30 +00:00
|
|
|
writing*, so having to zip and reupload for every typo is... not great. I
|
2024-10-28 20:42:31 +00:00
|
|
|
wanted to be able to do a simple `git push`, and not worry about the rest.
|
2024-10-27 20:04:13 +00:00
|
|
|
|
2024-10-30 15:46:43 +00:00
|
|
|
The "manual" approach also depends on me having already installed all
|
2024-10-27 20:04:13 +00:00
|
|
|
necessary software. If you have a dedicated server that you're running yourself,
|
|
|
|
that's probably okay, you just have to setup once, but I'm running this on a VPS
|
2024-10-27 20:26:01 +00:00
|
|
|
that I'm not sure I'll keep forever. The ability to reproduce this exact setup
|
2024-10-27 20:04:13 +00:00
|
|
|
within minutes actually matters.
|
|
|
|
|
2024-10-30 15:46:43 +00:00
|
|
|
After reading a bit on this topic, I decided I would use docker for this. Podman
|
2024-10-28 20:51:06 +00:00
|
|
|
would work just as nicely (any containerization software would work, really),
|
2024-10-30 15:46:43 +00:00
|
|
|
but I decided on docker because it's been the standard for a while now
|
2024-10-27 20:04:13 +00:00
|
|
|
|
|
|
|
## Motivation
|
|
|
|
|
2024-10-30 15:46:43 +00:00
|
|
|
Basically, I'm already running a web server. Why shouldn't I also host several
|
|
|
|
other services for friends and family while I'm at it? Why shouldn't I make the
|
|
|
|
entire setup reproducible?
|
2024-10-27 20:04:13 +00:00
|
|
|
|
|
|
|
Here are some of the services I wanted to self-host:
|
|
|
|
|
2024-10-30 15:46:43 +00:00
|
|
|
- Web server: obviously, who doesn't want a website?
|
|
|
|
- Some git server: having my own place to show off all the things I've done is
|
|
|
|
certainly really cool. For this, something like [Gitea](https://about.gitea.com/)
|
|
|
|
would normally be great. I went with [Gogs](https://gogs.io/) instead, because
|
|
|
|
it is far more lightweight.
|
|
|
|
- Wireguard: Free VPN along with the website? sign me up.
|
|
|
|
- CI/CD: automatic testing and releases of my software is cool, and also
|
|
|
|
incredibly useful.
|
|
|
|
|
|
|
|
Of course, there are always more things I could be self-hosting. So it makes
|
|
|
|
sense to automate the setup, and that's where docker comes in.
|
2024-10-27 20:04:13 +00:00
|
|
|
|
2024-10-30 15:46:43 +00:00
|
|
|
## Basics of docker
|
2024-10-27 20:04:13 +00:00
|
|
|
|
2024-10-30 15:46:43 +00:00
|
|
|
Before we can get to the exciting stuff, we need to go over what docker is, and how to
|
|
|
|
use it. Essentially, docker is a container engine: it lets you build and run
|
|
|
|
applications in a containerized environment. Containers are useful because they
|
|
|
|
provide security, easy setup and most importantly, reproducibility.
|
2024-10-27 20:04:13 +00:00
|
|
|
|
|
|
|
I'm not going to spend any more time explaining what containers are and why they're
|
|
|
|
good, that's been done to death already. Right now, what matters is the actual setup,
|
|
|
|
so let's get on with it.
|
|
|
|
|
|
|
|
If you've used docker before, you'll feel right at home. Many commands are unchanged
|
2024-10-30 15:46:43 +00:00
|
|
|
from docker, making docker a suitable drop-in replacement. Some things like network
|
2024-10-27 20:04:13 +00:00
|
|
|
setups tend to be a little different, but that won't matter too much right now.
|
|
|
|
|
2024-10-30 15:46:43 +00:00
|
|
|
In case you're unfamiliar with docker, here are some basic commands (run these
|
|
|
|
either as root, or as a user in the `docker` group):
|
2024-10-27 20:04:13 +00:00
|
|
|
|
|
|
|
```sh
|
|
|
|
# Search for container images (on docker.io unless you configure otherwise)
|
2024-10-30 15:46:43 +00:00
|
|
|
$ docker search <image name>
|
2024-10-27 20:04:13 +00:00
|
|
|
|
|
|
|
# Download (pull) an image from remote repo
|
2024-10-30 15:46:43 +00:00
|
|
|
$ docker pull <image name>
|
2024-10-27 20:04:13 +00:00
|
|
|
|
|
|
|
# list the images you have pulled.
|
2024-10-30 15:46:43 +00:00
|
|
|
$ docker images
|
2024-10-27 20:04:13 +00:00
|
|
|
|
|
|
|
# run a container.
|
2024-10-30 15:46:43 +00:00
|
|
|
$ docker run <image name>
|
2024-10-27 20:04:13 +00:00
|
|
|
|
|
|
|
# run a container, but with a LOT of flags. I just listed the most useful ones.
|
2024-10-30 15:46:43 +00:00
|
|
|
$ docker run
|
2024-10-27 20:04:13 +00:00
|
|
|
-i # interactive, so you can e.g. run a shell in the container
|
|
|
|
-t # allocates a tty. useful with -i so that shell completion etc. can work
|
|
|
|
-d # opposite of -i, detach and run in the background
|
|
|
|
--port <HOST PORT>:<CONTAINER PORT> # port forwarding, for when you need a server.
|
|
|
|
-v <HOST DIR>:<CONT DIR>:<FLAGS> # give the container access to some directory
|
|
|
|
<image name>
|
|
|
|
<command> # ... want a shell?
|
|
|
|
|
|
|
|
# list running containers. add -a to list ALL containers, running or stopped.
|
2024-10-30 15:46:43 +00:00
|
|
|
$ docker ps <-a>
|
2024-10-27 20:04:13 +00:00
|
|
|
|
|
|
|
# stop a running container.
|
2024-10-30 15:46:43 +00:00
|
|
|
$ docker stop <id>
|
2024-10-27 20:04:13 +00:00
|
|
|
|
|
|
|
# stopped containers don't automatically get removed. This command removes it.
|
2024-10-30 15:46:43 +00:00
|
|
|
$ docker rm <id>
|
2024-10-27 20:04:13 +00:00
|
|
|
```
|
|
|
|
|
2024-10-30 15:46:43 +00:00
|
|
|
## Compose is nice.
|
2024-10-27 20:04:13 +00:00
|
|
|
|
2024-10-30 15:46:43 +00:00
|
|
|
Docker compose is a nice way to essentially "group together" some containers,
|
|
|
|
and ship them in an easy way.
|
2024-10-27 20:04:13 +00:00
|
|
|
|
2024-10-27 20:34:11 +00:00
|
|
|
Usually, on a server, each application *isn't* totally separate from each other
|
2024-10-30 15:46:43 +00:00
|
|
|
- for my own use case, I want my git server (e.g. gogs) to automatically build
|
2024-10-27 20:34:11 +00:00
|
|
|
and update my website whenever I push to its git repository. That means my git
|
2024-10-30 15:18:30 +00:00
|
|
|
server and web server can't be *totally* separate, there's some amount of
|
2024-10-30 15:46:43 +00:00
|
|
|
relation.
|
|
|
|
|
|
|
|
At the same time... I don't really want to set up both containers, then their
|
|
|
|
volumes, and their ports etc. by hand. Sure I could stick it in a shell script,
|
|
|
|
but that's hardly elegant.
|
|
|
|
|
|
|
|
Docker compose helps with this: you can create a
|
|
|
|
`compose.yaml` file, and define containers, ports, volumes, secrets all inside
|
|
|
|
this file. Then, when you run `docker compose up` this configuration is read,
|
|
|
|
and all of it is processed as you would want it to.
|