Compare commits

..

4 Commits

Author SHA1 Message Date
30fd515635 fix: remove link to never-seen-before post 2025-04-13 19:50:01 +02:00
aed85865a9 feat: I found my old blog
It only had 2 posts, but whatever
2025-04-13 19:50:01 +02:00
23ea4544fd wip: neorg migration 2025-04-13 19:50:01 +02:00
c37d880506 wip: feat: xbox modding post 2025-01-27 20:45:02 +01:00
7 changed files with 7 additions and 632 deletions

View File

@ -13,21 +13,12 @@ docker run --rm -it -p 8080:8080 wip hugo serve --bind 0.0.0.0 --port 8080
### Opinion Pieces
- [ ] Clean Architecture is stupid - dependency injection is king
- [ ] Neorg is bad, actually - ?? is king
- [ ] Clean Architecture is stupid and overly complicated - dependency injection is king
- [ ] For want of a neater (human) internet
- [ ] A truly FOSS printer.
even the hardware should be FOSS. - most parts should be 3d printable.
should be a laser printer, as inkjet is stupid.
- [ ] A truly FOSS eink reader.
- [ ] VIM Bindings everywhere please
- [ ] trying to use a MIDI controller as a piano on Linux is insanity
### Digital Soverignty
- [x] how to host a blog
- [ ] how to securely "self-host" using a VPS, portainer and traefik
- [x] how to configure neomutt
- [ ] how to configure neomutt
- [ ] how to securely host a mail server
- [ ] how to private tracker with a NAS
### Old sillyblog
- [x] Avr memory model

View File

@ -3,10 +3,10 @@ title: About gtz blog
author: Asger Gitz-Johansen
---
I am a software engineer from Denmark working at [GomSpace](https://gomspace.com/home.aspx). This is just my simple
blog that I use for letting out "blogging-steam". I write GNU/Linux based tutorials and sometimes I write opinion
pieces. These posts are mostly for my own sake, but I hope you find my stuff useful.
I am a software engineer from Denmark working at [GomSpace](https://gomspace.com/home.aspx).
This is just my simple blog that I use for letting out "blogging-steam".
I write GNU/Linux based tutorials and sometimes I write opinion pieces.
I hope you find my stuff useful.
If you want more from me, check my links:
- [GitHub](https://github.com/sillydan1)

View File

@ -69,7 +69,7 @@ gdb: > x/16xb my_heap_object
```
The first bytes at address `0x800100` are `0a` and `00`. These bytes are the *free-list* entry and explains how "big"
the object is. When reading this, we have to remember that the model is little endian-based (meaning that the bytes are
the object is. When reading this, we have to remember that the model is littleengine-based (meaning that the bytes are
switched),
so we actually have the value of `0x000a`, meaning `10` in decimal. This makes a lot of sense, since we allocated 5
`int`s, that is of size 2 (16bit integers).

View File

@ -1,90 +0,0 @@
+++
date = '2018-05-10'
draft = false
title = 'Computation in Nature'
tags = ['philosophy', 'old']
categories = ['opinion']
+++
## Disclaimer
This was written as a student project as part of our ethics course, where we had to write an opinion piece on anything
we wanted in the field of computer science. Note that this was before *LLM*'s was a thing. I also apologize if the
wording is off - this was written in an afternoon as a rush-job. I still think it's an interesting read though.
# Computation in Nature
> "If you ever think your code is bad, just remember that CPUs are just rocks that we tricked into thinking"
**Does nature compute, or is computation something that only humans are doing? If so, what is it about?**
To answer this question, we would need to define what the terms used in it even means. If you look up the definition
of the word compute on Merriam Websters dictionary, you find that it primarily means _"to determine
especially by mathematical means"_. This definition mentions a usage of mathematics, which suggests a close bond
between these concepts. What would it mean to determine something? I would argue that it means to make a decision
based on either prior experience, data or calculations. This implies that computation have a focus on deciding
and _"finishing a thought"_. It has an end goal. You can even use conclusions made by previous computations to
compute more advanced problems.
In other words, computation is about answering queries about data and the process of doing so. We see
mathematics emerge in nature aswell. In
[The Chemical Basis of Morphogenesis](https://www.dna.caltech.edu/courses/cs191/paperscs191/turing.pdf), Alan M. Turing
mentions that flower petals rarely exceeds a quantity of five. We even see the fibonacci sequence in [sunflower
seeds](http://popmath.org.uk/rpamaths/rpampages/sunflower.html).
An example of computation in nature is actually very easy to find. Take a rabbit, or any other smaller prey. A rabbit
is constantly observing and reacting to the sorrounding environment, otherwise it gets eaten by predators or fall
into a lake and drown or any other scenario involving death. You could argue that the rabbit is constantly asking
questions about what to: _"Should I run away?"_, _"Should I keep eating?"_, _"Should I be eating this?"_ etc. The
rabbit may not be consciously aware of these queries, but nevertheless, it is answering to them through actions.
In Empiricism, the concept of a mind being a blank slate (in this case we are talking about a human mind, not
a rabbits), which remembers experiences throughout it's life is very much applicable here. This trait means that a
human mind has a memory, i.e. It can remember old conclusions and recall them when desired. We can actually prove that
this trait is not exclusive to humans, since we can observe other mammals (and even fish and reptiles) demonstrating
the usage of memory. A prime example is the elephant, but pretty much any animal applies here.
In Rationalism, we see a similar pattern that mimics memory - using the method of deduction to find conclusions and
deduct new conclusions. However, if you were to believe the Rationalists, getting the data needed for computation
in nature, may be a tricky task. We previously had an assumption that we could trust our senses and that other
creatures also had senses. In Rationalism the only thing we can trust is the fact that we are doubting. Since we
cant say anything about if the rabbit is doubting everything. This is where the rabbit example breaks down a
little, but we are not completely stuck here. Humans are mammals and mammals are a type of animal. Animals are
part of nature, therefore humans must be part of nature. You and I are humans (I assume) and this logic enables us
to make deductive arguments based on subjective thoughts. The first part of the Cartesian circle, _"Dubito ergo
cogito"_ (_"I doubt, therefore I think"_) made by René Descartes, is actually very applicable to computation in
nature. Thinking is a form of computation and since _I_ am part of nature. Computation rationally happens in nature.
But what about non-natural computation? Artificial computation machines such as modern digital computers or even
old mechanical adding-machines are definitely things that compute data. There is a diconnect from artificial
computers to natural computers (brains) though. Currently humans have not been able to produce a machine with natural
intuition as we observe it in nature. We have come close to something that looks like it with simulated organisms,
but we are not even close to the complexeties of an intuitive brain such as the human one (or even other clever
mammals, such as the dolphin or chimp). I personally believe that the reason for this disconnect is because of
the intention of the computational device at the point of origin. The intent that biology had when brains were
invented was certainly not to fix mathematical problems. It was primarily for the organism to survive and have a
better chance for survival. But fixing mathematical problems is the exact intent humans had when we created our
artificial computers. This **intent** changes the very nature of the system, and because of this, even though brains
and computers might be similar in some ways they are and always will be fundamentally different things.
A. M. Turing presents (and disagrees with) various arguments, in his article
[Computing Machinery and Intelligence](https://archive.org/details/MIND--COMPUTING-MACHINERY-AND-INTELLIGENCE),
that a computer will not be able to be conscious. I tend to follow Turings idea that most of the arguments he
presents are either made out of a tendency towards thinking that humans have to be superior to machines, either
intellectually or that we can *feel* things. I do disagree with one point that he makes in the article: Turing
argues that a computer/program will never be able to change its behavior based off of prior experiences, which
sounds ludicrous if youve taken any modern Machine Intelligence class. This was probably a conclusion he came
to because of the time era he was in and that AI as a field was not as big (if at all existent) at the time.
Turing finishes the article with the notion that there is still a lot of work to be done in the field of AI and it
is a fun contrast to see what arguments and thoughts a mind like his had back in the fifties, compared to modern
AI can offer. Will humans ever be able to create a truly conscious artificial mind? And will we ever be able to
test it properly?
If you believe the Mathematical Realists, mathematics is a thing that exists independently of humans, and can be
found/discovered by any being clever enough to deduct these laws. This point of view can be very reassuring, if
you believe that real artificial intelligence can be made. Since mathematics is an inherit trait of the universe,
and that computers are machines that can (essentially) execute math, and that humans are part of nature. It might
be possible to make an AI that is (atleast) as clever as humans, maybe it is innevitable.
{{< centered image="/6616144.png" >}}

View File

@ -1,210 +0,0 @@
+++
date = '2025-04-15'
draft = true
title = "How to Set Up Crowdsec"
tags = ["howto", "tutorial", "web", "securoty"]
categories = ["technical"]
+++
## Crowdsec
> NOTE: This configuration blocks *many* varieties of clients and services. You might want to whitelist your own ISP and
> / or your own IP ranges (perhaps even your entire country if you're trusting enough) in case your own services and
> homebrew experiments gets banned.
Short for [crowdsecurity](https://www.crowdsec.net/), crowdsec is a community effort to bring auto-banning security to
the masses, and it's surprisingly easy to set up. You just have to understand how the thing works.
I noticed that I am getting a lot of suspicious traffic on my gitea instance. Usernames such as `log4j` and `thomad`
from china and bulgaria. Yea. Let's enable some fucking security.
Fuck I hate that I have to do this, but I guess people will be assholes.
After [this](https://www.youtube.com/watch?v=-GxUP6bNxF0), the banhammer came down with the might of zeus. Now no-one
gets access. Not even me. I tried to do some country-code whitelisting, but that was a bit of a dud. I'm tired now.
Will look at it tomorrow.
Okay! I seem to have it working now! That was an adventure. Will elaborate when I get back home.
Okay, There's multiple "things" to a crowdsec setup. Crowdsec (the non-paid cloud solution) consists of:
- The core crowdsec security engine (`crowdsecurity/crowdsec` container image)
- Does the "detection" and hardcore logic and makes decisions.
- The bouncer (`fbonalair/traefik-crowdsec-bouncer:latest` container image in my case)
- Enforces the decisions.
- There are multiple different "types" of bouncers. I just use the forwardAuth type, as that is the most straight
forward one. Especially when combined with traefik.
### Concepts
In short, there are only a couple of concepts you should know in order to *use* crowdsec. This is
Feel free to skip these if you
don't care for now, and just want something up and running.
- Acquisitions
- In order for `crowdsec` to know *what* and *where* to look for potential intruders, threats etc. You must tell it
in the form of *acquisition* configurations. The easiest thing to do is to just give `crowdsec` access to your docker
logs and traefik logs - this is excactly what we're aiming to do.
- Parsers
- Bucket Overflow
- Bouncers
Note that the core crowdsec security engine should be part of the core traefik/portainer deployment because it will
need some elevated privileges. The traefik service should also register some middlewares, so it can't be part of the
portainer managed containers / stacks.
When using Traefik, make sure to add the docker labels that enable traefik trafficing to the containers:
```yaml
# For the new containers.
labels:
- traefik.enable=true
- traefik.docker.network=proxy
- traefik.http.routers.traefik-bouncer.entrypoints=websecure
```
## "easy"
This shit was not easy to set up. But it is easy to maintain. Keep a "new"/"learning" mind, and all should be fine.
## Configuring the Bouncer
Also called "Remediation"
I am using the traefik bouncer, that is using
[forwardAuth](https://doc.traefik.io/traefik/middlewares/http/forwardauth/) to check if an IP is blocked or not.
Configure the container in docker compose and afterwards, you should introduce the traefik middleware in the dynamic
and static configuration, like so:
```yaml
# dynamic traefik config
http:
middlewares:
traefikBouncer:
forwardauth:
address: http://traefik-bouncer:8080/api/v1/forwardAuth
trustForwardHeader: true
```
```yaml
# static traefik config
entryPoints:
http:
address: ":80"
http:
middlewares:
- traefikBouncer@file
https:
address: ":443"
http:
middlewares:
- traefikBouncer@file
```
If you have (I do) some other names for the `address: ":443"` and `":80"` middlewares, don worry, just add the
`traefikBouncer@file` to the list of middlewares and you should be good.
You will have to register your bouncer through the `cscli` as well:
```sh
docker exec crowdsec cscli bouncers list
docker exec crowdsec cscli bouncers add traefikBouncer
```
This should give you an API key. Place it in the environment variable `CROWDSEC_BOUNCER_API_KEY: <your-key-here>`.
Additionally, you should add the `CROWDSEC_AGENT_HOST: crowdsec:8080` environment variable (assuming the crowdsec
docker _service_ is called `crowdsec`) - the port is standard and you don't need to portmap or expose anything btw.
### Crowdsec Core Security Engine Configuration
In order for the crowdsec security engine to be able to detect intruders, it needs access to the logs of the other
containers on the server. To do this, you can just volume mount: `/var/run/docker.sock:/var/run/docker.sock:ro` and
then
Check out [https://app.crowdsec.net/hub/configurations](https://app.crowdsec.net/hub/configurations) if there are logparsers available for the service you want
to integrate.
#### Acquisitions
In the `acquis.d` directory (volume mapped into the `crowdsec` container to `./acquis.d:/etc/crowdsec/acquis.d`),
you should add YAML files for each source you want the crowdsec engine to scan for criminals and other scum:
```txt
acquis.d/
├── gitea.yaml
└── traefik.yaml
```
File Contents:
```yaml
# traefik.yaml
filenames:
- /var/log/traefik/*
labels:
type: traefik
```
```yaml
# gitea.yaml
source: docker
container_name:
- gitea
labels:
type: gitea
```
`traefik.yml` is a `filename` based acquisition file, meaning you need to configure the `traefik` container to
output access and system logs into a directory that is volume-mapped so that it's available to the crowdsec
container (`traefik-logs:/var/log/traefik/:ro` and associated `traefik-logs:/var/log/traefik/` on traefik).
The acquisition file for the `gitea` service is using the `docker` source. So it'll read the `docker logs`. The
cool thing about this, is that you dont have to do any extra configuration on the gitea side.
To configure `traefik` to output logs into a file (default it just outputs to stdout/stderr for no-one to read),
add the following to your static config (`traefik.yml`) - make sure to `docker compose up -d --force-recreate`
every time you edit the config (and want to apply the changes):
```yaml
# ... at the end of traefik.yml
log:
level: INFO
filePath: /var/log/traefik/traefik.log
accessLog:
filePath: /var/log/traefik/access.log
```
Also, in docker compose file, install some collections:
```yaml
# in crowdsec container spec
environment:
GID: "$(GID-1000)"
COLLECTIONS: "crowdsecurity/linux crowdsecurity/traefik crowdsecurity/whitelist-good-actors LePresidente/gitea"
```
#### Geofenching
You might have lost the bouncer - check with `docker exec crowdsec cscli bounders list`.
I am hosting some services that may produce some false-flags by crowdsec, so I will be whitelisting my country. To
do this, we need to register a country-code whitelist
[postoverflow](https://docs.crowdsec.net/docs/whitelist/create_postoverflow/) in the `postoverflows` directory,
which is volume mapped `./postoverflows:/etc/crowdsec/postoverflows/`:
```yaml
# postoverflow/s01-whitelist/sc-countries-whitelist.yaml
name: my/whitelist
description: Whitelist trusted regions
whitelist:
reason: Whitelisted country
expression:
- "evt.Enriched.IsoCode == 'DK'" # NO! Not anymore!
```
Note that the data is not "enriched" with the IsoCode yet. You need to install the `geoip-enrich` thing:
```sh
docker exec crowdsec cscli parsers install crowdsecurity/geoip-enrich
```
This solution is not very sophisticated, so I might change this to something less "sledgehammer"-y in the future.

View File

@ -1,316 +0,0 @@
+++
date = '2025-04-14'
draft = true
title = "How to Host Docker Containers Easily in The Cloud"
tags = ["howto", "tutorial", "web"]
categories = ["technical"]
+++
In this post, we will be going over how to set up a [portainer](https://www.portainer.io/) managed docker environment,
and how to use it. This is ideal if you want to host a personal website, a [blog](/posts/how-to-blog), a personal
[github](git.gtz.dk) or whatever your development heart desire.
If you choose to follow along, by the end of it, you will have an environment where you can just add or remove docker
based services at a whim using a nice web-based interface.
I assume that you already know about `docker` and `docker compose` yaml syntax. If you don't, may I recommend the
wonderful official [docker tutorial](https://docs.docker.com/get-started/workshop/) - once you're done with that come
back here. Or just read on and roll with the punches.
Oh yea, you should also have good knowledge and experience working on GNU/Linux systems, as you'll be doing a lot of
management and interaction with the terminal both during the setup process and during maintenance.
## Server
The very first thing to get is a server. This can either be the machine you're currently using if you don't want
to mess around on the public internet, or it could be an actual desktop you have set up with a public IP. Or
it could be a VPS (Virtual Private Server) - which is just a fancy word for a "cloud computer" that someone
else hosts and powers, and you just get an SSH connection to it. Any VPS provider will work, but [digital
ocean](https://www.digitalocean.com/) or [linode](https://www.linode.com/) are very affordable and easy to use
VPS providers. As long as you get a VPS and avoid a *webhotel*, you should be fine (side note: web hotels are a
scam and you shouldn't ever use them - especially not if you're tech-savvy enough to read this blog).
Once you have your server, [install](https://docs.docker.com/engine/install/) docker on it. Preferably the latest
version.
## Traefik and Portainer
Traefik is a load balancer / application proxy that makes it easy for you to route network traffic into your various
services on your server. By using traefik, you can have multiple docker containers, each providing their own service on
a single server, and traefik just routes user traffic based on the URL request, or ports used.
Portainer is a web-based docker container management GUI (Graphical User Interface) - if you've tried Docker Desktop,
think if portainer as a web-based version of that.
Getting traefik and portainer up and runinng is done by creating a new `docker-compose.yml` file on your server
and adding them as individual services. Just to keep things tidy, you should make a directory for all you are
going to do here. Do the following on your server.
```sh
# Make the config directory in your $HOME dir - this is where
# we'll be working throughout the tutorial. If not specified
# otherwise, you should only be editing files inside this directory.
mkdir -p ~/config
mkdir -p ~/config/traefik-data
mkdir -p ~/config/portainer-data
cd ~/config
# Create an empty yaml file
touch docker-compose.yml
```
It might be a good idea to initialize the `config` directory as a (local) `git` project. That way you will always have
a history of what you have been done, and what you did when you (inevitably) break things. This I will leave up to you
though (you should gitignore the `portainer-data` directory, since that's managed by portainer and may contain a bunch
of stuff you don't want).
Inside the new `docker-compose.yml` file, you should put the following content. Simply open the file using your favorite
terminal text editor and paste the following. Note! Don't start the stack yet - we still need to configure a bunch of
things.
```yaml
services:
traefik:
image: traefik:latest
container_name: traefik
restart: unless-stopped
security_opt:
- no-new-privileges:true
networks:
- proxy
ports:
- 80:80
- 443:443
volumes:
- /etc/localtime:/etc/localtime:ro
- /var/run/docker.sock:/var/run/docker.sock:ro
- ./traefik-data/traefik.yml:/traefik.yml:ro
- ./traefik-data/acme.json:/acme.json
- ./traefik-data/configurations:/configurations
labels:
- traefik.enable=true
- traefik.docker.network=proxy
- traefik.http.routers.traefik-secure.entrypoints=websecure
- traefik.http.routers.traefik-secure.rule=Host(`traefik.example.com`)
- traefik.http.routers.traefik-secure.service=traefik
- traefik.http.routers.traefik-secure.middlewares=user-auth@file
- traefik.http.routers.traefik-secure.service=api@internal
environment:
- "CF_DNS_API_TOKEN=" # ADD YOUR OWN DNS API TOKEN HERE
- "CF_ZONE_API_TOKEN=" # ADD YOUR OWN DNS API TOKEN HERE
portainer:
image: portainer/portainer-ce:alpine
container_name: portainer
restart: unless-stopped
security_opt:
- no-new-privileges:true
networks:
- proxy
volumes:
- /etc/localtime:/etc/localtime:ro
- /var/run/docker.sock:/var/run/docker.sock:ro
- ./portainer-data:/data
labels:
- traefik.enable=true
- traefik.docker.network=proxy
- traefik.http.routers.portainer-secure.entrypoints=websecure
- traefik.http.routers.portainer-secure.rule=Host(`portainer.example.com`)
- traefik.http.routers.portainer-secure.service=portainer
- traefik.http.services.portainer.loadbalancer.server.port=9000
networks:
proxy:
external: true
```
Whew! That's a lot. Let's break it down. We define two services `traefik` and `portainer`. Starting with the things that
are common to both of them, we set the initial niceties, such as the `container_name`, restart policy, security options
and set their shared network to be the externally defined `proxy` network. Both services need (read-only) access to the
system time for various reasons, so we volume mount `/etc/localtime` to their respective internal `/etc/localtime`. They
also both need access to the system docker socket, so we also volume mount that in (again, read-only). Then we map the
various configuration directories to their respective services.
If you haven't used `traefik` before, you might be scratching your head on the `labels` that we set on each of the
services. This is just how you configure services to integrate into traefik, enabling you to route your various
containers to various subdomains, integrate middle-wares such as forcing HTTPS and setting load-balancer settings etc.
The `CF_DNS_API_TOKEN` and `CF_ZONE_API_TOKEN` tokens are our cloudflare API keys. If you're using a different DNS
provider, you should check the [traefik documentation](https://doc.traefik.io/traefik/https/acme/#providers) to see if
your provider is supported, and change the environment variable names accordingly.
Since the configuration directories are currently empty, the setup won't work yet. Let's add the traefik configuration
files first:
```sh
cd ~/config/traefik-data
mkdir -p configurations
touch traefik.yml
touch configurations/dynamic.yml
```
The `traefik.yml` file contains your general traefik configuration. This is where you register certificates, enforce
HTTPS and set general settings. The content we're interested in having is the following:
```yaml
api:
dashboard: true
entryPoints:
web:
address: ":80"
http:
redirections:
entryPoint:
to: websecure
websecure:
address: ":443"
http:
middlewares:
- secureHeaders@file
tls:
certResolver: letsencrypt
certificatesResolvers:
letsencrypt:
acme:
email: your-email-here
storage: acme.json
keyType: EC384
dnsChallenge:
provider: cloudflare
delayBeforeCheck: 0
providers:
docker:
endpoint: "unix:///var/run/docker.sock"
exposedByDefault: false
file:
filename: /configurations/dynamic.yml
```
The first `api` section is pretty self-explanatory enables the web-ui dashboard. You can choose not to do
this if you don't want the traefik web dashboard. The `entryPoints` section is a bit more interesting. This
is where we enforce that all HTTP web-requests on port `80` will be redirected to port `443` using transport
layer security (TLS). You might notice that we specifically mention `letsencrypt` here, this leads us
to the `certificatesResolvers` section. Since I am using [cloudflare](https://www.cloudflare.com/)
as my DNS (Domain Name Service) provider, I can also use them as my TLS certificate provider as
they provide this service. This is a complex topic and if you're interested, I recommend reading
[this](https://blog.cloudflare.com/introducing-automatic-ssl-tls-securing-and-simplifying-origin-connectivity/)
blog post by cloudflare themselves. Boiling all this jargan down, we are just using cloudflare as a middleman to
help us get the little lock icon in the browser when someone visits our website(s). I've set the certificates to
automatically update, so I don't have to worry about it ever again.
The `providers` settings refer to where traefik can route internet traffic to. We simply register `docker` as a service
provider as well as the configurations we define in `configurations/dynamic.yml`. Let's take a look at the content of
that file.
```yaml
http:
middlewares:
secureHeaders:
headers:
sslRedirect: true
forceSTSHeader: true
stsIncludeSubdomains: true
stsPreload: true
stsSeconds: 31536000
user-auth:
basicAuth:
users:
- "administrator:<password>" # ADD YOUR ADMIN PASSWORD HERE ()
tls:
options:
default:
cipherSuites:
- TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
- TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
- TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
- TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
- TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305
- TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305
minVersion: VersionTLS12
```
Starting in the `http.middlewares` section, we first register a TLS middleware that we call `secureHeaders` (note that
this is the middleware referred in `traefik.yml`) - skipping past the details, this middleware simply adds security
headers to each request. Our second middleware, `user-auth` is the authentication method to gain access to the traefik
dashboard. Here we set the username `username` and you should generate the password using the `htpasswd` command. This
command should be available through the `apache2-utils` package on ubuntu systems, and `extra/apache` on Arch. Simply
copy / paste the generated hashed password into your yaml file.
```sh
# -n = output to stdout -B = use bcrypt
# Make sure to replace 'administrator' if you want a different username
htpasswd -nB administrator
```
## Starting Everything
We should now have everything set up and ready for starting! Simply navigate to the `~/control` directory and start the
docker compose stack.
```sh
# Start the containers (detached)
docker compose up -d
# Follow along with the logs
docker compose logs -f
```
Hopefully there shouldn't be any errors, but if there are, make doubly sure that your TLS settings are set correctly,
as that's likely to be the thing to mess up (ask me how I know). If you need additional assistance, the [official
traefik docs](https://doc.traefik.io/traefik/) are a great resource. Portainer is fairly fool-proof, so I don't expect
that to cause you any problems.
## TODO
- [ ] DNS records, ACME challenges, TXT records, Wildcard A records, CAA records - jesus there's so much shit I've forgotten
{{< centered image="/6616144.png" >}}
```yaml
services:
postgresql:
image: postgres:16
environment:
- POSTGRES_USER=keycloak
_ POSTGRES_DB=keycloak
- POSTGRES_PASSWORD=secret
volumes:
- postgres-data:/var/lib/postgresql/data
networks:
- keycloak
keycloak:
image: quay.io/keycloa/keycloak:22
restart: always
command: start
depends_on:
- postgresql
environment:
# traefik handles ssl
- KC_PROXY_ADDRESS_FORWARDING=true
- KC_HOSTNAME_STRUCT=false
- KC_HOSTNAME=keycloak.gtz.dk
- KC_PROXY=edge
- KC_HTTP_ENABLED=true
# connect to the postgres thing
- DB=keycloak
- DB_URL='jdbc:postgresql://postgres:5432/postgresql?ssl=allow'
- DB_USERNAME=keycloak
- DB_PASSWORD=secret
- KEYCLOAK_ADMIN=admin
- KEYCLOAK_ADMIN_PASSWORD=admin
networks:
- proxy
- keycloa
labels:
- "traefik.enable=true"
- port=8080
networks:
proxy:
external: true
keycloak:
```

View File

@ -1,6 +1,6 @@
+++
date = '2025-01-27'
draft = true
draft = false
title = 'Softmod your Xbox Original Today'
tags = ['technical', 'games', 'modding']
categories = ['technical']