first prototype

hector (dev) -> raspen (rev proxy) -> agge (appserver: nextcloud, gitea,
postgre)
This commit is contained in:
2026-05-02 21:26:35 +02:00
commit 5e97218dc8
13 changed files with 458 additions and 0 deletions
+17
View File
@@ -0,0 +1,17 @@
# PostgreSQL (internal, for Nextcloud)
POSTGRES_DB=nextcloud
POSTGRES_USER=nextcloud
POSTGRES_PASSWORD=CHANGE_THIS_PASSWORD
# Remote PostgreSQL (for external access)
PG_DB=remotedb
PG_USER=remoteuser
PG_PASSWORD=CHANGE_THIS_PASSWORD
# Nextcloud
NEXTCLOUD_ADMIN_USER=admin
NEXTCLOUD_ADMIN_PASSWORD=CHANGE_THIS_PASSWORD
TRUSTED_DOMAINS=nc.home localhost 127.0.0.1
# Gitea
GITEA_DOMAIN=git.home
+83
View File
@@ -0,0 +1,83 @@
services:
postgres:
image: postgres:16-alpine
restart: unless-stopped
volumes:
- postgres_data:/var/lib/postgresql/data
environment:
- POSTGRES_DB=${POSTGRES_DB}
- POSTGRES_USER=${POSTGRES_USER}
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
networks:
- backend
nextcloud:
image: nextcloud:latest
restart: unless-stopped
volumes:
- nextcloud_data:/var/www/html/data
- nextcloud_config:/var/www/html/config
environment:
- POSTGRES_HOST=postgres
- POSTGRES_DB=${POSTGRES_DB}
- POSTGRES_USER=${POSTGRES_USER}
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
- NEXTCLOUD_ADMIN_USER=${NEXTCLOUD_ADMIN_USER}
- NEXTCLOUD_ADMIN_PASSWORD=${NEXTCLOUD_ADMIN_PASSWORD}
- TRUSTED_DOMAINS=${TRUSTED_DOMAINS}
- OVERWRITEPROTOCOL=https
depends_on:
- postgres
ports:
- "8080:80"
networks:
- backend
gitea:
image: gitea/gitea:latest
restart: unless-stopped
volumes:
- gitea_data:/data
expose:
- "3000"
- "2222"
environment:
- USER_UID=1000
- USER_GID=1000
- GITEA__database__DB_TYPE=sqlite3
- GITEA__server__PROTOCOL=http
- GITEA__server__DOMAIN=${GITEA_DOMAIN}
- GITEA__server__ROOT_URL=https://${GITEA_DOMAIN}/
- GITEA__server__SSH_PORT=2222
- GITEA__server__HTTP_PORT=3000
- GITEA__security__INSTALL_LOCK=true
ports:
- "3000:3000"
- "2222:22"
networks:
- backend
postgres_remote:
image: postgres:16-alpine
restart: unless-stopped
volumes:
- postgres_remote_data:/var/lib/postgresql/data
environment:
- POSTGRES_DB=${PG_DB}
- POSTGRES_USER=${PG_USER}
- POSTGRES_PASSWORD=${PG_PASSWORD}
ports:
- "5432:5432"
networks:
- backend
networks:
backend:
driver: bridge
volumes:
postgres_data:
postgres_remote_data:
nextcloud_data:
nextcloud_config:
gitea_data:
+8
View File
@@ -0,0 +1,8 @@
{
"$schema": "https://opencode.ai/config.json",
"permission": {
"bash": "ask",
"external_directory": "ask"
}
}
+22
View File
@@ -0,0 +1,22 @@
-----BEGIN CERTIFICATE-----
MIIDlTCCAn2gAwIBAgIUYjBM2NNMtn5jRcofMSbFZLlk7iIwDQYJKoZIhvcNAQEL
BQAwWjELMAkGA1UEBhMCVVMxDjAMBgNVBAgMBVN0YXRlMQ0wCwYDVQQHDARDaXR5
MRMwEQYDVQQKDApTZWxmaG9zdGVkMRcwFQYDVQQDDA5uZXh0Y2xvdWQuaG9tZTAe
Fw0yNjA0MTYwMDExNTdaFw0yNzA0MTYwMDExNTdaMFoxCzAJBgNVBAYTAlVTMQ4w
DAYDVQQIDAVTdGF0ZTENMAsGA1UEBwwEQ2l0eTETMBEGA1UECgwKU2VsZmhvc3Rl
ZDEXMBUGA1UEAwwObmV4dGNsb3VkLmhvbWUwggEiMA0GCSqGSIb3DQEBAQUAA4IB
DwAwggEKAoIBAQC0LsyecVOM91qViXPsuE2btbJLpx988mZDYfyBcEMuv2R2jIIC
FmEM5B2oeKoLQiHuF55NaKgSPZBCgKqEyz0qbwiQBdL6MmqF2cAHf35oQgTRqYXQ
XTRfKIQUjZnGfAda/+PF4ydOgiztrswnjohPr1Man+VehRyfqT5pSY/1PGGO+nL4
9UeK2mTRVhS8SBwj70lQJGgXutlhPM2B4GZDZHaaTwENp6WkrB6YtNRHhlDi5brp
ftJzrK07iGAZ6kaqzUYA30qQMcs8MjNxNcB2y14LafdFheVgvZMvhO/uz0zO2kWg
BnSHADJKgs/NrquDP08joDUShtl1tNpZEya9AgMBAAGjUzBRMB0GA1UdDgQWBBRU
bfFJoyAV4JJc4QOj3Py3xh4SmDAfBgNVHSMEGDAWgBRUbfFJoyAV4JJc4QOj3Py3
xh4SmDAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQA+exKQ7Gp6
rpbpYj56ZoGX/mVHdXz4zEwSfJqcOvILnNgtiMmlpmDF99CwnpXeMcbWxapVmOtV
mo9fO56L6IX6FZlin0IIhO8QEUUfodHV7KHLSkgUPJJIM/pgw19dKgi2wiJJ3zaw
JFfVaVPIFMspa+1GkYElnDnUKFi9YYDeH4nP/OkpezekIkmSa6Y4cppIgicV4WmS
YRRMCuEjrDrJ+wI/OyZtbTfQSWjmG469WAPFysHNttHMOZk8Av3DPG+YU7/KZUwQ
WLYOxoljXu5c/D/VJHu9l7l9oOWvDbgWwP9bEDJIGOkYaZ+RKIBbtVaPNZhFk0Tj
nXr4XRRjwn+9
-----END CERTIFICATE-----
+28
View File
@@ -0,0 +1,28 @@
-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC0LsyecVOM91qV
iXPsuE2btbJLpx988mZDYfyBcEMuv2R2jIICFmEM5B2oeKoLQiHuF55NaKgSPZBC
gKqEyz0qbwiQBdL6MmqF2cAHf35oQgTRqYXQXTRfKIQUjZnGfAda/+PF4ydOgizt
rswnjohPr1Man+VehRyfqT5pSY/1PGGO+nL49UeK2mTRVhS8SBwj70lQJGgXutlh
PM2B4GZDZHaaTwENp6WkrB6YtNRHhlDi5brpftJzrK07iGAZ6kaqzUYA30qQMcs8
MjNxNcB2y14LafdFheVgvZMvhO/uz0zO2kWgBnSHADJKgs/NrquDP08joDUShtl1
tNpZEya9AgMBAAECggEAEwoC6xcUegfFFZoBmtjasoJfhajyJdTDQ4l+EftXzf/B
UNmF/0x4EtGj5KJjbW8egLcULh/J6quAq9ZGrmN/YhV7dSR4Z6GeKeiZZvFs3P1k
3vanwh2nJAr28ekIf7WpXU8+tTFMfPo6Xx8iSWfBNZJUGLMenH86SBCtHJj+Ui5S
qr1+HuMBzAK6FtxDuWTp6j7+5XpOFkv9iC3HCtV8tX4rKZrCJdNp5eQG10KfDjRk
q4XqqimlF07a6XydfxHCX7nHapWmjNNZYhOyBcphBdma9Xcf/DZj/kiikmG5IzvP
N6yx9aTV3pL2xAI73QyHvbdW/x7KQnXjszJFN5AbDQKBgQDm5+275kVk9lycm74b
xJ9xgmOcQF1Dx2RAhnEj7u2KR9FGQkKY7e1Y0ME++a/QwiRQY1BBcQ3Be+gtESiN
P8s9bmMliqYGV0wkzus9aQkIitzbsdLtA7L9ttZit06WqQUCNGPANoLVxhFFPSke
IVD/q6aWt7KkYrLz0vwW3v2YjwKBgQDHw7GO8wBNFTFd1QV8U1oGc9HyLGIgMCx1
4I0Rd5K5RV3bgwtq8ucBCHzxK42PYCPTxVHkFPNeC/2k74Cmwu7jU4zx6AHY41It
0raP8llYWiVD30xi0Z0SmFH+ajpI+LcDwXeIZN0i7y+R0T3AVsWFUBuPHKP8XSmx
UsyQGSS58wKBgQCZEcTaXANCs8KfGuuC0uxzveE0ssJg7Sw7TiRwkrIrigJkVgZ6
BLfjubdxfOodNKYIGF4ak8xvqCk4vvgn8tNTbPsS5v+6kmJqwDTXp+qSHCPfC9ns
vxgH8w3ZsPTLEU69sGc0A67l8gB+6tV4INPmOS8dGLe3G6rP0dzFeJuaZwKBgDRB
xRkYCGQhvyBEsYKsa0h0097+LU0uTPMpIr4HAaLlun/J8BqyICvtBIIyWn2/MKAd
Zia8NE3N5TRYUtdM9yEQojZF8vXBwaWrEYbmZujt7AGtUFYpb2WF4y0irMyaA4Y/
/fz4JcEVwOPsULMX/+O36P2vCFbkKBvzBQBNE4ZxAoGAZi8kU56E6m8ZdVIoQ99l
1QPf+e/6UvZ5eFnYGSqldv+W4uxx0BhlXFJDH1saeTm2/cqX+ybQQB/fZSRJ843A
sg/S4SH3oRuMN0GI4y0qtLY26xyg6EDNIvabBjasEWeLveoNMQZCfIIW8qZ8Rxkn
lxH2MtHps3gY7fVIcRkUfFs=
-----END PRIVATE KEY-----
+83
View File
@@ -0,0 +1,83 @@
services:
postgres:
image: postgres:16-alpine
restart: unless-stopped
volumes:
- postgres_data:/var/lib/postgresql/data
environment:
- POSTGRES_DB=${POSTGRES_DB}
- POSTGRES_USER=${POSTGRES_USER}
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
networks:
- backend
nextcloud:
image: nextcloud:latest
restart: unless-stopped
volumes:
- nextcloud_data:/var/www/html/data
- nextcloud_config:/var/www/html/config
environment:
- POSTGRES_HOST=postgres
- POSTGRES_DB=${POSTGRES_DB}
- POSTGRES_USER=${POSTGRES_USER}
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
- NEXTCLOUD_ADMIN_USER=${NEXTCLOUD_ADMIN_USER}
- NEXTCLOUD_ADMIN_PASSWORD=${NEXTCLOUD_ADMIN_PASSWORD}
- TRUSTED_DOMAINS=${TRUSTED_DOMAINS}
- OVERWRITEPROTOCOL=https
depends_on:
- postgres
ports:
- "8080:80"
networks:
- backend
gitea:
image: gitea/gitea:latest
restart: unless-stopped
volumes:
- gitea_data:/data
expose:
- "3000"
- "2222"
environment:
- USER_UID=1000
- USER_GID=1000
- GITEA__database__DB_TYPE=sqlite3
- GITEA__server__PROTOCOL=http
- GITEA__server__DOMAIN=${GITEA_DOMAIN}
- GITEA__server__ROOT_URL=https://${GITEA_DOMAIN}/
- GITEA__server__SSH_PORT=2222
- GITEA__server__HTTP_PORT=3000
- GITEA__security__INSTALL_LOCK=true
ports:
- "3000:3000"
- "2222:22"
networks:
- backend
postgres_remote:
image: postgres:16-alpine
restart: unless-stopped
volumes:
- postgres_remote_data:/var/lib/postgresql/data
environment:
- POSTGRES_DB=${PG_DB}
- POSTGRES_USER=${PG_USER}
- POSTGRES_PASSWORD=${PG_PASSWORD}
ports:
- "5432:5432"
networks:
- backend
networks:
backend:
driver: bridge
volumes:
postgres_data:
postgres_remote_data:
nextcloud_data:
nextcloud_config:
gitea_data:
+20
View File
@@ -0,0 +1,20 @@
services:
nginx:
image: nginx:alpine
restart: unless-stopped
volumes:
- ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro
- ./nginx/conf.d:/etc/nginx/conf.d:ro
- ./nginx/stream.d:/etc/nginx/stream.d:ro
- ./ssl:/etc/nginx/certs:ro
- ./html:/usr/share/nginx/html:ro
ports:
- "80:80"
- "443:443"
- "5432:5432"
networks:
- frontend
networks:
frontend:
driver: bridge
+15
View File
@@ -0,0 +1,15 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>raspen.home</title>
<style>
body { font-family: sans-serif; max-width: 800px; margin: 2em auto; padding: 0 1em; }
</style>
</head>
<body>
<h1>Welcome to raspen.home</h1>
<p>This server is the reverse proxy / VPS for the selfhosted stack.</p>
</body>
</html>
+96
View File
@@ -0,0 +1,96 @@
upstream nextcloud {
server 192.168.1.188:8080;
}
upstream gitea {
server 192.168.1.188:3000;
}
server {
listen 80;
server_name nc.home;
return 301 https://nc.home$request_uri;
}
server {
listen 80;
server_name git.home;
return 301 https://git.home$request_uri;
}
server {
listen 80;
server_name raspen.home;
root /usr/share/nginx/html;
index index.html;
location / {
try_files $uri $uri/ =404;
}
}
server {
listen 80;
server_name _;
return 444;
}
server {
listen 443 ssl;
server_name nc.home;
ssl_certificate /etc/nginx/certs/ssl.crt;
ssl_certificate_key /etc/nginx/certs/ssl.key;
client_max_body_size 10G;
client_body_timeout 3600s;
proxy_read_timeout 3600s;
proxy_connect_timeout 3600s;
location / {
proxy_pass http://nextcloud;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_buffering off;
proxy_request_buffering off;
proxy_http_version 1.1;
proxy_redirect off;
}
}
server {
listen 443 ssl;
server_name git.home;
ssl_certificate /etc/nginx/certs/ssl.crt;
ssl_certificate_key /etc/nginx/certs/ssl.key;
location / {
proxy_pass http://gitea;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_http_version 1.1;
proxy_redirect off;
}
}
server {
listen 443 ssl;
server_name raspen.home;
ssl_certificate /etc/nginx/certs/ssl.crt;
ssl_certificate_key /etc/nginx/certs/ssl.key;
root /usr/share/nginx/html;
index index.html;
location / {
try_files $uri $uri/ =404;
}
}
+28
View File
@@ -0,0 +1,28 @@
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
keepalive_timeout 65;
include /etc/nginx/conf.d/*.conf;
}
stream {
include /etc/nginx/stream.d/*.conf;
}
+8
View File
@@ -0,0 +1,8 @@
upstream postgres_backend {
server 192.168.1.188:5432;
}
server {
listen 5432;
proxy_pass postgres_backend;
}
+22
View File
@@ -0,0 +1,22 @@
-----BEGIN CERTIFICATE-----
MIIDlTCCAn2gAwIBAgIUYjBM2NNMtn5jRcofMSbFZLlk7iIwDQYJKoZIhvcNAQEL
BQAwWjELMAkGA1UEBhMCVVMxDjAMBgNVBAgMBVN0YXRlMQ0wCwYDVQQHDARDaXR5
MRMwEQYDVQQKDApTZWxmaG9zdGVkMRcwFQYDVQQDDA5uZXh0Y2xvdWQuaG9tZTAe
Fw0yNjA0MTYwMDExNTdaFw0yNzA0MTYwMDExNTdaMFoxCzAJBgNVBAYTAlVTMQ4w
DAYDVQQIDAVTdGF0ZTENMAsGA1UEBwwEQ2l0eTETMBEGA1UECgwKU2VsZmhvc3Rl
ZDEXMBUGA1UEAwwObmV4dGNsb3VkLmhvbWUwggEiMA0GCSqGSIb3DQEBAQUAA4IB
DwAwggEKAoIBAQC0LsyecVOM91qViXPsuE2btbJLpx988mZDYfyBcEMuv2R2jIIC
FmEM5B2oeKoLQiHuF55NaKgSPZBCgKqEyz0qbwiQBdL6MmqF2cAHf35oQgTRqYXQ
XTRfKIQUjZnGfAda/+PF4ydOgiztrswnjohPr1Man+VehRyfqT5pSY/1PGGO+nL4
9UeK2mTRVhS8SBwj70lQJGgXutlhPM2B4GZDZHaaTwENp6WkrB6YtNRHhlDi5brp
ftJzrK07iGAZ6kaqzUYA30qQMcs8MjNxNcB2y14LafdFheVgvZMvhO/uz0zO2kWg
BnSHADJKgs/NrquDP08joDUShtl1tNpZEya9AgMBAAGjUzBRMB0GA1UdDgQWBBRU
bfFJoyAV4JJc4QOj3Py3xh4SmDAfBgNVHSMEGDAWgBRUbfFJoyAV4JJc4QOj3Py3
xh4SmDAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQA+exKQ7Gp6
rpbpYj56ZoGX/mVHdXz4zEwSfJqcOvILnNgtiMmlpmDF99CwnpXeMcbWxapVmOtV
mo9fO56L6IX6FZlin0IIhO8QEUUfodHV7KHLSkgUPJJIM/pgw19dKgi2wiJJ3zaw
JFfVaVPIFMspa+1GkYElnDnUKFi9YYDeH4nP/OkpezekIkmSa6Y4cppIgicV4WmS
YRRMCuEjrDrJ+wI/OyZtbTfQSWjmG469WAPFysHNttHMOZk8Av3DPG+YU7/KZUwQ
WLYOxoljXu5c/D/VJHu9l7l9oOWvDbgWwP9bEDJIGOkYaZ+RKIBbtVaPNZhFk0Tj
nXr4XRRjwn+9
-----END CERTIFICATE-----
+28
View File
@@ -0,0 +1,28 @@
-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC0LsyecVOM91qV
iXPsuE2btbJLpx988mZDYfyBcEMuv2R2jIICFmEM5B2oeKoLQiHuF55NaKgSPZBC
gKqEyz0qbwiQBdL6MmqF2cAHf35oQgTRqYXQXTRfKIQUjZnGfAda/+PF4ydOgizt
rswnjohPr1Man+VehRyfqT5pSY/1PGGO+nL49UeK2mTRVhS8SBwj70lQJGgXutlh
PM2B4GZDZHaaTwENp6WkrB6YtNRHhlDi5brpftJzrK07iGAZ6kaqzUYA30qQMcs8
MjNxNcB2y14LafdFheVgvZMvhO/uz0zO2kWgBnSHADJKgs/NrquDP08joDUShtl1
tNpZEya9AgMBAAECggEAEwoC6xcUegfFFZoBmtjasoJfhajyJdTDQ4l+EftXzf/B
UNmF/0x4EtGj5KJjbW8egLcULh/J6quAq9ZGrmN/YhV7dSR4Z6GeKeiZZvFs3P1k
3vanwh2nJAr28ekIf7WpXU8+tTFMfPo6Xx8iSWfBNZJUGLMenH86SBCtHJj+Ui5S
qr1+HuMBzAK6FtxDuWTp6j7+5XpOFkv9iC3HCtV8tX4rKZrCJdNp5eQG10KfDjRk
q4XqqimlF07a6XydfxHCX7nHapWmjNNZYhOyBcphBdma9Xcf/DZj/kiikmG5IzvP
N6yx9aTV3pL2xAI73QyHvbdW/x7KQnXjszJFN5AbDQKBgQDm5+275kVk9lycm74b
xJ9xgmOcQF1Dx2RAhnEj7u2KR9FGQkKY7e1Y0ME++a/QwiRQY1BBcQ3Be+gtESiN
P8s9bmMliqYGV0wkzus9aQkIitzbsdLtA7L9ttZit06WqQUCNGPANoLVxhFFPSke
IVD/q6aWt7KkYrLz0vwW3v2YjwKBgQDHw7GO8wBNFTFd1QV8U1oGc9HyLGIgMCx1
4I0Rd5K5RV3bgwtq8ucBCHzxK42PYCPTxVHkFPNeC/2k74Cmwu7jU4zx6AHY41It
0raP8llYWiVD30xi0Z0SmFH+ajpI+LcDwXeIZN0i7y+R0T3AVsWFUBuPHKP8XSmx
UsyQGSS58wKBgQCZEcTaXANCs8KfGuuC0uxzveE0ssJg7Sw7TiRwkrIrigJkVgZ6
BLfjubdxfOodNKYIGF4ak8xvqCk4vvgn8tNTbPsS5v+6kmJqwDTXp+qSHCPfC9ns
vxgH8w3ZsPTLEU69sGc0A67l8gB+6tV4INPmOS8dGLe3G6rP0dzFeJuaZwKBgDRB
xRkYCGQhvyBEsYKsa0h0097+LU0uTPMpIr4HAaLlun/J8BqyICvtBIIyWn2/MKAd
Zia8NE3N5TRYUtdM9yEQojZF8vXBwaWrEYbmZujt7AGtUFYpb2WF4y0irMyaA4Y/
/fz4JcEVwOPsULMX/+O36P2vCFbkKBvzBQBNE4ZxAoGAZi8kU56E6m8ZdVIoQ99l
1QPf+e/6UvZ5eFnYGSqldv+W4uxx0BhlXFJDH1saeTm2/cqX+ybQQB/fZSRJ843A
sg/S4SH3oRuMN0GI4y0qtLY26xyg6EDNIvabBjasEWeLveoNMQZCfIIW8qZ8Rxkn
lxH2MtHps3gY7fVIcRkUfFs=
-----END PRIVATE KEY-----