Pathoris CI/CD Environment

A self-hosted CI/CD setup for hobby projects, running on a virtual root server at pathoris.de.

Goals

Architecture

All services run as containers via podman compose on pathoris.de. Nginx acts as reverse proxy, terminating TLS and enforcing client certificate authentication.

Internet
  │
  ▼
nginx (TLS + client certs)
  ├── git.cicd.pathoris.de     → Forgejo  (port 3000)
  ├── ldap.cicd.pathoris.de    → phpLDAPadmin (port 8080)
  ├── jenkins.cicd.pathoris.de → Jenkins  (port 8080)
  └── cicd.pathoris.de         → static landing page

Components

Docker Compose — Container Orchestration

All services defined in a single docker-compose.yaml, managed with podman compose. Custom Dockerfiles per service, shared variables via env.txt, jinja2 templating for configuration.

Nginx — Reverse Proxy

TLS termination with Let's Encrypt certificates. Client certificate authentication restricts access to authorized users. Each service gets its own subdomain. - Debug Guide - Issues and Mitigations

LDAP — User Directory

OpenLDAP (slapd) provides centralized authentication for all services. Runs embedded inside the phpLDAPadmin container. Users, groups, and service accounts are bootstrapped automatically on first start. The memberOf overlay maintains group membership attributes. - Debug Guide - Issues and Mitigations

phpLDAPadmin — LDAP Web UI

Web interface for managing LDAP users and groups. Includes a custom user creation template tailored for CI/CD accounts. Runs on the same container as slapd. - Debug Guide - Issues and Mitigations

Forgejo — Git Hosting

Lightweight, self-hosted Git forge (Gitea fork). Authenticates against LDAP. Uses PostgreSQL as its database backend. The container automatically creates its database on first start.

Jenkins — Build Server

Automation server for builds and tests. LDAP authentication is configured automatically on first boot via a Groovy init script. Plugins (ldap, matrix-auth, git, workflow) are installed at image build time.

PostgreSQL — Database

Stores Forgejo's data. Uses the official postgres:16-alpine image without customization. Database and user creation is handled by Forgejo's entrypoint.

Directory Layout

pathoris/
├── deploy.sh                          # Deploy configs to server
├── setup-ca.sh                        # Create client certificate CA
├── create-client-cert.sh              # Issue client certificates
├── client-cert.cnf                    # Certificate extensions
├── etc/nginx/
│   ├── nginx.conf                     # Main nginx config
│   └── conf.d/cicd-pathoris.conf      # Virtual host definitions
└── opt/docker-compose/cicd/
    ├── docker-compose.yaml            # All services
    ├── env.txt                        # Shared environment variables
    ├── restart.sh                     # Helper functions for restart/reset
    ├── phpldapadmin/                  # Custom image: slapd + phpLDAPadmin
    ├── forgejo/                       # Custom image: rootless + DB init
    ├── jenkins/                       # Custom image: plugins + LDAP config
    └── postgres/                      # No custom image, just README

Getting Started

  1. Set up the server with nginx and podman
  2. Create a client certificate CA (setup-ca.sh) and issue your first cert (create-client-cert.sh)
  3. Configure nginx with the provided cicd-pathoris.conf
  4. Review and update passwords in env.txt (all LDAP and service credentials are centralized there)
  5. Run podman compose up -d to start all services
  6. Access phpLDAPadmin to verify LDAP bootstrap data
  7. Configure Forgejo's LDAP authentication source via its web UI
  8. Jenkins LDAP is configured automatically on first boot