2024-10-30 15:02:21 +00:00
<!doctype html> < html lang = "en-us" >
2024-10-30 15:19:01 +00:00
< head >
2024-10-30 15:02:21 +00:00
< meta charset = "utf-8" / >
< meta name = "viewport" content = "width=device-width, initial-scale=1.0" / >
< meta http-equiv = "X-UA-Compatible" content = "IE=edge" / >
< meta name = "generator" content = "Qubt theme for Hugo" / >
< title > haxala1r< / title >
< meta name = "title" content = "haxala1r" / >
< meta name = "author" content = "Emin Arslan" / >
< link type = "text/css" rel = "stylesheet" href = "/css/main.bundle.min.955b22a3fcff20511a11d9c7fdac7dd57e8293ee16e4d4ca0d6ab737f4895c3017582739cfd1f17a7c3feae23b42a8f4b01d7052fa2bc03a1430fa0669bf2d60.css" integrity = "sha512-lVsio/z/IFEaEdnH/ax91X6Ck+4W5NTKDWq3N/SJXDAXWCc5z9Hxenw/6uI7Qqj0sB1wUvorwDoUMPoGab8tYA==" / >
< script defer src = "/js/main.bundle.min.4657c962c90bb42241e3db9c00332ac44a2ff6a901654b8248b4e2f4b586571fd2aa672dcadf728d6f2135b0ea6088f21d1cf5302b4cae8557e0593f70081d72.js" integrity = "sha512-RlfJYskLtCJB49ucADMqxEov9qkBZUuCSLTi9LWGVx/Sqmctyt9yjW8hNbDqYIjyHRz1MCtMroVX4Fk/cAgdcg==" > < / script >
2024-10-30 15:19:01 +00:00
< meta property = "og:url" content = "https://emin.software/posts/setup_p1/" >
2024-10-30 15:02:21 +00:00
< meta property = "og:site_name" content = "haxala1r" >
2024-11-13 16:38:13 +00:00
< meta property = "og:title" content = "My Setup " >
2024-10-30 15:46:43 +00:00
< meta property = "og:description" content = "I go over the things I’ ve learned about docker, and how I’ ve used it to host my website." >
2024-10-30 15:02:21 +00:00
< meta property = "og:locale" content = "en_us" >
< meta property = "og:type" content = "article" >
< meta property = "article:section" content = "posts" >
< meta property = "article:published_time" content = "2024-10-25T23:11:17+03:00" >
< meta property = "article:modified_time" content = "2024-10-25T23:11:17+03:00" >
< meta name = "twitter:card" content = "summary" >
2024-11-13 16:38:13 +00:00
< meta name = "twitter:title" content = "My Setup " >
2024-10-30 15:46:43 +00:00
< meta name = "twitter:description" content = "I go over the things I’ ve learned about docker, and how I’ ve used it to host my website." >
2024-10-30 15:02:21 +00:00
< script >
if (localStorage.getItem("color-theme") === "dark" || (!("color-theme" in localStorage) & & window.matchMedia("(prefers-color-scheme: dark)").matches)) {
document.documentElement.classList.add("dark");
} else {
document.documentElement.classList.remove("dark");
}
< / script >
< / head >
< body class = "flex h-screen flex-col justify-between bg-neutral-100 dark:bg-neutral-800" >
< div >
< header class = "sticky top-0 z-10 bg-neutral-100 dark:bg-neutral-800" >
< section class = "mx-auto flex max-w-screen-xl items-center justify-between p-4" >
2024-10-30 15:19:01 +00:00
< a href = "https://emin.software/" class = "flex items-center space-x-3" >
2024-10-30 15:02:21 +00:00
< span class = "self-center whitespace-nowrap text-2xl font-semibold text-slate-700 dark:text-slate-400" >
haxala1r
< / span >
< / a >
< div class = "flex flex-row space-x-8" >
< nav class = "hidden space-x-8 text-xl md:block" aria-label = "main" >
< a href = "/" class = "px-3 py-2 text-slate-700 hover:text-indigo-500 md:p-0 dark:text-slate-400" >
Home
< / a >
< a href = "/about/" class = "px-3 py-2 text-slate-700 hover:text-indigo-500 md:p-0 dark:text-slate-400" >
About
< / a >
< a href = "/posts/" class = "px-3 py-2 text-slate-700 hover:text-indigo-500 md:p-0 dark:text-slate-400" >
Posts
< / a >
< / nav >
< button id = "theme-toggle" type = "button" class = "rounded-lg text-sm text-slate-700 hover:text-indigo-500 dark:text-slate-400" aria-label = "theme-switcher" >
< svg id = "theme-toggle-dark-icon" class = "hidden h-6 w-6" fill = "currentColor" viewBox = "0 0 20 20" xmlns = "http://www.w3.org/2000/svg" >
< path d = "M17.293 13.293A8 8 0 016.707 2.707a8.001 8.001 0 1010.586 10.586z" > < / path >
< / svg >
< svg id = "theme-toggle-light-icon" class = "hidden h-6 w-6" fill = "currentColor" viewBox = "0 0 20 20" xmlns = "http://www.w3.org/2000/svg" >
< path
d="M10 2a1 1 0 011 1v1a1 1 0 11-2 0V3a1 1 0 011-1zm4 8a4 4 0 11-8 0 4 4 0 018 0zm-.464 4.95l.707.707a1 1 0 001.414-1.414l-.707-.707a1 1 0 00-1.414 1.414zm2.12-10.607a1 1 0 010 1.414l-.706.707a1 1 0 11-1.414-1.414l.707-.707a1 1 0 011.414 0zM17 11a1 1 0 100-2h-1a1 1 0 100 2h1zm-7 4a1 1 0 011 1v1a1 1 0 11-2 0v-1a1 1 0 011-1zM5.05 6.464A1 1 0 106.465 5.05l-.708-.707a1 1 0 00-1.414 1.414l.707.707zm1.414 8.486l-.707.707a1 1 0 01-1.414-1.414l.707-.707a1 1 0 011.414 1.414zM4 11a1 1 0 100-2H3a1 1 0 000 2h1z"
fill-rule="evenodd"
clip-rule="evenodd">< / path >
< / svg >
< / button >
< button id = "hamburger-button" class = "relative h-8 w-8 cursor-pointer text-3xl md:hidden" aria-label = "hamburger-button" >
< div
class="absolute top-4 -mt-0.5 h-[3px] w-8 rounded bg-slate-700 transition-all duration-500 before:absolute before:h-[3px] before:w-8 before:-translate-x-4 before:-translate-y-2.5 before:rounded before:bg-slate-700 before:transition-all before:duration-500 before:content-[''] after:absolute after:h-[3px] after:w-8 after:-translate-x-4 after:translate-y-2.5 after:rounded after:bg-slate-700 after:transition-all after:duration-500 after:content-[''] dark:bg-slate-400 before:dark:bg-slate-400 after:dark:bg-slate-400">< / div >
< / button >
< / div >
< / section >
< section id = "mobile-menu" class = "absolute hidden w-full origin-top animate-open-menu flex-col justify-center bg-neutral-100 text-4xl dark:bg-neutral-800" >
< nav class = "flex min-h-screen flex-col items-center py-8" aria-label = "mobile" >
< a href = "/" class = "px-3 py-2 text-center text-slate-700 hover:text-indigo-500 md:p-0 dark:text-slate-400" >
Home
< / a >
< a href = "/about/" class = "px-3 py-2 text-center text-slate-700 hover:text-indigo-500 md:p-0 dark:text-slate-400" >
About
< / a >
< a href = "/posts/" class = "px-3 py-2 text-center text-slate-700 hover:text-indigo-500 md:p-0 dark:text-slate-400" >
Posts
< / a >
< / nav >
< / section >
< / header >
< main >
< div class = "justify-left mx-auto mt-8 flex max-w-screen-md px-4" >
< article >
< h1 class = "text-4xl font-extrabold text-slate-700 dark:text-slate-200" >
2024-11-13 16:38:13 +00:00
My Setup
2024-10-30 15:02:21 +00:00
< / h1 >
< h2 class = "mt-4 text-2xl text-slate-500 dark:text-slate-400" >
2024-11-13 16:38:13 +00:00
Containers! Docker!
2024-10-30 15:02:21 +00:00
< / h2 >
< div class = "mb-4 mt-2 text-sm text-slate-500 dark:text-slate-400" >
2024-11-13 16:38:13 +00:00
Oct 25, 2024 - 6 minute read
2024-10-30 15:02:21 +00:00
< / div >
< span class = "prose prose-slate break-words text-lg text-slate-700 dark:prose-invert prose-pre:max-w-[90vw] md:prose-pre:max-w-screen-md dark:text-slate-200" >
< h1 id = "my-setup" > My Setup< / h1 >
< p > In this ‘ series’ I will be walking you through my process of how I
host everything on this server.< / p >
< p > I’ m currently running, on top of < a href = "https://emin.software" > my blog< / a > , a < a href = "https://git.emin.software" > gogs
instance< / a > .< / p >
< p > When first creating this website, I just had my blog. I generated this blog
using < a href = "https://hugo.io" > hugo< / a > : 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.< / p >
< p > 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.< / p >
< p > This is a cumbersome process. The whole point of using hugo is to < em > focus on the
2024-10-30 15:18:30 +00:00
writing< / em > , so having to zip and reupload for every typo is… not great. I
2024-10-30 15:02:21 +00:00
wanted to be able to do a simple < code > git push< / code > , and not worry about the rest.< / p >
2024-10-30 15:46:43 +00:00
< p > The “ manual” approach also depends on me having already installed all
2024-10-30 15:02:21 +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
that I’ m not sure I’ ll keep forever. The ability to reproduce this exact setup
within minutes actually matters.< / p >
2024-10-30 15:46:43 +00:00
< p > After reading a bit on this topic, I decided I would use docker for this. Podman
2024-10-30 15:02:21 +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< / p >
2024-10-30 15:02:21 +00:00
< h2 id = "motivation" > Motivation< / h2 >
2024-10-30 15:46:43 +00:00
< p > 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?< / p >
< p > Here are some of the services I wanted to self-host:< / p >
< ul >
< li > Web server: obviously, who doesn’ t want a website?< / li >
< li > Some git server: having my own place to show off all the things I’ ve done is
certainly really cool. For this, something like < a href = "https://about.gitea.com/" > Gitea< / a >
would normally be great. I went with < a href = "https://gogs.io/" > Gogs< / a > instead, because
it is far more lightweight.< / li >
< li > Wireguard: Free VPN along with the website? sign me up.< / li >
< li > CI/CD: automatic testing and releases of my software is cool, and also
incredibly useful.< / li >
< / ul >
< p > 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.< / p >
< h2 id = "basics-of-docker" > Basics of docker< / h2 >
< p > 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.< / p >
2024-10-30 15:02:21 +00:00
< p > 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.< / p >
< p > 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-30 15:02:21 +00:00
setups tend to be a little different, but that won’ t matter too much right now.< / p >
2024-10-30 15:46:43 +00:00
< p > In case you’ re unfamiliar with docker, here are some basic commands (run these
either as root, or as a user in the < code > docker< / code > group):< / p >
2024-10-30 15:02:21 +00:00
< div class = "highlight" > < pre tabindex = "0" style = "color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;" > < code class = "language-sh" data-lang = "sh" > < span style = "display:flex;" > < span > < span style = "color:#75715e" > # Search for container images (on docker.io unless you configure otherwise)< / span >
2024-10-30 15:46:43 +00:00
< / span > < / span > < span style = "display:flex;" > < span > $ docker search < image name>
2024-10-30 15:02:21 +00:00
< / span > < / span > < span style = "display:flex;" > < span >
< / span > < / span > < span style = "display:flex;" > < span > < span style = "color:#75715e" > # Download (pull) an image from remote repo< / span >
2024-10-30 15:46:43 +00:00
< / span > < / span > < span style = "display:flex;" > < span > $ docker pull < image name>
2024-10-30 15:02:21 +00:00
< / span > < / span > < span style = "display:flex;" > < span >
< / span > < / span > < span style = "display:flex;" > < span > < span style = "color:#75715e" > # list the images you have pulled.< / span >
2024-10-30 15:46:43 +00:00
< / span > < / span > < span style = "display:flex;" > < span > $ docker images
2024-10-30 15:02:21 +00:00
< / span > < / span > < span style = "display:flex;" > < span >
< / span > < / span > < span style = "display:flex;" > < span > < span style = "color:#75715e" > # run a container.< / span >
2024-10-30 15:46:43 +00:00
< / span > < / span > < span style = "display:flex;" > < span > $ docker run < image name>
2024-10-30 15:02:21 +00:00
< / span > < / span > < span style = "display:flex;" > < span >
< / span > < / span > < span style = "display:flex;" > < span > < span style = "color:#75715e" > # run a container, but with a LOT of flags. I just listed the most useful ones.< / span >
2024-10-30 15:46:43 +00:00
< / span > < / span > < span style = "display:flex;" > < span > $ docker run
2024-10-30 15:02:21 +00:00
< / span > < / span > < span style = "display:flex;" > < span > -i < span style = "color:#75715e" > # interactive, so you can e.g. run a shell in the container< / span >
< / span > < / span > < span style = "display:flex;" > < span > -t < span style = "color:#75715e" > # allocates a tty. useful with -i so that shell completion etc. can work< / span >
< / span > < / span > < span style = "display:flex;" > < span > -d < span style = "color:#75715e" > # opposite of -i, detach and run in the background< / span >
< / span > < / span > < span style = "display:flex;" > < span > --port < HOST PORT> :< CONTAINER PORT> < span style = "color:#75715e" > # port forwarding, for when you need a server.< / span >
< / span > < / span > < span style = "display:flex;" > < span > -v < HOST DIR> :< CONT DIR> :< FLAGS> < span style = "color:#75715e" > # give the container access to some directory< / span >
< / span > < / span > < span style = "display:flex;" > < span > < image name>
< / span > < / span > < span style = "display:flex;" > < span > < command> < span style = "color:#75715e" > # ... want a shell?< / span >
< / span > < / span > < span style = "display:flex;" > < span >
< / span > < / span > < span style = "display:flex;" > < span > < span style = "color:#75715e" > # list running containers. add -a to list ALL containers, running or stopped.< / span >
2024-10-30 15:46:43 +00:00
< / span > < / span > < span style = "display:flex;" > < span > $ docker ps < -a>
2024-10-30 15:02:21 +00:00
< / span > < / span > < span style = "display:flex;" > < span >
< / span > < / span > < span style = "display:flex;" > < span > < span style = "color:#75715e" > # stop a running container.< / span >
2024-10-30 15:46:43 +00:00
< / span > < / span > < span style = "display:flex;" > < span > $ docker stop < id>
2024-10-30 15:02:21 +00:00
< / span > < / span > < span style = "display:flex;" > < span >
< / span > < / span > < span style = "display:flex;" > < span > < span style = "color:#75715e" > # stopped containers don' t automatically get removed. This command removes it.< / span >
2024-10-30 15:46:43 +00:00
< / span > < / span > < span style = "display:flex;" > < span > $ docker rm < id>
< / span > < / span > < / code > < / pre > < / div > < h2 id = "compose-is-nice" > Compose is nice.< / h2 >
< p > Docker compose is a nice way to essentially “ group together” some containers,
and ship them in an easy way.< / p >
2024-10-30 15:02:21 +00:00
< p > Usually, on a server, each application < em > isn’ t< / em > totally separate from each other< / p >
< ul >
2024-10-30 15:46:43 +00:00
< li > for my own use case, I want my git server (e.g. gogs) to automatically build
2024-10-30 15:02:21 +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 < em > totally< / em > separate, there’ s some amount of
2024-10-30 15:46:43 +00:00
relation.< / li >
2024-10-30 15:02:21 +00:00
< / ul >
2024-10-30 15:46:43 +00:00
< p > 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.< / p >
< p > Docker compose helps with this: you can create a
< code > compose.yaml< / code > file, and define containers, ports, volumes, secrets all inside
this file. Then, when you run < code > docker compose up< / code > this configuration is read,
and all of it is processed as you would want it to.< / p >
2024-11-13 16:38:13 +00:00
< p > e.g you might have this for starting a web server on port 3000:< / p >
< div class = "highlight" > < pre tabindex = "0" style = "color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;" > < code class = "language-yaml" data-lang = "yaml" > < span style = "display:flex;" > < span > < span style = "color:#f92672" > services< / span > :
< / span > < / span > < span style = "display:flex;" > < span > < span style = "color:#f92672" > web< / span > :
< / span > < / span > < span style = "display:flex;" > < span > < span style = "color:#f92672" > image< / span > : < span style = "color:#e6db74" > " nginx" < / span >
< / span > < / span > < span style = "display:flex;" > < span > < span style = "color:#f92672" > ports< / span > :
< / span > < / span > < span style = "display:flex;" > < span > - < span style = "color:#ae81ff" > 3000< / span > :< span style = "color:#ae81ff" > 80< / span >
< / span > < / span > < / code > < / pre > < / div > < p > Or you could even have < em > two< / em > servers, like, a gogs and a web server!< / p >
< div class = "highlight" > < pre tabindex = "0" style = "color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;" > < code class = "language-yaml" data-lang = "yaml" > < span style = "display:flex;" > < span > < span style = "color:#f92672" > services< / span > :
< / span > < / span > < span style = "display:flex;" > < span > < span style = "color:#f92672" > web< / span > :
< / span > < / span > < span style = "display:flex;" > < span > < span style = "color:#f92672" > image< / span > : < span style = "color:#e6db74" > " nginx" < / span >
< / span > < / span > < span style = "display:flex;" > < span > < span style = "color:#f92672" > ports< / span > :
< / span > < / span > < span style = "display:flex;" > < span > - < span style = "color:#ae81ff" > 80< / span > :< span style = "color:#ae81ff" > 80< / span >
< / span > < / span > < span style = "display:flex;" > < span > < span style = "color:#f92672" > gogs-haha< / span > :
< / span > < / span > < span style = "display:flex;" > < span > < span style = "color:#f92672" > image< / span > : < span style = "color:#e6db74" > " gogs/gogs" < / span >
< / span > < / span > < span style = "display:flex;" > < span > < span style = "color:#f92672" > ports< / span > :
< / span > < / span > < span style = "display:flex;" > < span > - < span style = "color:#ae81ff" > 3000< / span > :< span style = "color:#ae81ff" > 3000< / span >
< / span > < / span > < span style = "display:flex;" > < span > - < span style = "color:#ae81ff" > 3022< / span > :< span style = "color:#ae81ff" > 22< / span >
< / span > < / span > < / code > < / pre > < / div > < p > See how we got multiple services to run, very very easily? Isn’ t that just
really nice? You can just keep adding stuff. And compose even sets up dns for
these containers! That means, for example, you can have your web server act as
a reverse proxy by having it access http://gogs-haha:3000 in the above config!
It just works!< / p >
< p > Of course, you can add volumes to tie it all, and ‘ secrets’ to manage sensitive
files (like keys and certificates). I won’ t go into those here though.< / p >
< h1 id = "conclusion" > Conclusion< / h1 >
< p > Docker and Docker Compose are a lot more useful than my younger self would have
given them credit for. It was really fun learning about them, and hopefully I’ ll
use this knowledge in the future.< / p >
< p > Thank you for reading.< / p >
2024-10-30 15:02:21 +00:00
< / span >
< / article >
< / div >
< / main >
< / div >
< footer >
< div class = "flex flex-col justify-center p-10" >
< p class = "text-center text-slate-700 dark:text-slate-400" >
©
2024
Emin Arslan
< / p >
< p class = "text-center text-sm text-slate-700 dark:text-slate-400" >
Published with < a class = "hover:underline hover:decoration-indigo-500 hover:text-indigo-500" href = "https://gohugo.io" target = "_blank" rel = "noopener noreferrer" > Hugo< / a > & < a class = "hover:underline hover:decoration-indigo-500 hover:text-indigo-500" href = "https://github.com/chrede88/qubt" target = "_blank" rel = "noopener noreferrer" > Qubt< / a >
< / p >
< / div >
< / footer >
< / body >
< / html >