kitestacks-homelab/homelab-mastery/build-guide/with-ai/04-core-services.md
kenpat 1e8319ee75 docs: comprehensive homelab-mastery rewrite with full build guides
Complete documentation suite for KiteStacks covering all 11 services across
2-host active-active architecture. Includes beginner track (with AI, 8 files)
and advanced track (without AI, 7 files) with time estimates, real troubleshooting
cases, and command-by-command explanations. Updates certifications roadmap to
reflect July 7 2026 A+ Core 2 exam goal.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-19 01:08:43 -05:00

298 lines
6.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Step 4 — Core Services: Portal, Forgejo, and Authentik
**Track:** With AI (Beginner)
**Time for this step:** 35 hours
These three services form the foundation of KiteStacks:
- **Portal** — the homepage that links to everything
- **Forgejo** — stores all your code and configurations in Git
- **Authentik** — handles all logins for every service (SSO)
Set these up first. Everything else depends on them.
---
## How Docker Compose Files Work
Every service in this homelab has its own folder with a `docker-compose.yml` file.
That file describes the service: what image to use, what environment variables to set,
what folders to use for data, and what network to join.
You will create these files using `nano` (a simple text editor in the terminal).
**Ask your AI:** "Can you explain what each section of a docker-compose.yml file does:
services, image, container_name, restart, environment, volumes, networks?"
---
## Service 1 — The Portal (Homepage)
The portal is your home page at `www.yourdomain.com`. It shows links to all your
services and displays live system stats.
```bash
mkdir -p ~/kitestacks-live/docker/kitestacks-portal/public
cd ~/kitestacks-live/docker/kitestacks-portal
```
Create `docker-compose.yml`:
```yaml
services:
homepage:
image: nginx:alpine
container_name: homepage
restart: unless-stopped
volumes:
- ./public:/usr/share/nginx/html:ro
- ./nginx.conf:/etc/nginx/conf.d/default.conf:ro
networks:
- kitestacks
networks:
kitestacks:
external: true
```
Create a basic `nginx.conf`:
```nginx
server {
listen 3000;
root /usr/share/nginx/html;
index index.html;
location / {
try_files $uri $uri/ /index.html;
}
}
```
Create a basic `public/index.html` to test:
```html
<!DOCTYPE html>
<html>
<head><title>KiteStacks</title></head>
<body>
<h1>KiteStacks is live!</h1>
</body>
</html>
```
Start it:
```bash
docker compose up -d
docker ps
```
Visit `www.yourdomain.com` in a browser. You should see your page.
If it works, you have confirmed the tunnel is routing correctly.
**Ask your AI:** "I want to build a proper homepage for my homelab. It should have a
dark cyberpunk theme with cards for each of my services. Can you help me write the HTML?"
Work with your AI to build the portal you want. The KiteStacks portal source is in
`~/kitestacks-homelab/apps/kitestacks-portal/` as reference.
---
## Service 2 — Forgejo (Git)
Forgejo stores all your code. You will push your homelab configs to it so everything
is version-controlled and you never lose your work.
First, set up the shared PostgreSQL database (Forgejo will use this):
```bash
mkdir -p ~/kitestacks-live/docker/postgres
cd ~/kitestacks-live/docker/postgres
```
Create `.env`:
```
POSTGRES_USER=authentik
POSTGRES_PASSWORD=choose-a-strong-password-here
POSTGRES_DB=authentik
```
Create `docker-compose.yml`:
```yaml
services:
authentik-postgres:
image: postgres:16-alpine
container_name: authentik-postgres
restart: unless-stopped
env_file: .env
volumes:
- ./data:/var/lib/postgresql/data
networks:
- kitestacks
networks:
kitestacks:
external: true
```
```bash
docker compose up -d
```
Now create the Forgejo service:
```bash
mkdir -p ~/kitestacks-live/docker/forgejo
cd ~/kitestacks-live/docker/forgejo
```
Create `.env`:
```
FORGEJO_DB_TYPE=postgres
FORGEJO_DB_HOST=authentik-postgres:5432
FORGEJO_DB_NAME=forgejo
FORGEJO_DB_USER=forgejo
FORGEJO_DB_PASSWD=choose-a-strong-password-here
FORGEJO_DOMAIN=gitforge.yourdomain.com
FORGEJO_SSH_DOMAIN=gitforge.yourdomain.com
FORGEJO_ROOT_URL=https://gitforge.yourdomain.com
```
Create `docker-compose.yml`:
```yaml
services:
forgejo:
image: codeberg.org/forgejo/forgejo:latest
container_name: forgejo
restart: unless-stopped
env_file: .env
volumes:
- ./data:/data
networks:
- kitestacks
networks:
kitestacks:
external: true
```
```bash
docker compose up -d
docker logs forgejo -f
```
Wait for it to finish starting (about 30 seconds), then visit `gitforge.yourdomain.com`.
You will see a Forgejo setup page — follow the on-screen instructions to create your admin account.
**Ask your AI:** "How do I create a repository on Forgejo and push my local files to it?"
---
## Service 3 — Authentik (Single Sign-On)
Authentik is the most complex service to set up, but it is worth it — once done,
you log in once and every other service recognizes you automatically.
First, set up Redis (Authentik needs this for session management):
```bash
mkdir -p ~/kitestacks-live/docker/redis
cd ~/kitestacks-live/docker/redis
```
Create `docker-compose.yml`:
```yaml
services:
authentik-redis:
image: redis:alpine
container_name: authentik-redis
restart: unless-stopped
networks:
- kitestacks
networks:
kitestacks:
external: true
```
```bash
docker compose up -d
```
Now create Authentik:
```bash
mkdir -p ~/kitestacks-live/docker/authentik
cd ~/kitestacks-live/docker/authentik
```
Generate a secret key (run this and save the output):
```bash
openssl rand -base64 60 | tr -d '\n'
```
Create `.env` (replace the values):
```
PG_PASS=same-postgres-password-from-above
AUTHENTIK_SECRET_KEY=paste-the-generated-key-here
AUTHENTIK_BOOTSTRAP_EMAIL=your@email.com
AUTHENTIK_BOOTSTRAP_PASSWORD=choose-a-strong-admin-password
AUTHENTIK_POSTGRESQL__HOST=authentik-postgres
AUTHENTIK_POSTGRESQL__USER=authentik
AUTHENTIK_POSTGRESQL__NAME=authentik
AUTHENTIK_POSTGRESQL__PASSWORD=same-postgres-password-from-above
AUTHENTIK_REDIS__HOST=authentik-redis
```
Create `docker-compose.yml`:
```yaml
services:
authentik:
image: ghcr.io/goauthentik/server:latest
container_name: authentik
restart: unless-stopped
command: server
env_file: .env
networks:
- kitestacks
authentik-worker:
image: ghcr.io/goauthentik/server:latest
container_name: authentik-worker
restart: unless-stopped
command: worker
env_file: .env
networks:
- kitestacks
networks:
kitestacks:
external: true
```
```bash
docker compose up -d
```
Authentik takes about 2 minutes to start on first run (it sets up the database).
Watch the logs:
```bash
docker logs authentik -f
```
When you see "Starting authentik server" it is ready.
Visit `auth.yourdomain.com` and log in with the bootstrap email and password you set.
**Ask your AI:** "I have Authentik running. How do I create an OAuth2 provider for Grafana
so it can use SSO? Walk me through the steps in the Authentik admin panel."
Use the same process (with your AI's help) to create OAuth2 providers for each service
as you add them in the next steps.
---
## Checkpoint
Before moving to Step 5:
- [ ] Portal is live at `www.yourdomain.com`
- [ ] Forgejo is live at `gitforge.yourdomain.com` with your admin account created
- [ ] Authentik is live at `auth.yourdomain.com` and you can log in
- [ ] You can see all three containers in `docker ps`
---
**Next:** [Step 5 — All Remaining Services](05-all-services.md)