diff --git a/servers/apoc/README.md b/servers/apoc/README.md
new file mode 100644
index 0000000..6a25c42
--- /dev/null
+++ b/servers/apoc/README.md
@@ -0,0 +1 @@
+server configuration for `apoc`.
diff --git a/servers/apoc/docker-compose.d/README.md b/servers/apoc/docker-compose.d/README.md
new file mode 100644
index 0000000..26b9ae3
--- /dev/null
+++ b/servers/apoc/docker-compose.d/README.md
@@ -0,0 +1 @@
+This folder houses all docker-compose files
\ No newline at end of file
diff --git a/servers/apoc/docker-compose.d/custom/nginx/Dockerfile b/servers/apoc/docker-compose.d/custom/nginx/Dockerfile
new file mode 100644
index 0000000..6bb5b49
--- /dev/null
+++ b/servers/apoc/docker-compose.d/custom/nginx/Dockerfile
@@ -0,0 +1,13 @@
+FROM nginx:alpine
+
+RUN apk add \
+ certbot \
+ certbot-nginx
+
+COPY content /usr/share/nginx/html
+COPY conf.d/ /etc/nginx/conf.d/
+COPY nginx.conf /etc/nginx/nginx.conf
+
+COPY entrypoint.sh /entrypoint
+ENTRYPOINT [ "sh", "/entrypoint" ]
+CMD [ "nginx", "-g", "daemon off;" ]
\ No newline at end of file
diff --git a/servers/apoc/docker-compose.d/custom/nginx/conf.d/default.conf b/servers/apoc/docker-compose.d/custom/nginx/conf.d/default.conf
new file mode 100644
index 0000000..eec286f
--- /dev/null
+++ b/servers/apoc/docker-compose.d/custom/nginx/conf.d/default.conf
@@ -0,0 +1,17 @@
+server {
+ listen 80;
+ server_name apoc.ixvd.net;
+
+ # SSL is managed by certbot, no need for a ssl listen; it will be generated automagically!
+
+ # default html page
+ location / {
+ root /usr/share/nginx/html;
+ index index.html index.htm;
+ }
+
+ error_page 500 502 503 504 /50x.html;
+ location = /50x.html {
+ root /usr/share/nginx/html;
+ }
+}
diff --git a/servers/apoc/docker-compose.d/custom/nginx/conf.d/git.conf b/servers/apoc/docker-compose.d/custom/nginx/conf.d/git.conf
new file mode 100644
index 0000000..030ecff
--- /dev/null
+++ b/servers/apoc/docker-compose.d/custom/nginx/conf.d/git.conf
@@ -0,0 +1,15 @@
+server {
+ listen 80;
+ server_name git.ixvd.net;
+
+ location / {
+ proxy_pass http://git:3000;
+ proxy_set_header Connection $http_connection;
+ proxy_set_header Upgrade $http_upgrade;
+ 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;
+ client_max_body_size 0;
+ }
+}
\ No newline at end of file
diff --git a/servers/apoc/docker-compose.d/custom/nginx/conf.d/keycloak.conf b/servers/apoc/docker-compose.d/custom/nginx/conf.d/keycloak.conf
new file mode 100644
index 0000000..76faeae
--- /dev/null
+++ b/servers/apoc/docker-compose.d/custom/nginx/conf.d/keycloak.conf
@@ -0,0 +1,20 @@
+server {
+ listen 80;
+ server_name my.ixvd.net;
+
+ set_real_ip_from 0.0.0.0/0;
+ real_ip_header X-Real-IP;
+ real_ip_recursive on;
+
+ location / {
+ proxy_pass http://keycloak;
+
+ proxy_redirect off;
+ proxy_set_header Host $host;
+ proxy_set_header X-Real-IP $remote_addr;
+ proxy_set_header X-Forwarded-For $remote_addr;
+ proxy_set_header X-Forwarded-Proto $scheme;
+ proxy_set_header X-Forwarded-Port 443;
+ }
+
+};
diff --git a/servers/apoc/docker-compose.d/custom/nginx/conf.d/rainloop.conf b/servers/apoc/docker-compose.d/custom/nginx/conf.d/rainloop.conf
new file mode 100644
index 0000000..6110037
--- /dev/null
+++ b/servers/apoc/docker-compose.d/custom/nginx/conf.d/rainloop.conf
@@ -0,0 +1,8 @@
+server {
+ listen 80;
+ server_name mail.ixvd.net;
+
+ location / {
+ proxy_pass http://rainloop:8888$request_uri;
+ }
+}
\ No newline at end of file
diff --git a/servers/apoc/docker-compose.d/custom/nginx/content/index.html b/servers/apoc/docker-compose.d/custom/nginx/content/index.html
new file mode 100644
index 0000000..6420e32
--- /dev/null
+++ b/servers/apoc/docker-compose.d/custom/nginx/content/index.html
@@ -0,0 +1,23 @@
+
+
+
+
+ Welcome to nginx!
+
+
+
+
+ Welcome to apoc!
+
+
+
\ No newline at end of file
diff --git a/servers/apoc/docker-compose.d/custom/nginx/entrypoint.sh b/servers/apoc/docker-compose.d/custom/nginx/entrypoint.sh
new file mode 100644
index 0000000..df5fa5c
--- /dev/null
+++ b/servers/apoc/docker-compose.d/custom/nginx/entrypoint.sh
@@ -0,0 +1,28 @@
+#!/bin/sh
+
+trap exit TERM
+
+if [ -n "${CERTBOT_DOMAINS}" ]; then
+ echo "registering..."
+ if ! certbot show_account; then
+ certbot register -n \
+ --agree-tos \
+ -m "${CERTBOT_EMAIL}"
+ fi
+
+ for d in $(echo "${CERTBOT_DOMAINS}" | sed 's/,/ /g'); do
+ echo "requesting for $d..."
+ certbot --nginx -n --keep -d "$d"
+ done
+
+ while :; do
+ echo "renewing domains..."
+ certbot --nginx --keep -n renew
+ sleep 12h &
+ wait $!
+ done &
+else
+ echo "skipping certbot due to no domains!"
+fi &
+
+exec "$@"
\ No newline at end of file
diff --git a/servers/apoc/docker-compose.d/custom/nginx/nginx.conf b/servers/apoc/docker-compose.d/custom/nginx/nginx.conf
new file mode 100644
index 0000000..2f54d99
--- /dev/null
+++ b/servers/apoc/docker-compose.d/custom/nginx/nginx.conf
@@ -0,0 +1,35 @@
+
+user nginx;
+worker_processes auto;
+
+error_log /var/log/nginx/error.log notice;
+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"';
+
+ # docker resolver and quad9;
+ resolver 127.0.0.11 9.9.9.9 ipv6=off;
+
+ access_log /var/log/nginx/access.log main;
+
+ sendfile on;
+ #tcp_nopush on;
+
+ keepalive_timeout 65;
+
+ #gzip on;
+
+ include /etc/nginx/conf.d/*.conf;
+}
diff --git a/servers/apoc/docker-compose.d/docker-compose.dms.yml b/servers/apoc/docker-compose.d/docker-compose.dms.yml
new file mode 100644
index 0000000..afeceb7
--- /dev/null
+++ b/servers/apoc/docker-compose.d/docker-compose.dms.yml
@@ -0,0 +1,34 @@
+version: '2.2'
+
+services:
+ mailserver:
+ image: ghcr.io/docker-mailserver/docker-mailserver:latest
+ container_name: mailserver
+ # Provide the FQDN of your mail server here (Your DNS MX record should point to this value)
+ hostname: mail.ixvd.net
+ env_file: ../../env/mailserver.env
+ # More information about the mail-server ports:
+ # https://docker-mailserver.github.io/docker-mailserver/latest/config/security/understanding-the-ports/
+ # To avoid conflicts with yaml base-60 float, DO NOT remove the quotation marks.
+ ports:
+ - "25:25" # SMTP (explicit TLS => STARTTLS)
+ - "143:143" # IMAP4 (explicit TLS => STARTTLS)
+ - "465:465" # ESMTP (implicit TLS)
+ - "587:587" # ESMTP (explicit TLS => STARTTLS)
+ - "993:993" # IMAP4 (implicit TLS)
+ volumes:
+ - /srv/mailserver/data:/var/mail/
+ - /srv/mailserver/config:/tmp/docker-mailserver/
+ - /srv/mailserver/other/state:/var/mail-state/
+ - /srv/mailserver/other/log/:/var/log/mail/
+ - /etc/localtime:/etc/localtime:ro
+ - /srv/certbot/data/live/mail.ixvd.net:/etc/letsencrypt/live/mail.ixvd.net
+ restart: always
+ stop_grace_period: 1m
+ # Uncomment if using `ENABLE_FAIL2BAN=1`:
+ # cap_add:
+ # - NET_ADMIN
+ healthcheck:
+ test: "ss --listening --tcp | grep -P 'LISTEN.+:smtp' || exit 1"
+ timeout: 3s
+ retries: 0
diff --git a/servers/apoc/docker-compose.d/docker-compose.git.yml b/servers/apoc/docker-compose.d/docker-compose.git.yml
new file mode 100644
index 0000000..58031b2
--- /dev/null
+++ b/servers/apoc/docker-compose.d/docker-compose.git.yml
@@ -0,0 +1,19 @@
+version: '2.2'
+services:
+ git:
+ image: codeberg.org/forgejo/forgejo:1.20
+ container_name: git # IMPORTANT FOR SSH
+ restart: always
+ privileged: true
+ environment:
+ USER_UID: 1000
+ USER_GID: 1002
+ volumes:
+ - /srv/gitea/data:/data/git
+ - /srv/gitea/config:/data/gitea
+ - /srv/gitea/other/ssh:/data/ssh
+ - /etc/timezone:/etc/timezone:ro
+ - /etc/localtime:/etc/localtime:ro
+ networks:
+ - proxy
+ - internal
diff --git a/servers/apoc/docker-compose.d/docker-compose.keycloak.yml b/servers/apoc/docker-compose.d/docker-compose.keycloak.yml
new file mode 100644
index 0000000..2db8ded
--- /dev/null
+++ b/servers/apoc/docker-compose.d/docker-compose.keycloak.yml
@@ -0,0 +1,36 @@
+version: '2.2'
+
+services:
+ keycloak:
+ build: custom/keycloak
+ command: start --optimized
+ env_file:
+ - /etc/ixvd/secrets/env/keycloak.env
+ depends_on:
+ - kcdb
+ environment:
+ KC_HOSTNAME: my.ixvd.net
+ KC_PROXY: edge
+ KC_HTTP_ENABLED: "true"
+ KC_HTTP_PORT: "80"
+ KC_DB: postgres
+ KC_DB_URL: jdbc:postgresql://kcdb:5432/keycloak
+ KC_DB_USERNAME: keycloak
+ KC_DB_PASSWORD: keycloak
+ networks:
+ - proxy
+ - keycloak
+
+ kcdb:
+ image: postgres:16
+ environment:
+ POSTGRES_USER: keycloak
+ POSTGRES_PASSWORD: keycloak
+ POSTGRES_DB: keycloak
+ volumes:
+ - /srv/keycloak/other/database:/var/lib/postgresql/data
+ networks:
+ - keycloak
+
+networks:
+ keycloak:
\ No newline at end of file
diff --git a/servers/apoc/docker-compose.d/docker-compose.rainloop.yml b/servers/apoc/docker-compose.d/docker-compose.rainloop.yml
new file mode 100644
index 0000000..b78498b
--- /dev/null
+++ b/servers/apoc/docker-compose.d/docker-compose.rainloop.yml
@@ -0,0 +1,19 @@
+version: '2.2'
+
+services:
+ rainloop:
+ image: hardware/rainloop
+ container_name: rainloop
+ depends_on:
+ - mailserver
+ volumes:
+ - /srv/rainloop/data:/rainloop/data
+ networks:
+ - proxy
+ - internal
+
+networks:
+ proxy:
+ external: true
+ internal:
+ external: true
\ No newline at end of file
diff --git a/servers/apoc/docker-compose.d/docker-compose.yml b/servers/apoc/docker-compose.d/docker-compose.yml
new file mode 100644
index 0000000..f5cf8c7
--- /dev/null
+++ b/servers/apoc/docker-compose.d/docker-compose.yml
@@ -0,0 +1,26 @@
+# I'm very comfortable in this version, therefore it's the standard
+version: '2.2'
+
+services:
+ # default nginx setup
+ nginx:
+ build: custom/nginx
+ environment:
+ CERTBOT_EMAIL: "webmaster@ixvd.net"
+ CERTBOT_DOMAINS: "apoc.ixvd.net,mail.ixvd.net,git.ixvd.net,my.ixvd.net"
+ volumes:
+ - /srv/certbot/data:/etc/letsencrypt
+ - /srv/certbot/other/www:/var/www/certbot
+ ports:
+ - 80:80
+ - 443:443
+ networks:
+ - proxy
+
+# Here the default networks are defined
+networks:
+ proxy:
+ external: true
+ internal:
+ external: true
+
\ No newline at end of file
diff --git a/servers/apoc/setup.d/00-setup-git.sh b/servers/apoc/setup.d/00-setup-git.sh
new file mode 100644
index 0000000..5cfc7ba
--- /dev/null
+++ b/servers/apoc/setup.d/00-setup-git.sh
@@ -0,0 +1,7 @@
+#!/bin/sh
+
+if ! getent passwd git &>/dev/null; then
+ echo "creating git user..."
+ useradd -m git
+ usermod git -aG docker
+fi
diff --git a/servers/apoc/setup.d/10-apply-skel.sh b/servers/apoc/setup.d/10-apply-skel.sh
new file mode 100644
index 0000000..1ece9be
--- /dev/null
+++ b/servers/apoc/setup.d/10-apply-skel.sh
@@ -0,0 +1,7 @@
+#!/bin/sh
+
+echo "applying skel..."
+cp -r skel/. /
+
+echo "ensuring /home/git/docker-shell a+x..."
+chmod a+x /home/git/docker-shell
\ No newline at end of file
diff --git a/servers/apoc/skel/etc/ssh/sshd_config.d/git.conf b/servers/apoc/skel/etc/ssh/sshd_config.d/git.conf
new file mode 100644
index 0000000..17ac506
--- /dev/null
+++ b/servers/apoc/skel/etc/ssh/sshd_config.d/git.conf
@@ -0,0 +1,3 @@
+Match User git
+ AuthorizedKeysCommandUser git
+ AuthorizedKeysCommand /usr/bin/docker exec -i git /usr/local/bin/gitea keys -c /data/gitea/conf/app.ini -e git -u %u -t %t -k %k
\ No newline at end of file
diff --git a/servers/apoc/skel/home/git/docker-shell b/servers/apoc/skel/home/git/docker-shell
new file mode 100644
index 0000000..74d4fff
--- /dev/null
+++ b/servers/apoc/skel/home/git/docker-shell
@@ -0,0 +1,2 @@
+#!/bin/sh
+/usr/bin/docker exec -i --env SSH_ORIGINAL_COMMAND="$SSH_ORIGINAL_COMMAND" gitea sh "$@"
\ No newline at end of file