chore: initial hub repo structure

This commit is contained in:
asepharyana
2026-07-09 22:08:26 +07:00
commit b31fe9d188
83 changed files with 7969 additions and 0 deletions
+61
View File
@@ -0,0 +1,61 @@
# Traefik Environment Configuration
This document describes environment variables used to configure Traefik certificate and config paths in production deployments.
## Certificate Path Environment Variables
All certificate paths support environment variable substitution with safe fallback defaults. This allows flexible certificate management across different deployment environments without modifying compose files.
### Configuration Variables
| Variable | Description | Default Path | Purpose |
| ------------------------------------- | --------------------------------------------------------------- | --------------------------------------------- | ------------------------------------------------------- |
| `TRAEFIK_CONFIG_PATH` | Directory containing dynamic Traefik configuration files (YAML) | `/root/asepharyana-hub/infra/traefik/dynamic` | Location of middleware, router, and service definitions |
| `TRAEFIK_CERT_ASEPHARYANA_MY_ID_PEM` | Certificate file for asepharyana.my.id | `/root/asepharyana.my.id.pem` | SSL/TLS certificate for asepharyana.my.id domain |
| `TRAEFIK_CERT_ASEPHARYANA_MY_ID_KEY` | Key file for asepharyana.my.id | `/root/asepharyana.my.id.key` | SSL/TLS private key for asepharyana.my.id domain |
| `TRAEFIK_CERT_ASEPHARYANA_WEB_ID_PEM` | Certificate file for asepharyana.web.id | `/root/asepharyana.web.id.pem` | SSL/TLS certificate for asepharyana.web.id domain |
| `TRAEFIK_CERT_ASEPHARYANA_WEB_ID_KEY` | Key file for asepharyana.web.id | `/root/asepharyana.web.id.key` | SSL/TLS private key for asepharyana.web.id domain |
## Usage
### Default Behavior (Production)
If no environment variables are set, Traefik will use the default paths shown above. This is suitable for production deployments where certificates are installed at these standard locations.
```bash
docker compose -f infra/compose/traefik.yml up -d
```
### Custom Paths (Custom Deployments)
To override paths for a custom deployment, set environment variables before starting services:
```bash
export TRAEFIK_CONFIG_PATH=/etc/traefik/custom-dynamic
docker compose -f infra/compose/traefik.yml up -d
```
### Via .env File
Create or update your `.env` file in the deployment directory:
```env
TRAEFIK_CONFIG_PATH=/root/asepharyana-hub/infra/traefik/dynamic
TRAEFIK_CERT_ASEPHARYANA_MY_ID_PEM=/root/asepharyana.my.id.pem
TRAEFIK_CERT_ASEPHARYANA_MY_ID_KEY=/root/asepharyana.my.id.key
TRAEFIK_CERT_ASEPHARYANA_WEB_ID_PEM=/root/asepharyana.web.id.pem
TRAEFIK_CERT_ASEPHARYANA_WEB_ID_KEY=/root/asepharyana.web.id.key
```
Then deploy:
```bash
docker compose --env-file .env -f infra/compose/traefik.yml up -d
```
## Notes
- All certificate paths use read-only mounts (`:ro`) for security
- If a certificate file is missing at the specified path, Docker volume mounting will fail—ensure certificates exist before starting Traefik
- The dynamic configuration directory must contain valid YAML files for Traefik to load properly
+57
View File
@@ -0,0 +1,57 @@
http:
routers:
# ── React SPA (domain root) ──
react:
rule: 'Host(`asepharyana.my.id`) || Host(`asepharyana.web.id`)'
entryPoints:
- websecure
tls: {}
service: react-service
# ── Scraper API ──
scraper:
rule: 'Host(`scraper.asepharyana.my.id`) || Host(`api.asepharyana.my.id`) || Host(`scraper.asepharyana.web.id`) || Host(`api.asepharyana.web.id`)'
entryPoints:
- websecure
tls: {}
middlewares:
- common-chain@file
service: scraper-service
# ── Elysia API ──
elysia:
rule: 'Host(`elysia.asepharyana.my.id`) || Host(`elysia.asepharyana.web.id`)'
entryPoints:
- websecure
tls: {}
middlewares:
- common-chain@file
service: elysia-service
# ── Rust Auth API ──
rust-auth:
rule: 'Host(`auth.asepharyana.my.id`) || Host(`auth.asepharyana.web.id`)'
entryPoints:
- websecure
tls: {}
middlewares:
- common-chain@file
service: rust-auth-service
services:
react-service:
loadBalancer:
servers:
- url: 'http://react-web:80'
scraper-service:
loadBalancer:
servers:
- url: 'http://scraper-api:4091'
elysia-service:
loadBalancer:
servers:
- url: 'http://elysia-api:4092'
rust-auth-service:
loadBalancer:
servers:
- url: 'http://rust-auth:3000'
+74
View File
@@ -0,0 +1,74 @@
http:
middlewares:
secure-headers:
headers:
sslRedirect: true
forceSTSHeader: true
stsSeconds: 31536000
stsIncludeSubdomains: true
stsPreload: true
frameDeny: true
contentTypeNosniff: true
browserXSSFilter: true
referrerPolicy: 'same-origin'
customResponseHeaders:
X-Content-Type-Options: 'nosniff'
X-Frame-Options: 'DENY'
X-XSS-Protection: '1; mode=block'
Referrer-Policy: 'same-origin'
Permissions-Policy: 'geolocation=(), microphone=(), camera=()'
compress:
compress:
minResponseBodyBytes: 256
excludedContentTypes:
- 'image/*'
- 'application/octet-stream'
retry:
retry:
attempts: 3
rate-limit:
rateLimit:
average: 100
burst: 50
buffer:
buffering:
maxRequestBodyBytes: 10485760
maxResponseBodyBytes: 10485760
memRequestBodyBytes: 1048576
memResponseBodyBytes: 1048576
admin-chain:
chain:
middlewares:
- secure-headers
- compress
- retry
# ── Useful Plugins ──
real-ip:
plugin:
real-ip:
excludednetworks:
- '127.0.0.1/32'
realipheader: 'CF-Connecting-IP'
block-sensitive-paths:
plugin:
blockpath:
regex:
- "^/\\.env"
- "^/\\.git"
- '^/wp-admin'
- "^/wp-login\\.php"
- "^/config\\.php"
# ── Common Chain ──
common-chain:
chain:
middlewares:
# - real-ip
# - block-sensitive-paths
- secure-headers
- compress
- retry
- rate-limit
- buffer
+14
View File
@@ -0,0 +1,14 @@
tls:
certificates:
# Legacy production layout: asephstech.pem is paired with asephscloud.key.
- certFile: /etc/traefik/certs/asephstech.pem
keyFile: /etc/traefik/certs/asephscloud.key
- certFile: /etc/traefik/certs/asepharyana.my.id.pem
keyFile: /etc/traefik/certs/asepharyana.my.id.key
- certFile: /etc/traefik/certs/asepharyana.web.id.pem
keyFile: /etc/traefik/certs/asepharyana.web.id.key
stores:
default:
defaultCertificate:
certFile: /etc/traefik/certs/asephstech.pem
keyFile: /etc/traefik/certs/asephscloud.key
+29
View File
@@ -0,0 +1,29 @@
api:
dashboard: true
insecure: true
log:
level: INFO
format: json
accessLog: {}
entryPoints:
web:
address: ':80'
http:
redirections:
entryPoint:
to: websecure
scheme: https
websecure:
address: ':443'
providers:
docker:
endpoint: 'unix:///var/run/docker.sock'
exposedByDefault: false
network: app-shared-net
file:
directory: /etc/traefik/dynamic
watch: true