Restructured Documentation
Automatic Documentation Deployment / Sync Docs to https://kb.bunny-lab.io (push) Successful in 8s

This commit is contained in:
2026-09-05 14:08:43 -06:00
parent c4bd235eba
commit 289769a601
281 changed files with 5403 additions and 3563 deletions
@@ -0,0 +1,89 @@
---
tags:
- Homebox
- Asset Management
- Docker
---
## Purpose
Homebox is the inventory and organization system built for the Home User! With a focus on simplicity and ease of use, Homebox is the perfect solution for your home inventory, organization, and management needs.
[Reference Documentation](https://hay-kot.github.io/homebox/quick-start/)
!!! warning "Protect with Keycloak"
The GitHub project for this software appears to have been archived in a read-only state in June 2024. There is no default admin credential, so setting the environment variable `HBOX_OPTIONS_ALLOW_REGISTRATION` to `false` will literally make you unable to log into the system. You also cannot change it after-the-fact, so you cannot just register an account then disable it and restart the container, it doesn't work that way.
Due to this behavior, it is imperative that you deploy this either only internally, or if its external, put it behind something like [Authentik](<../../Identity and Certificates/Authentik.md>) or [Keycloak](<../../Identity and Certificates/Keycloak/Deploy Keycloak.md>).
## Docker Configuration
```yaml title="docker-compose.yml"
version: "3.4"
services:
homebox:
image: ghcr.io/hay-kot/homebox:latest
container_name: homebox
restart: always
environment:
- HBOX_LOG_LEVEL=info
- HBOX_LOG_FORMAT=text
- HBOX_WEB_MAX_UPLOAD_SIZE=10
- HBOX_MODE=production
- HBOX_OPTIONS_ALLOW_REGISTRATION=true
- HBOX_WEB_MAX_UPLOAD_SIZE=50
- HBOX_WEB_READ_TIMEOUT=20
- HBOX_WEB_WRITE_TIMEOUT=20
- HBOX_WEB_IDLE_TIMEOUT=60
- HBOX_MAILER_HOST=${HBOX_MAILER_HOST}
- HBOX_MAILER_PORT=${HBOX_MAILER_PORT}
- HBOX_MAILER_USERNAME=${HBOX_MAILER_USERNAME}
- HBOX_MAILER_PASSWORD=${HBOX_MAILER_PASSWORD}
- HBOX_MAILER_FROM=${HBOX_MAILER_FROM}
volumes:
- /srv/containers/homebox:/data/
ports:
- 7745:7745
networks:
docker_network:
ipv4_address: 192.168.5.25
networks:
docker_network:
external: true
```
```yaml title=".env"
HBOX_MAILER_HOST=mail.bunny-lab.io
HBOX_MAILER_PORT=587
HBOX_MAILER_USERNAME=noreply@bunny-lab.io
HBOX_MAILER_PASSWORD=REDACTED
HBOX_MAILER_FROM=noreply@bunny-lab.io
```
## Traefik Reverse Proxy Configuration
If the container does not run on the same host as Traefik, you will need to manually add configuration to Traefik's dynamic config file, outlined below.
```yaml
http:
routers:
homebox:
entryPoints:
- websecure
tls:
certResolver: letsencrypt
http2:
service: homebox
rule: Host(`box.bunny-lab.io`)
middlewares:
- "auth-bunny-lab-io" # Referencing the Keycloak Server
services:
homebox:
loadBalancer:
servers:
- url: http://192.168.5.25:7745
passHostHeader: true
```
## Related Documentation
- [Docker Network Prerequisite](<../../Containers/Docker/Create the Docker Network.md>) — The configuration references the external `docker_network`; prepare it on the intended Docker host.
- [Related Applications Documentation](<../../../reference/Applications/index.md>) — Find the connected deployments, procedures, and references for this subject.
- [Traefik Deployment](<../../Networking and Access/Reverse Proxies/Traefik.md>) — Prepare the reverse proxy before applying this page's routing configuration.
@@ -0,0 +1,150 @@
---
tags:
- Snipe-IT
- Asset Management
- Docker
---
## Purpose
A free open source IT asset/license management system.
!!! warning
The Snipe-IT container will attempt to launch after the MariaDB container starts, but MariaDB takes a while set itself up before it can accept connections; as a result, Snipe-IT will fail to initialize the database. Just wait about 30 seconds after deploying the stack, then restart the Snipe-IT container to initialize the database. You will know it worked if you see notes about data being `Migrated`.
## Docker Configuration
```yaml title="docker-compose.yml"
version: '3.7'
services:
snipeit:
image: snipe/snipe-it
ports:
- "8000:80"
depends_on:
- db
env_file:
- stack.env
volumes:
- /srv/containers/snipe-it:/var/lib/snipeit
networks:
docker_network:
ipv4_address: 192.168.5.50
redis:
image: redis:6.2.5-buster
ports:
- "6379:6379"
env_file:
- stack.env
networks:
docker_network:
ipv4_address: 192.168.5.51
db:
image: mariadb:10.5
ports:
- "3306:3306"
env_file:
- stack.env
volumes:
- /srv/containers/snipe-it/db:/var/lib/mysql
networks:
docker_network:
ipv4_address: 192.168.5.52
mailhog:
image: mailhog/mailhog:v1.0.1
ports:
# - 1025:1025
- "8025:8025"
env_file:
- stack.env
networks:
docker_network:
ipv4_address: 192.168.5.53
networks:
docker_network:
external: true
```
```yaml title=".env"
APP_ENV=production
APP_DEBUG=false
APP_KEY=base64:SomethingSecure
APP_URL=https://assets.bunny-lab.io
APP_TIMEZONE='America/Denver'
APP_LOCALE=en
MAX_RESULTS=500
PRIVATE_FILESYSTEM_DISK=local
PUBLIC_FILESYSTEM_DISK=local_public
DB_CONNECTION=mysql
DB_HOST=db
DB_DATABASE=snipedb
DB_USERNAME=snipeuser
DB_PASSWORD=SomethingSecure
DB_PREFIX=null
DB_DUMP_PATH='/usr/bin'
DB_CHARSET=utf8mb4
DB_COLLATION=utf8mb4_unicode_ci
IMAGE_LIB=gd
MYSQL_DATABASE=snipedb
MYSQL_USER=snipeuser
MYSQL_PASSWORD=SomethingSecure
MYSQL_ROOT_PASSWORD=SomethingSecure
REDIS_HOST=redis
REDIS_PASSWORD=SomethingSecure
REDIS_PORT=6379
MAIL_DRIVER=smtp
MAIL_HOST=mail.bunny-lab.io
MAIL_PORT=587
MAIL_USERNAME=assets@bunny-lab.io
MAIL_PASSWORD=SomethingSecure
MAIL_ENCRYPTION=starttls
MAIL_FROM_ADDR=assets@bunny-lab.io
MAIL_FROM_NAME='Bunny Lab Asset Management'
MAIL_REPLYTO_ADDR=assets@bunny-lab.io
MAIL_REPLYTO_NAME='Bunny Lab Asset Management'
MAIL_AUTO_EMBED_METHOD='attachment'
DATA_LOCATION=/srv/containers/snipe-it
APP_TRUSTED_PROXIES=192.168.5.29
```
## Traefik Reverse Proxy Configuration
If the container does not run on the same host as Traefik, you will need to manually add configuration to Traefik's dynamic config file, outlined below.
```yaml
http:
routers:
assets-bunny-lab-io:
entryPoints:
- websecure
rule: "Host(`assets.bunny-lab.io`)"
service: "assets-bunny-lab-io"
tls:
certResolver: letsencrypt
middlewares:
- "assets-bunny-lab-io"
- "auth-bunny-lab-io" # Referencing the Keycloak Server
middlewares:
assets-bunny-lab-io:
headers:
customRequestHeaders:
X-Forwarded-Proto: "https"
X-Forwarded-Host: "assets.bunny-lab.io"
customResponseHeaders:
X-Custom-Header: "CustomValue" # Example of a static header
services:
assets-bunny-lab-io:
loadBalancer:
servers:
- url: "http://192.168.5.50:8080"
passHostHeader: true
```
## Related Documentation
- [Docker Network Prerequisite](<../../Containers/Docker/Create the Docker Network.md>) — The configuration references the external `docker_network`; prepare it on the intended Docker host.
- [Related Applications Documentation](<../../../reference/Applications/index.md>) — Find the connected deployments, procedures, and references for this subject.
- [Traefik Deployment](<../../Networking and Access/Reverse Proxies/Traefik.md>) — Prepare the reverse proxy before applying this page's routing configuration.
@@ -0,0 +1,57 @@
---
tags:
- Niltalk
- Communication
- Docker
---
## Purpose
Niltalk is a web based disposable chat server. It allows users to create password protected disposable, ephemeral chatrooms and invite peers to chat rooms.
```yaml title="docker-compose.yml"
version: "3.7"
services:
redis:
image: redis:alpine
volumes:
- /srv/niltalk
restart: unless-stopped
networks:
docker_network:
ipv4_address: 192.168.5.196
niltalk:
image: kailashnadh/niltalk:latest
ports:
- "9000:9000"
depends_on:
- redis
restart: unless-stopped
networks:
docker_network:
ipv4_address: 192.168.5.197
labels:
- "traefik.enable=true"
- "traefik.http.routers.niltalk.rule=Host(`temp.cyberstrawberry.net`)"
- "traefik.http.routers.niltalk.entrypoints=websecure"
- "traefik.http.routers.niltalk.tls.certresolver=myresolver"
- "traefik.http.services.niltalk.loadbalancer.server.port=9000"
networks:
default:
external:
name: docker_network
docker_network:
external: true
volumes:
niltalk-data:
```
```yaml title=".env"
Not Applicable
```
## Related Documentation
- [Docker Network Prerequisite](<../../Containers/Docker/Create the Docker Network.md>) — The configuration references the external `docker_network`; prepare it on the intended Docker host.
- [Related Applications Documentation](<../../../reference/Applications/index.md>) — Find the connected deployments, procedures, and references for this subject.
@@ -0,0 +1,115 @@
---
tags:
- Rocket.Chat
- Communication
- Docker
---
## Purpose
Deploy a RocketChat and MongoDB database together.
!!! caution "Folder Pre-Creation"
You need to make the folders for the Mongo database before launching the container stack for the first time. If you do not make this folder ahead of time, Mongo will give Permission Denied errors to the data directorry. You can create the folder as well as adjust permissions with the following commands:
```sh
mkdir -p /srv/containers/rocketchat/mongodb/data
chmod -R 777 /srv/containers/rocketchat
```
```yaml title="docker-compose.yml"
services:
rocketchat:
image: registry.rocket.chat/rocketchat/rocket.chat:${RELEASE:-latest}
restart: always
# labels:
# traefik.enable: "true"
# traefik.http.routers.rocketchat.rule: Host(`${DOMAIN:-}`)
# traefik.http.routers.rocketchat.tls: "true"
# traefik.http.routers.rocketchat.entrypoints: https
# traefik.http.routers.rocketchat.tls.certresolver: le
environment:
MONGO_URL: "${MONGO_URL:-\
mongodb://${MONGODB_ADVERTISED_HOSTNAME:-rc_mongodb}:${MONGODB_INITIAL_PRIMARY_PORT_NUMBER:-27017}/\
${MONGODB_DATABASE:-rocketchat}?replicaSet=${MONGODB_REPLICA_SET_NAME:-rs0}}"
MONGO_OPLOG_URL: "${MONGO_OPLOG_URL:\
-mongodb://${MONGODB_ADVERTISED_HOSTNAME:-rc_mongodb}:${MONGODB_INITIAL_PRIMARY_PORT_NUMBER:-27017}/\
local?replicaSet=${MONGODB_REPLICA_SET_NAME:-rs0}}"
ROOT_URL: ${ROOT_URL:-http://localhost:${HOST_PORT:-3000}}
PORT: ${PORT:-3000}
DEPLOY_METHOD: docker
DEPLOY_PLATFORM: ${DEPLOY_PLATFORM:-}
REG_TOKEN: ${REG_TOKEN:-}
depends_on:
- rc_mongodb
expose:
- ${PORT:-3000}
dns:
- 1.1.1.1
- 1.0.0.1
- 8.8.8.8
- 8.8.4.4
ports:
- "${BIND_IP:-0.0.0.0}:${HOST_PORT:-3000}:${PORT:-3000}"
networks:
docker_network:
ipv4_address: 192.168.5.2
rc_mongodb:
image: docker.io/bitnami/mongodb:${MONGODB_VERSION:-5.0}
restart: always
volumes:
- /srv/containers/rocket.chat/mongodb:/bitnami/mongodb
environment:
MONGODB_REPLICA_SET_MODE: primary
MONGODB_REPLICA_SET_NAME: ${MONGODB_REPLICA_SET_NAME:-rs0}
MONGODB_PORT_NUMBER: ${MONGODB_PORT_NUMBER:-27017}
MONGODB_INITIAL_PRIMARY_HOST: ${MONGODB_INITIAL_PRIMARY_HOST:-rc_mongodb}
MONGODB_INITIAL_PRIMARY_PORT_NUMBER: ${MONGODB_INITIAL_PRIMARY_PORT_NUMBER:-27017}
MONGODB_ADVERTISED_HOSTNAME: ${MONGODB_ADVERTISED_HOSTNAME:-rc_mongodb}
MONGODB_ENABLE_JOURNAL: ${MONGODB_ENABLE_JOURNAL:-true}
ALLOW_EMPTY_PASSWORD: ${ALLOW_EMPTY_PASSWORD:-yes}
networks:
docker_network:
ipv4_address: 192.168.5.3
networks:
docker__network:
external: true
```
```yaml title=".env"
TZ=America/Denver
RELEASE=6.3.0
PORT=3000 #Redundant - Can be Removed
MONGODB_VERSION=6.0
MONGODB_INITIAL_PRIMARY_HOST=rc_mongodb #Redundant - Can be Removed
MONGODB_ADVERTISED_HOSTNAME=rc_mongodb #Redundant - Can be Removed
```
## Reverse Proxy Configuration
```yaml title="nginx.conf"
# Rocket.Chat Server
server {
listen 443 ssl;
server_name rocketchat.domain.net;
error_log /var/log/nginx/new_rocketchat_error.log;
client_max_body_size 500M;
location / {
proxy_pass http://192.168.5.2:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $http_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 https;
proxy_set_header X-Nginx-Proxy true;
proxy_redirect off;
}
}
```
## Related Documentation
- [Docker Network Prerequisite](<../../../Containers/Docker/Create the Docker Network.md>) — The configuration references the external `docker_network`; prepare it on the intended Docker host.
- [Related Applications Documentation](<../../../../reference/Applications/index.md>) — Find the connected deployments, procedures, and references for this subject.
- [Traefik Deployment](<../../../Networking and Access/Reverse Proxies/Traefik.md>) — Prepare the reverse proxy before applying this page's routing configuration.
@@ -0,0 +1,67 @@
---
tags:
- Dashy
- Dashboards
- Docker
---
## Purpose
A self-hostable personal dashboard built for you. Includes status-checking, widgets, themes, icon packs, a UI editor and tons more!
```yaml title="docker-compose.yml"
version: "3.8"
services:
dashy:
container_name: Dashy
# Pull latest image from DockerHub
image: lissy93/dashy
# Set port that web service will be served on. Keep container port as 80
ports:
- 4000:80
labels:
- "traefik.enable=true"
- "traefik.http.routers.dashy.rule=Host(`dashboard.cyberstrawberry.net`)"
- "traefik.http.routers.dashy.entrypoints=websecure"
- "traefik.http.routers.dashy.tls.certresolver=myresolver"
- "traefik.http.services.dashy.loadbalancer.server.port=80"
# Set any environmental variables
environment:
- NODE_ENV=production
- UID=1000
- GID=1000
# Pass in your config file below, by specifying the path on your host machine
volumes:
- /srv/Containers/Dashy/conf.yml:/app/public/conf.yml
- /srv/Containers/Dashy/item-icons:/app/public/item-icons
# Specify restart policy
restart: unless-stopped
# Configure healthchecks
healthcheck:
test: ['CMD', 'node', '/app/services/healthcheck']
interval: 1m30s
timeout: 10s
retries: 3
start_period: 40s
# Connect container to Docker_Network
networks:
docker_network:
ipv4_address: 192.168.5.57
networks:
default:
external:
name: docker_network
docker_network:
external: true
```
## Related Documentation
- [Docker Network Prerequisite](<../../Containers/Docker/Create the Docker Network.md>) — The configuration references the external `docker_network`; prepare it on the intended Docker host.
- [Related Applications Documentation](<../../../reference/Applications/index.md>) — Find the connected deployments, procedures, and references for this subject.
@@ -0,0 +1,70 @@
---
tags:
- Docker
- Homepage
- Dashboards
---
## Purpose
A highly customizable homepage (or startpage / application dashboard) with Docker and service API integrations.
```yaml title="docker-compose.yml"
version: '3.8'
services:
homepage:
image: ghcr.io/gethomepage/homepage:latest
container_name: homepage
volumes:
- /srv/containers/homepage-docker:/config
- /srv/containers/homepage-docker/icons:/app/public/icons
ports:
- 80:80
- 443:443
- 3000:3000
environment:
- PUID=1000
- PGID=1000
- TZ=America/Denver
- HOMEPAGE_ALLOWED_HOSTS=servers.bunny-lab.io
dns:
- 192.168.3.25
- 192.168.3.26
restart: unless-stopped
extra_hosts:
- "rancher.bunny-lab.io:192.168.3.21"
networks:
docker_network:
ipv4_address: 192.168.5.44
dockerproxy:
image: ghcr.io/tecnativa/docker-socket-proxy:latest
container_name: dockerproxy
environment:
- CONTAINERS=1 # Allow access to viewing containers
- SERVICES=1 # Allow access to viewing services (necessary when using Docker Swarm)
- TASKS=1 # Allow access to viewing tasks (necessary when using Docker Swarm)
- POST=0 # Disallow any POST operations (effectively read-only)
ports:
- 127.0.0.1:2375:2375
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro # Mounted as read-only
restart: unless-stopped
networks:
docker_network:
ipv4_address: 192.168.5.46
networks:
default:
external:
name: docker_network
docker_network:
external: true
```
```yaml title=".env"
Not Applicable
```
## Related Documentation
- [Docker Network Prerequisite](<../../Containers/Docker/Create the Docker Network.md>) — The configuration references the external `docker_network`; prepare it on the intended Docker host.
- [Related Applications Documentation](<../../../reference/Applications/index.md>) — Find the connected deployments, procedures, and references for this subject.
@@ -0,0 +1,79 @@
---
tags:
- Microsoft Exchange
- Lets Encrypt
- Email
---
## Purpose
If you want to set up automatic Let's Encrypt SSL certificates on a Microsoft Exchange server, you have to go through a few steps to install the WinACME bot, and configure it to automatically renew certificates.
!!! note "ACME Bot Provisioning Considerations"
This document assumes you want a fully-automated one-liner command for configuring the ACME Bot, it is also completely valid to go step-by-step through the bot to configure the SSL certificate, the IIS server, etc, and it will automatically create a Scheduled Task to renew on its own. The whole process is very straight-forward with most answers being the default option.
### Download the Win-ACME Bot
- Log into the on-premise Exchange Server via Datto RMM
- Navigate to: [https://www.win-acme.com/](https://www.win-acme.com/)
- On the top-right of the website, you will see a "**Download**" button with the most recent version of the Win-ACME bot
- Extract the contents of the ZIP file to "**C:\\Program Files (x86)\\Lets Encrypt**"
- Make the "**Lets Encrypt**" folder if it does not already exist
### Configure `settings_default.json`
- The next step involves us making a modification to the configuration of the Win-ACME bot that allows us to export the necessary private key data for Exchange
- Using a text editor, open the "**settings\_default.json**" file
- Look for the setting called "**PrivateKeyExportable**" and change the value from "**false**" to "**true**"
- Save and close the file
### Download and Install the SSL Certificate
- Open an administrative Command Line (DO NOT USE POWERSHELL)
- Navigate to the Let's Encrypt bot directory: `CD "C:\Program Files (x86)\Lets Encrypt"`
- Invoke the bot to automatically download and install the certificate into the IIS Server that Exchange uses to host the Exchange Server
- Be sure to change the placeholder subdomains to match the domain of the actual Exchange Server
- (e.g. "**mail.example.org**" | "**autodiscover.example.org**")
```text
wacs.exe --target manual --host mail.example.org,autodiscover.example.org --certificatestore My --acl-fullcontrol "network service,administrators" --installation iis,script --installationsiteid 1 --script "./Scripts/ImportExchange.ps1" --scriptparameters "'{CertThumbprint}' 'IIS,SMTP,IMAP' 1 '{CacheFile}' '{CachePassword}' '{CertFriendlyName}'" --verbose
```
- When the command is running, it will ask for an email address for alerts and abuse notifications, just put "**infrastructure@bunny-lab.io**"
- If you run into any unexpected errors that result in anything other than exiting with a status "0", consult with Nicole Rappe to proceed
- Check that the domain of the Exchange Server is reachable on port 80 as Let's Encrypt uses this to build the cert.
- Searching the external IP of the server on [Shodan](https://www.shodan.io/) will reveal all open ports.
### Troubleshooting
If you find that any of the services such as [https://mail.example.org/ecp](https://mail.example.org/ecp), [https://autodiscover.example.org](https://autodiscover.example.org), or [https://mail.example.org/owa](https://mail.example.org/owa) do not let you log in, proceed with the steps below to correct the "Certificate Binding" in IIS Manager:
- Open "**Server Manager**" > Tools > "**Internet Information Services (IIS) Manager**"
- Expand the "**Connections**" server tree on the left-hand side of the IIS Manager
- Expand the "**Sites**" folder
- Click on "**Default Web Site**"
- On the right-hand Actions menu, click on "**Bindings...**"
- A table will appear with different endpoints on the Exchange server > What you are looking for is an entry that looks like the following:
- **Type**: https
- **Host Name**: autodiscover.example.org
- **Port**: 443
- Double-click on the row, or click one then click the "**Edit**" button to open the settings for that endpoint
- Under "**SSL Certificate**" > Make sure the certificate name matches the following format: "**\[Manual\] autodiscover.example.org @ YYYY/MM/DD**"
- If it does not match the above, use the dropdown menu to correct it and click the "**OK**" button
- **Type**: https
- **Host Name**: mail.example.org
- **Port**: 443
- Repeat the steps seen above, except this time for "**mail.example.org**"
- Click on "**Exchange Back End**"
- On the right-hand Actions menu, click on "**Bindings...**"
- A table will appear with different endpoints on the Exchange server > What you are looking for is an entry that looks like the following:
- **Type**: https
- **Host Name**: <blank>
- **Port**: 444
- Repeat the steps seen above, ensuring that the "**\[Manual\] autodiscover.example.org @ YYYY/MM/DD**" certificate is selected and applied
- Click the "**OK**" button
- On the left-hand menu under "**Connections**" in IIS Manager, click on the server name itself
- (e.g. "**EXAMPLE-EXCHANGE (DOMAIN\\dptadmin**")
- On the right-hand "**Actions**" menu > Under "Manage Server" > Select "Restart"
- Wait for the IIS server to restart itself, then try accessing the webpages for Exchange that were exhibiting issues logging in
### Additional Documentation
- [https://www.alitajran.com/install-free-lets-encrypt-certificate-in-exchange-server/](https://www.alitajran.com/install-free-lets-encrypt-certificate-in-exchange-server/)
## Related Documentation
- [Related Email Documentation](<../../../../reference/Applications/Email/index.md>) — Find the connected deployments, procedures, and references for this subject.
@@ -0,0 +1,802 @@
---
tags:
- Proxmox Mail Gateway
- PMG
- Mailcow
- Email
- SMTP
---
## Purpose
This document defines the procedure for placing `Proxmox Mail Gateway` in front of an existing `Mailcow` server for inbound SMTP filtering.
PMG will handle inbound SMTP inspection before delivering accepted mail to Mailcow.
This document covers **inbound SMTP filtering only**.
It does not move:
- Outbound SMTP delivery
- DKIM signing
- SMTP submission
- IMAP
- POP3
- ManageSieve
- Mailcow certificates
- Mailcow web access
- Roundcube access
## Assumptions
Mailcow is already deployed and functional.
Mailcow already handles:
- Mailbox hosting
- User authentication
- Webmail
- Mailcow admin interface
- IMAP
- POP3
- SMTP submission
- Outbound delivery
- DKIM signing
- TLS certificates for `mail.bunny-lab.io`
Example environment:
```text
Proxmox Mail Gateway: 192.168.3.15
Mailcow Server: 192.168.3.61
Mail Hostname: mail.bunny-lab.io
Mail Domain: bunny-lab.io
Firewall: pfSense
Reverse Proxy: Traefik
```
!!! warning "Inbound SMTP Only"
Only move public inbound SMTP port `25` to PMG during this stage.
```text
Do not move mail client ports, outbound relay behavior, DKIM signing, or Mailcow web access.
```
## Architecture
### Existing Mail Flow
```text
Internet
|
v
pfSense WAN :25
|
v
Mailcow 192.168.3.61:25
```
### Target Mail Flow
```text
Internet
|
v
pfSense WAN :25
|
v
PMG 192.168.3.15:25
|
v
Mailcow 192.168.3.61:25
```
### Final Service Ownership
```text
PMG
- Inbound SMTP on port 25
- Spam filtering
- Virus filtering
- Tracking Center
- Quarantine
- Delivery of accepted inbound mail to Mailcow
Mailcow
- Mailbox hosting
- User authentication
- Webmail
- Mailcow admin interface
- IMAP
- POP3
- SMTP submission
- Outbound mail delivery
- DKIM signing
- TLS certificates for mail.bunny-lab.io
Traefik
- Public HTTP
- Public HTTPS
- Mailcow / Roundcube frontend routing
```
## DNS
Public DNS remains unchanged.
```text
bunny-lab.io MX 10 mail.bunny-lab.io
mail.bunny-lab.io A <Public WAN IP>
```
The public DNS records continue pointing to the WAN IP.
The firewall determines where inbound SMTP is delivered internally.
```text
pfSense WAN :25 -> PMG 192.168.3.15:25
```
!!! note "DNS Does Not Point to PMG Directly"
The public MX and A records do not point to the internal PMG IP.
```text
NAT controls the internal SMTP destination.
```
## Firewall and NAT Design
Only public inbound SMTP changes.
Change this:
```text
WAN :25 -> Mailcow 192.168.3.61:25
```
To this:
```text
WAN :25 -> PMG 192.168.3.15:25
```
Leave Mailcow client access ports pointed directly at Mailcow.
```text
WAN :465 -> Mailcow 192.168.3.61:465
WAN :587 -> Mailcow 192.168.3.61:587
WAN :993 -> Mailcow 192.168.3.61:993
WAN :995 -> Mailcow 192.168.3.61:995
WAN :110 -> Mailcow 192.168.3.61:110
WAN :143 -> Mailcow 192.168.3.61:143
WAN :4190 -> Mailcow 192.168.3.61:4190
```
Leave web traffic on the existing reverse proxy path.
```text
WAN :80 -> Traefik :80
WAN :443 -> Traefik :443
```
!!! warning "Do Not Move Mail Client Ports to PMG"
PMG is an SMTP gateway.
```text
Do not forward IMAP, POP3, SMTPS, Submission, or ManageSieve ports to PMG.
```
## Initial PMG Access
Access the PMG management interface.
```text
https://192.168.3.15:8006
```
Use the `root` credentials configured during PMG installation.
!!! note "Certificate Warning"
Browser certificate warnings are expected when accessing PMG by IP address unless a trusted certificate has already been configured for the management interface.
## Pre-Cutover Connectivity Checks
Confirm PMG can reach Mailcow on SMTP port `25`.
Run from the PMG shell:
```sh
# Confirm PMG can reach Mailcow SMTP
nc -vz 192.168.3.61 25
```
Expected result:
```text
(UNKNOWN) [192.168.3.61] 25 (smtp) open
```
Reverse DNS warnings are not automatically failures.
```text
inverse host lookup failed: Unknown host
```
If port `25` still reports as open, SMTP connectivity is working.
Confirm Mailcow presents an SMTP banner.
```sh
# Connect from PMG directly to Mailcow SMTP
nc 192.168.3.61 25
```
Expected banner:
```text
220-mail.bunny-lab.io ESMTP Postcow
220 mail.bunny-lab.io ESMTP Postcow
```
Exit the SMTP session.
```text
quit
```
!!! note "Mailcow SMTP Banner"
Mailcow commonly identifies its SMTP service as `Postcow`.
```text
That is expected.
```
## PMG Mail Proxy Ports
In PMG, navigate to:
```text
Configuration > Mail Proxy > Ports
```
Confirm:
```text
External SMTP Port: 25
```
No outbound filtering is configured during this stage.
!!! note "Internal SMTP Port"
PMG also has an internal SMTP port used for outbound filtering from an internal mail server.
```text
This deployment does not use outbound PMG filtering yet.
```
## PMG Relay Domains
In PMG, navigate to:
```text
Configuration > Mail Proxy > Relay Domains
```
Add the accepted mail domain.
```text
bunny-lab.io
```
This authorizes PMG to accept mail for the domain.
!!! warning "Relay Domains Are Required"
If the domain is missing from Relay Domains, PMG may reject inbound mail because it is not configured as responsible for that domain.
## PMG Default Relay
In PMG, navigate to:
```text
Configuration > Mail Proxy > Relaying
```
Configure Mailcow as the default relay.
```text
Default Relay: 192.168.3.61
Relay Port: 25
Relay Protocol: smtp
Disable MX Lookup: Yes
Smarthost: none
```
Target internal relay path:
```text
PMG 192.168.3.15
|
v
Mailcow 192.168.3.61:25
```
!!! note "Disable MX Lookup"
PMG should deliver accepted inbound mail directly to the internal Mailcow server.
```text
It should not perform public MX lookup for the local mail domain.
```
!!! note "No Smarthost"
Leave `Smarthost` unset or set to `none` for inbound-only filtering.
```text
Smarthost configuration is used for outbound relay behavior.
```
## Mailcow Forwarding Host
Configure Mailcow to trust PMG as a forwarding host.
In Mailcow, navigate to:
```text
System > Configuration Dropdown > Options > Forwarding Hosts Dropdown
```
Add the PMG IP address.
```text
192.168.3.15
```
Set the forwarding-host spam filter option to:
```text
Inactive
```
!!! note "Forwarding Host Behavior"
After cutover, Mailcow sees PMG as the immediate SMTP source for inbound mail.
```text
Trusting PMG allows Mailcow to interpret forwarded mail correctly.
```
!!! note "Spam Filtering Placement"
PMG is the primary inbound spam and virus filtering system.
```text
Leave Mailcow forwarding-host spam filtering inactive to avoid double-filtering messages already inspected by PMG.
```
## Outbound Mail
Leave outbound mail unchanged.
```text
Mailcow 192.168.3.61
|
v
Internet
```
Do not configure Mailcow to relay outbound mail through PMG during this stage.
Do not change:
```text
Relayhost
Outbound firewall rules
DKIM signing
SPF record
DMARC record
```
!!! warning "Do Not Move DKIM"
DKIM signing applies to outbound mail.
```text
This document only moves inbound SMTP filtering.
```
## Filtering Policy
Initial filtering ownership:
```text
PMG = primary inbound SMTP filtering, tracking, quarantine
Mailcow = mailbox hosting, authentication, webmail, mail client access
```
Avoid configuring both PMG and Mailcow to aggressively quarantine the same inbound mail stream.
!!! note "Keep Filtering Boring"
PMG should own edge filtering first.
```text
Mailcow should continue owning mailbox and client access behavior.
```
## SMTP NAT Cutover
After PMG relay domains, PMG default relay, and Mailcow forwarding host settings are configured, update the pfSense NAT rule.
Change:
```text
WAN :25 -> Mailcow 192.168.3.61:25
```
To:
```text
WAN :25 -> PMG 192.168.3.15:25
```
Do not change the remaining Mailcow port forwards.
```text
465 -> 192.168.3.61
587 -> 192.168.3.61
993 -> 192.168.3.61
995 -> 192.168.3.61
143 -> 192.168.3.61
110 -> 192.168.3.61
4190 -> 192.168.3.61
```
Do not change the Traefik web path.
```text
80 -> Traefik
443 -> Traefik
```
!!! warning "Cutover Point"
Changing `WAN :25` is the actual inbound mail cutover.
```text
External SMTP servers will begin connecting to PMG instead of Mailcow directly.
```
## Validation
### External SMTP Reachability
From an external system:
```sh
# Confirm public SMTP is reachable
nc -vz mail.bunny-lab.io 25
```
Alternative:
```sh
# Confirm public SMTP banner using telnet
telnet mail.bunny-lab.io 25
```
Expected result:
```text
Port 25 open
SMTP banner returned by gateway
```
!!! note "Internal Testing Limitations"
Internal tests may not represent public mail flow if NAT reflection or split-horizon DNS is involved.
```text
Prefer external testing.
```
If external port testing is unavailable, send real mail from an outside provider.
Usable external sources:
```text
Gmail
Outlook.com
iCloud
Proton Mail
Work mailbox hosted outside Mailcow
```
### Inbound Delivery
Send an external message to a Mailcow-hosted mailbox.
Expected path:
```text
External mailbox
|
v
mail.bunny-lab.io
|
v
pfSense WAN :25
|
v
PMG 192.168.3.15
|
v
Mailcow 192.168.3.61
|
v
User mailbox
```
Check PMG:
```text
PMG > Tracking Center
```
Expected PMG status:
```text
Status: accepted/delivered
Relay: 192.168.3.61[192.168.3.61]:25
```
Check Mailcow:
```text
System > Logs
```
or review the relevant Mailcow Postfix and Dovecot logs.
### Mail Client Access
Confirm normal mail client behavior remains unchanged.
Test:
```text
IMAP receive
SMTP submission send
Mobile mail client access
Desktop mail client access
Webmail / Roundcube access
Mailcow UI access
```
Expected service paths:
```text
IMAPS: 993 -> Mailcow
Submission: 587 -> Mailcow
SMTPS: 465 -> Mailcow
Web: 443 -> Traefik -> Mailcow
```
Confirm outbound mail still works by replying from a Mailcow-hosted mailbox to the external sender.
### PMG Queues
Check PMG queues after test delivery.
```text
PMG > Queues
```
Expected state:
```text
Queue empty or near-empty after delivery
```
Queue status confirms PMG is not silently holding or deferring mail because of relay, DNS, or delivery errors.
## Validation Checklist
- [ ] Public MX record points to `mail.bunny-lab.io`
- [ ] `mail.bunny-lab.io` resolves to the correct public WAN IP
- [ ] DNS records are unchanged
- [ ] PMG can reach Mailcow on `192.168.3.61:25`
- [ ] Mailcow SMTP banner is visible from PMG
- [ ] PMG external SMTP port is `25`
- [ ] PMG has `bunny-lab.io` configured as a relay domain
- [ ] PMG default relay points to `192.168.3.61`
- [ ] PMG relay port is `25`
- [ ] PMG relay protocol is `smtp`
- [ ] PMG internal delivery has MX lookup disabled
- [ ] PMG smarthost is unset or `none`
- [ ] Mailcow trusts `192.168.3.15` as a forwarding host
- [ ] Mailcow forwarding-host spam filter is `Inactive`
- [ ] Firewall forwards `WAN :25` to `192.168.3.15:25`
- [ ] Firewall still forwards mail client ports directly to Mailcow
- [ ] Traefik still handles Mailcow / Roundcube web traffic
- [ ] Inbound test mail appears in PMG Tracking Center
- [ ] PMG Tracking Center shows `accepted/delivered`
- [ ] PMG log shows delivery to `192.168.3.61:25`
- [ ] Inbound test mail is delivered to the Mailcow mailbox
- [ ] PMG queue is empty after delivery
- [ ] Mobile email client still works
- [ ] Desktop email client still works
- [ ] Webmail still works
- [ ] Replying outbound from Mailcow still works
- [ ] DKIM behavior is unchanged
- [ ] SPF record is unchanged
- [ ] DMARC record is unchanged
- [ ] Outbound mail routing is unchanged
## Troubleshooting
### Inbound Mail Never Reaches PMG
Verify NAT.
```text
WAN :25 -> 192.168.3.15:25
```
Verify inbound port `25` is not blocked by the ISP.
From an external system:
```sh
# Test public SMTP reachability
nc -vz mail.bunny-lab.io 25
```
If external testing is unavailable, send a real external test message and check:
```text
PMG > Tracking Center
```
### PMG Receives Mail but Does Not Deliver to Mailcow
Verify PMG relay settings.
```text
Default Relay: 192.168.3.61
Relay Port: 25
Relay Protocol: smtp
Disable MX Lookup: Yes
```
Verify Mailcow SMTP is reachable from PMG.
```sh
# Test Mailcow SMTP from PMG
nc -vz 192.168.3.61 25
```
Confirm the Mailcow SMTP banner.
```sh
# Inspect Mailcow SMTP banner from PMG
nc 192.168.3.61 25
```
Expected banner:
```text
220-mail.bunny-lab.io ESMTP Postcow
220 mail.bunny-lab.io ESMTP Postcow
```
### PMG Shows Reverse DNS Warning for Mailcow
A warning like this is not automatically a failure:
```text
inverse host lookup failed: Unknown host
```
If the connection still reports port `25` as open, SMTP connectivity is working.
### Mailcow Rejects Mail from PMG
Verify Mailcow trusts PMG as a forwarding host.
```text
192.168.3.15
```
Verify the recipient domain exists in Mailcow.
```text
bunny-lab.io
```
Verify the recipient mailbox or alias exists in Mailcow.
### Mail Clients Stop Working
Verify only inbound SMTP port `25` was moved to PMG.
These ports should still forward directly to Mailcow:
```text
465
587
993
995
110
143
4190
```
Expected service ownership:
```text
PMG -> inbound SMTP gateway only
Mailcow -> client access and mailbox services
```
### Roundcube or Mailcow Web UI Stops Working
Verify web traffic was not moved to PMG.
Expected path:
```text
WAN :80 -> Traefik :80
WAN :443 -> Traefik :443
```
PMG should not replace Traefik for Mailcow or Roundcube web access.
### Outbound Mail Stops Working
Outbound mail should not change during this deployment.
Verify no changes were made to:
```text
Mailcow relayhost
Outbound firewall behavior
DKIM signing
SPF record
DMARC record
Public DNS records
```
### Spam Filtering Behavior Is Confusing
Use one primary inbound filtering authority.
Recommended initial state:
```text
PMG = primary inbound edge spam filter
Mailcow = mailbox hosting and client access
```
Avoid dual aggressive quarantine policies until basic mail flow is stable.
## Confirmed Final State
After Stage 1, the environment should operate as follows:
```text
Inbound SMTP:
Internet -> pfSense WAN :25 -> PMG 192.168.3.15:25 -> Mailcow 192.168.3.61:25
Outbound SMTP:
Mailcow -> Internet
Mail Client Access:
Clients -> Mailcow
Webmail / Roundcube:
Internet -> Traefik -> Mailcow
```
The only public NAT behavior changed is:
```text
WAN :25
```
Unchanged components:
```text
DNS records
DKIM behavior
SPF record
DMARC record
Outbound mail routing
SMTP submission
IMAP
POP3
ManageSieve
Mailcow certificates
Traefik web routing
Mailcow / Roundcube web access
```
## Deployment Status
This document completes Stage 1 of the PMG deployment.
```text
Stage 1: Inbound filtering only
Stage 2: Optional outbound filtering
```
At the end of Stage 1:
```text
PMG = inbound SMTP filtering only
Mailcow = mailboxes, webmail, authenticated submission, certificates, DKIM, outbound delivery, user-facing mail services
```
## Maintain Mail Delivery
For sender-validation and trusted-relay failures after integration, follow [Repair Trusted Mail Delivery Between PMG and Mailcow](<../../../../workflows/Applications/Email/Proxmox Mail Gateway/Repair Trusted Mail Delivery Between PMG and Mailcow.md>).
## Related Documentation
- [Related Email Documentation](<../../../../reference/Applications/Email/index.md>) — Find the connected deployments, procedures, and references for this subject.
@@ -0,0 +1,17 @@
---
tags:
- cPanel
- Email
---
## Purpose
This documentation helps you deploy an email server within a cPanel hosted environment.
!!! warning "Incomplete Procedure"
The deployment steps remain a scaffold. No completed cPanel mail-server procedure is recorded here.
!!! note "Assumptions"
It is assumed that the cPanel environment is set up (prior) to following this documentation, as deploying cPanel itself is not covered in this document.
## Related Documentation
- [Related Email Documentation](<../../../../reference/Applications/Email/index.md>) — Find the connected deployments, procedures, and references for this subject.
@@ -0,0 +1,285 @@
---
tags:
- IredMail
- Email
---
## Purpose
Self-Hosted Open-Source email server that can be setup in minutes, and is enterprise-grade if upgraded with an iRedAdmin-Pro license.
!!! note "Assumptions"
It is assumed you are running at least Rocky Linux 9.3. While you can use CentOS Stream, Alma, Debian, Ubuntu, FreeBSD, and OpenBSD, the more enterprise-level sections of my homelab are built on Rocky Linux.
!!! warning "iRedMail / iRedAdmin-Pro Version Mismatching"
This document assumes you are deploying iRedMail 1.6.8, which at the time of writing, coincided with iRedAdmin-Pro 5.5. If you are not careful, you may end up with mismatched versions down the road as iRedMail keeps getting updates. Due to how you have to pay for a license in order to get access to the original iRedAdmin-Pro-SQL repository data, if a newer version of iRedAdmin-Pro comes out after February 2025, this document may not account for that, leaving you on an older version of the software. This is unavoidable if you want to avoid paying $500/year for licensing this software.
## Overview
The instructions below are specific to my homelab environment, but can be easily ported depending on your needs. This guide also assumes you want to operate a PostgreSQL-based iRedMail installation. You can follow along with the official documentation on [Installation](https://docs.iredmail.org/install.iredmail.on.rhel.html) as well as [DNS Record Configuration](https://docs.iredmail.org/setup.dns.html) if you want more detailed explanations throughout the installation process.
## Configure FQDN
Ensure the FQDN of the server is correctly set in `/etc/hostname`. The `/etc/hosts` file will be automatically injected using the FQDN from `/etc/hostname` in a script further down, don't worry about editing it.
## Disable SELinux
iRedMail doesn't work with SELinux, so please disable it by setting below value in its config file /etc/selinux/config. After server reboot, SELinux will be completely disabled.
```sh
# Elevate to Root User
sudo su
# Disable SELinux
sed -i 's/^SELINUX=.*/SELINUX=disabled/' /etc/selinux/config # (1)
setenforce 0
```
1. If you prefer to let SELinux prints warnings instead of enforcing, you can set this value instead: `SELINUX=permissive`
## iRedMail Installation
### Set Domain and iRedMail Version
Start by connecting to the server / VM via SSH, then set silent deployment variables below.
```sh
# Define some deployment variables.
VERSION="1.6.8" # (1)
MAIL_DOMAIN="bunny-lab.io" # (2)
```
1. This is the version of iRedMail you are deploying. You can find the newest version on the [iRedMail Download Page](https://www.iredmail.org/download.html).
2. This is the domain suffix that appears after mailbox names. e.g. `first.last@bunny-lab.io` would use a domain value of `bunny-lab.io`.
You will then proceed to bootstrap a silent unattended installation of iRedMail. (I've automated as much as I can to make this as turn-key as possible). Just copy/paste this whole thing into your terminal and hit ENTER.
!!! danger "Storage Space Requirements"
You absolutely need to ensure that `/var/vmail` has a lot of space. At least 16GB. This is where all of your emails / mailboxes / a lot of settings will be. If possible, create a second physical/virtual disk specifically for the `/var` partition, or specifically for `/var/vmail` at minimum, so you can expand it over time if necessary. LVM-based provisioning is recommended but not required.
### Install iRedMail
```sh
# Automatically configure the /etc/hosts file to point to the server listed in "/etc/hostname".
sudo sed -i "1i 127.0.0.1 $(cat /etc/hostname) $(cut -d '.' -f 1 /etc/hostname) localhost localhost.localdomain localhost4 localhost4.localdomain4" /etc/hosts
# Check for Updates in the Package Manager
yum update -y
# Install Extra Packages for Enterprise Linux
dnf -y install https://dl.fedoraproject.org/pub/epel/epel-release-latest-9.noarch.rpm
# Download the iRedMail binaries and extract them
cd /root
curl https://codeload.github.com/iredmail/iRedMail/tar.gz/refs/tags/$VERSION -o iRedMail-$VERSION.tar.gz
tar zxf iRedMail-$VERSION.tar.gz
# Create the unattend config file for silent deployment. This will automatically generate random 32-character passwords for all of the databases.
(echo "export STORAGE_BASE_DIR='/var/vmail'"; echo "export WEB_SERVER='NGINX'"; echo "export BACKEND_ORIG='PGSQL'"; echo "export BACKEND='PGSQL'"; for var in VMAIL_DB_BIND_PASSWD VMAIL_DB_ADMIN_PASSWD MLMMJADMIN_API_AUTH_TOKEN NETDATA_DB_PASSWD AMAVISD_DB_PASSWD IREDADMIN_DB_PASSWD RCM_DB_PASSWD SOGO_DB_PASSWD SOGO_SIEVE_MASTER_PASSWD IREDAPD_DB_PASSWD FAIL2BAN_DB_PASSWD PGSQL_ROOT_PASSWD DOMAIN_ADMIN_PASSWD_PLAIN; do echo "export $var='$(openssl rand -base64 48 | tr -d '+/=' | head -c 32)'"; done; echo "export FIRST_DOMAIN='$MAIL_DOMAIN'"; echo "export USE_IREDADMIN='YES'"; echo "export USE_SOGO='YES'"; echo "export USE_NETDATA='YES'"; echo "export USE_FAIL2BAN='YES'"; echo "#EOF") > /root/iRedMail-$VERSION/config
# Make Config Read-Only
chmod 400 /root/iRedMail-$VERSION/config
# Set Environment Variables for Silent Deployment
cd /root/iRedMail-$VERSION
# Deploy iRedMail via the Install Script
AUTO_USE_EXISTING_CONFIG_FILE=y \
AUTO_INSTALL_WITHOUT_CONFIRM=y \
AUTO_CLEANUP_REMOVE_SENDMAIL=y \
AUTO_CLEANUP_REPLACE_FIREWALL_RULES=y \
AUTO_CLEANUP_RESTART_FIREWALL=n \
AUTO_CLEANUP_REPLACE_MYSQL_CONFIG=y \
bash iRedMail.sh
```
When the installation is completed, take note of any output it gives you for future reference. Then reboot the server to finalize the server installation.
```text
reboot
```
!!! warning "Automatically-Generated Postmaster Password"
When you deploy iRedMail, it will give you a username and password for the postmaster account. If you accidentally forget to document this, you can log back into the server via SSH and see the credentials at `/root/iRedMail-$VERSION/iRedMail.tips`. This file is critical and contains passwords and DNS information such as DKIM record information as well.
## Networking Configuration
### Nested Reverse Proxy Configuration
In my homelab environment, I run Traefik reverse proxy in front of everything, which includes the NGINX reverse proxy that iRedMail creates. In my scenario, I have to make some custom adjustments to the reverse proxy dynamic configuration data to ensure it will step aside and let the NGINX reverse proxy inside of iRedMail handle everything, including handling its own SSL termination with Let's Encrypt.
```sh
tcp:
routers:
mail-tcp-router:
rule: "HostSNI(`mail.bunny-lab.io`)"
entryPoints: ["websecure"]
service: mail-nginx-service
tls:
passthrough: true
services:
mail-nginx-service:
loadBalancer:
servers:
- address: "192.168.3.13:443"
```
### Let's Encrypt ACME Certbot
At this point, we want to set up automatic Let's Encrypt SSL termination inside of iRedMail so we don't have to manually touch this in the future.
#### Generate SSL Certificate
=== "Debian/Ubuntu"
```sh
# Download the Certbot
sudo apt update
sudo apt install -y certbot
sudo certbot certonly --webroot -w /var/www/html -d mail.bunny-lab.io
# Set up Symbolic Links (Where iRedMail Expects Them)
sudo mv /etc/ssl/certs/iRedMail.crt{,.bak}
sudo mv /etc/ssl/private/iRedMail.key{,.bak}
sudo ln -s /etc/letsencrypt/live/mail.bunny-lab.io/fullchain.pem /etc/ssl/certs/iRedMail.crt
sudo ln -s /etc/letsencrypt/live/mail.bunny-lab.io/privkey.pem /etc/ssl/private/iRedMail.key
# Restart iRedMail Services
sudo systemctl restart postfix dovecot nginx
```
=== "CentOS/Rocky/AlmaLinux"
```sh
# Download the Certbot
sudo yum install -y epel-release
sudo yum install -y certbot
sudo certbot certonly --webroot -w /var/www/html -d mail.bunny-lab.io
# Set up Symbolic Links (Where iRedMail Expects Them)
sudo mv /etc/pki/tls/certs/iRedMail.crt{,.bak}
sudo mv /etc/pki/tls/private/iRedMail.key{,.bak}
sudo ln -s /etc/letsencrypt/live/mail.bunny-lab.io/fullchain.pem /etc/pki/tls/certs/iRedMail.crt
sudo ln -s /etc/letsencrypt/live/mail.bunny-lab.io/privkey.pem /etc/pki/tls/private/iRedMail.key
# Restart iRedMail Services
sudo systemctl restart postfix dovecot nginx
```
#### Configure Automatic Renewal
To automate the renewal process, set up a cron job that runs the certbot renew command regularly. This command will renew certificates that are due to expire within 30 days.
Open the crontab editor with the following command:
```sh
sudo crontab -e
```
Add the following line to run the renewal process daily at 3:01 AM:
```text
1 3 * * * certbot renew --post-hook 'systemctl restart postfix dovecot nginx'
```
### DNS Records
Now you need to set up DNS records in Cloudflare (or the DNS Registrar you have configured) so that the mail server can be found and validated.
| **Type** | **Name** | **Content** | **Proxy Status** | **TTL** |
| :--- | :--- | :--- | :--- | :--- |
| MX | bunny-lab.io | mail.bunny-lab.io | DNS Only | Auto |
| TXT | bunny-lab.io | "v=spf1 a:mail.bunny-lab.io ~all" | DNS Only | Auto |
| TXT | dkim._domainkey | v=DKIM1; p=`IREDMAIL-DKIM-VALUE` | DNS Only | 1 Hour |
| TXT | _dmarc | "v=DMARC1; p=reject; pct=100; rua=mailto:postmaster@bunny-lab.io; ruf=mailto:postmaster@bunny-lab.io" | DNS Only | Auto |
### Port Forwarding
Lastly, we need to set up port forwarding to open the ports necessary for the server to send and receive email.
| **Protocol** | **Port** | **Destination Server** | **Description** |
| :--- | :--- | :--- | :--- |
| TCP | 995 | 192.168.3.13 | POP3 service: port 110 over STARTTLS |
| TCP | 993 | 192.168.3.13 | IMAP service: port 143 over STARTTLS |
| TCP | 587 | 192.168.3.13 | SMTP service: port 587 over STARTTLS |
| TCP | 25 | 192.168.3.13 | SMTP (Email Server-to-Server Communication) |
## Install iRedAdmin-Pro
When it comes to adding extra features, start by copying the data from this [Bunny Lab repository](https://git.bunny-lab.io/bunny-lab/iRedAdmin-Pro-SQL) to the following folder by running these commands first:
```sh
# Stop the iRedMail Services
sudo systemctl stop postfix dovecot nginx
# Grant Temporary Access to the iRedAdmin Files and Folders
sudo chown nicole:nicole -R /opt/www/iRedAdmin-2.5
# Copy the data from the repository mentioned above into this folder, merging identical folders and files. Feel free to use your preferred file transfer tool tool / method (e.g. MobaXTerm / WinSCP).
# Change permissions back to normal
sudo chown iredadmin:iredadmin -R /opt/www/iRedAdmin-2.5
# Reboot the Server
sudo reboot
```
### Activate iRedAdmin-Pro
At this point, if you want to use iRedAdmin-Pro, you either have a valid license key, or you adjust the python function responsible for checking license keys to bypass the check, effectively forcing iRedAdmin to be activated. In this instance, we will be forcing activation by adjusting this function, seen below.
There is someone else who outlined all of these changes, and additional (aesthetic) ones, like removing the renew license button from the license page, but the core functionality is seen below. If you want to see the original repository this was inspired from, it can be found [Here](https://github.com/marcus-alicia/iRedAdmin-Pro-SQL)
```sh
# Take permission of the python script
sudo chown nicole:nicole /opt/www/iRedAdmin-2.5/libs/sysinfo.py
```
=== "Original Activation Function"
```python title="/opt/www/iRedAdmin-2.5/libs/sysinfo.py"
def get_license_info():
if len(__id__) != 32:
web.conn_iredadmin.delete("updatelog")
session.kill()
raise web.seeother("/login?msg=INVALID_PRODUCT_ID")
params = {
"v": __version__,
"f": __id__,
"lang": settings.default_language,
"host": get_hostname(),
"backend": settings.backend,
"webmaster": settings.webmaster,
"mac": ",".join(get_all_mac_addresses()),
}
url = "https://lic.iredmail.org/check_version/licenseinfo/" + __id__ + ".json"
url += "?" + urllib.parse.urlencode(params)
try:
urlopen = __get_proxied_urlopen()
_json = urlopen(url).read()
lic_info = json.loads(_json)
lic_info["id"] = __id__
return True, lic_info
except Exception as e:
return False, web.urlquote(e)
```
=== "Bypassed Activation Function"
```python title="/opt/www/iRedAdmin-2.5/libs/sysinfo.py"
def get_license_info():
return True, {
"status": "active",
"product": "iRedAdmin-Pro-SQL",
"licensekey": "forcefully-open-source",
"upgradetutorials": "https://docs.iredmail.org/iredadmin-pro.releases.html",
"purchased": "Never",
"contacts": "nicole.rappe@bunny-lab.io",
"latestversion": "5.5",
"expired": "Never",
"releasenotes": "https://docs.iredmail.org/iredadmin-pro.releases.html",
"id": __id__
}
```
```sh
# Revert permission of the python script
sudo chown iredadmin:iredadmin /opt/www/iRedAdmin-2.5/libs/sysinfo.py
# Reboot the Server (To be safe)
sudo reboot
```
!!! success "Successful Activation"
At this point, if you navigate to the [iRedAdmin-Pro License Page](https://mail.bunny-lab.io/iredadmin/system/license) you should see the server is activated successfully.
## Related Documentation
- [Related Email Documentation](<../../../../reference/Applications/Email/index.md>) — Find the connected deployments, procedures, and references for this subject.
+168
View File
@@ -0,0 +1,168 @@
---
tags:
- Mailcow
- Email
- Docker
---
## Purpose
The purpose of this document is to illustrate how to deploy Mailcow in a dockerized format.
!!! note "Assumptions"
It is assumed that you are deploying Mailcow into an existing Ubuntu Server environment. If you are using a different operating system, refer to the [official documentation](https://docs.mailcow.email/getstarted/install/).
### Setting Up Docker
Go ahead and set up docker and docker-compose with the following commands:
```bash
sudo su # (1)
curl -sSL https://get.docker.com/ | CHANNEL=stable sh # (2)
apt install docker-compose-plugin # (3)
systemctl enable --now docker # (4)
```
1. Make yourself root.
2. Install `Docker`
3. Install `Docker-Compose`
4. Make docker run automatically when the server is booted.
### Download and Deploy Mailcow
Run the following commands to pull down the mailcow deployment files and install them with docker. Go get a cup of coffee as the `docker compose pull` command may take a while to run.
!!! note "Potential `Docker Compose` Issues"
If you run the `docker-compose pull` command and it fails for some reason, change the command to `docker compose pull` instead. This is just the difference between the plugin version of compose versus the standalone version. Both will have the same result.
```bash
cd /opt
git clone https://github.com/mailcow/mailcow-dockerized
cd mailcow-dockerized
./generate_config.sh # (1)
docker-compose pull # (2)
docker-compose up -d
```
1. Generate a configuration file. Use a FQDN (`host.domain.tld`) as hostname when asked.
2. If you get an error about the ports of the `nginx-mailcow` service in the `docker-compose.yml` stack, change the ports for that service as follows:
```yaml
ports:
- "${HTTPS_BIND:-0.0.0.0}:${HTTPS_PORT:-443}:${HTTPS_PORT:-443}"
- "${HTTP_BIND:-0.0.0.0}:${HTTP_PORT:-80}:${HTTP_PORT:-80}"
```
### Firewall / NAT Configuration
Forward Mailcow service ports as follows:
```text
WAN :80 -> Traefik :80
WAN :443 -> Traefik :443
WAN :25 -> Mailcow :25
WAN :465 -> Mailcow :465
WAN :587 -> Mailcow :587
WAN :993 -> Mailcow :993
WAN :995 -> Mailcow :995
WAN :110 -> Mailcow :110
WAN :143 -> Mailcow :143
WAN :4190 -> Mailcow :4190
```
Mail protocol ports should be sent directly to the Mailcow server. Traefik should not terminate or proxy the SMTP, SMTPS, Submission, IMAP, IMAPS, POP3, POP3S, or ManageSieve ports.
### Reverse-Proxy Configuration
For the purposes of this document, it will be assumed that you are deploying Mailcow behind Traefik for web traffic only. Traefik should pass HTTPS through transparently, allowing Mailcow to manage and serve its own certificates.
You can use the following dynamic configuration file to achieve this:
```yaml title="/srv/containers/traefik/config/dynamic/mail.bunny-lab.io.yml"
# =====================================================================
# Mailcow / Traefik Dynamic Configuration
# Hostname: mail.bunny-lab.io
#
# Mailcow owns certificates.
# Traefik forwards HTTP and passes HTTPS through.
# Mail protocol ports are handled directly by pfSense -> Mailcow.
# =====================================================================
http:
routers:
mailcow-http:
entryPoints:
- web
rule: Host(`mail.bunny-lab.io`)
service: mailcow-http
priority: 100
services:
mailcow-http:
loadBalancer:
passHostHeader: true
servers:
- url: "http://192.168.3.61:80"
tcp:
routers:
mailcow-https-passthrough:
entryPoints:
- websecure
rule: HostSNI(`mail.bunny-lab.io`)
service: mailcow-https
tls:
passthrough: true
services:
mailcow-https:
loadBalancer:
servers:
- address: "192.168.3.61:443"
```
### Traefik-Specific Configuration
Traefik only needs the standard HTTP and HTTPS entrypoints for Mailcow web traffic. Mail protocol ports should not be exposed through Traefik if the firewall is forwarding those ports directly to Mailcow.
```yaml
#Entrypoints
- "--entrypoints.web.address=:80"
- "--entrypoints.websecure.address=:443"
#Ports
- "80:80"
- "443:443"
```
Do not add Mailcow mail protocol entrypoints or port bindings to Traefik unless you intentionally want Traefik to proxy those ports.
### Certificate Validation
Mailcow should manage and serve the certificate for `mail.bunny-lab.io`.
To verify the active Mailcow certificate on disk, run the following on the Mailcow server:
```bash
cd /opt/mailcow-dockerized
openssl x509 \
-in /opt/mailcow-dockerized/data/assets/ssl/cert.pem \
-noout -subject -issuer -dates -serial -fingerprint -sha256
```
If the certificate has renewed but services are still presenting an old certificate, restart the Mailcow services that serve TLS:
```bash
cd /opt/mailcow-dockerized
docker compose restart postfix-mailcow dovecot-mailcow nginx-mailcow
```
### Login to Mailcow
At this point, the Mailcow server has been deployed so you can log into it.
- **Administrators**: `https://${MAILCOW_HOSTNAME}/admin` (Username: `admin` | Password: `moohoo`)
- **Regular Mailbox Users**: `https://${MAILCOW_HOSTNAME}` (*FQDN only*)
### Mail-Client Considerations
You need to ensure that you generate an app password if you have MFA enabled within Mailcow. (MFA is non-functional in Roundcube/SoGo, you set it up via Mailcow itself). You can access it via the Mailcow configuration page: https://mail.bunny-lab.io/user, then look for the "**App Passwords**" tab.
### Running Updates
If you want to run updates, just SSH into the server, and navigate to `/opt/mailcow-dockerized` and run `./update.sh`. I recommend avoiding the IPv6 implementation section. Be patient, and the upgrade will be fully-automated.
## Related Documentation
- [Related Email Documentation](<../../../reference/Applications/Email/index.md>) — Find the connected deployments, procedures, and references for this subject.
- [Traefik Deployment](<../../Networking and Access/Reverse Proxies/Traefik.md>) — Prepare the reverse proxy before applying this page's routing configuration.
@@ -0,0 +1,129 @@
---
tags:
- Collabora
- Productivity
- Docker
---
## Purpose
The Collabora CODE Server is used by Nextcloud Office to open and edit documents and spreadsheets collaboratively. When Nextcloud is not deployed in a [Nextcloud AIO](<Nextcloud AIO.md>) way, and is instead installed not as a container, you (may) run into stability issues with Collabora CODE Server just randomly breaking and not allowing users to edit documents. If this happens, you can follow this document to stand-up a dedicated Collabora CODE Server on the same host as your Nextcloud server.
!!! info "Assumptions"
- It is assumed that you are running an ACME Certificate Bot on your Nextcloud server to generate certificates for Nextcloud.
- It is also assumed that you are running Ubuntu Server 24.04.3 LTS. *This document does not outline the process for setting up an ACME Certificate Bot*.
- It is lastly assumed that (until changes are made to allow such) this will only work for internal access. Unless you port-forward port `9980` Collabora will not function for public internet-facing access.
### Install Docker and Configure Portainer
The first thing you need to do is install Docker then Portainer. You can do this by following the [Portainer Deployment](<../../Containers/Docker/Deploy Portainer.md>) documentation.
### Portainer Stack
```yaml title="docker-compose.yml"
name: app
services:
code:
image: collabora/code
container_name: collabora
restart: always
networks:
- collabora-net
environment:
- domain=${NEXTCLOUD_COLLABORA_URL}
- aliasgroup1=${NEXTCLOUD_COLLABORA_URL}
- username=${CODESERVER_ADMIN_USER} # Used to login @ https://cloud.bunny-lab.io:9980/browser/dist/admin/admin.html
- password=${CODESERVER_ADMIN_PASSWORD} # Used to login @ https://cloud.bunny-lab.io:9980/browser/dist/admin/admin.html
# CODE speaks HTTP internally, TLS is terminated at nginx
- extra_params=--o:ssl.enable=false --o:ssl.termination=true
# no direct port mapping; only reachable via proxy
collabora-proxy:
image: nginx:alpine
container_name: collabora-proxy
restart: always
depends_on:
- code
networks:
- collabora-net
ports:
# Host port 9980 -> container port 443 (HTTPS)
- "9980:443"
volumes:
# Our nginx vhost config (this exists outside of the container anywhere you want to put it, by default "/opt/collabora/nginx.conf")
- /opt/collabora/nginx.conf:/etc/nginx/conf.d/default.conf:ro
# Mount the entire letsencrypt tree so symlinks keep working
- /etc/letsencrypt:/etc/letsencrypt:ro
networks:
collabora-net:
driver: bridge
```
```yaml title=".env"
NEXTCLOUD_COLLABORA_URL=cloud\\.bunny-lab\\.io
CODESERVER_ADMIN_USER=admin
CODESERVER_ADMIN_PASSWORD=ChangeThisPassword
```
## NGINX Reverse Proxy Configuration
If the container does not run on the same host as Traefik, you will need to manually add configuration to Traefik's dynamic config file, outlined below.
```yaml title="/opt/collabora/nginx.conf"
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
server {
listen 443 ssl;
server_name cloud.bunny-lab.io;
ssl_certificate /etc/letsencrypt/live/cloud.bunny-lab.io/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/cloud.bunny-lab.io/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers on;
# Main proxy to CODE
location / {
proxy_pass http://collabora:9980;
# Required for WebSockets
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
# Standard headers
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto https;
proxy_read_timeout 36000;
proxy_connect_timeout 36000;
proxy_send_timeout 36000;
proxy_buffering off;
proxy_request_buffering off;
}
}
```
### Configuring Nextcloud Office
Now that the Collabora CODE Server was deployed and instructed to use the existing LetsEncrypt SSL Certificates located in `/etc/letsencrypt/live/cloud.bunny-lab.io/` on the Ubuntu host, we can proceed to reconfiguring Nextcloud to use this new server.
- Login to the Nextcloud server as an administrator
- Navigate to "**Apps**"
- Ensure that any existing ONLYOFFICE or Built-in Collabora CODE Server apps are disabled / removed from Nextcloud itself
- Navigate to "**Administration Settings**"
- In the left-hand "**Administration**" sidebar, look for something like "**Office**" or "**Nextcloud Office**" and click on it
- Check the radio box that says "**Use your own server**"
- For the URL, enter `https://cloud.bunny-lab.io:9980` and uncheck the "**Disable certificate verification (insecure)**" checkbox, then click the "**Save**" button.
!!! success "Collabora Online Server is Reachable"
At this point, you should see a green banner at the top of the Nextcloud webpage stating something like "**Collabora Online Development Edition 25.04.7.2 a246f9ab3c**". This would indicate that Nextcloud should be able to successfully talk with the Collabora CODE Server and that you can now proceed to verify that everything is working by trying to create and edit some documents and spreadsheets.
### Administrating Collabora CODE Server
As aforementioned, we can manage Collabora CODE Server sessions and useful metrics about who is editing documents and being able to terminate their sessions if they get stuck or something can be useful. You can login to the management web interface at https://cloud.bunny-lab.io:9980/browser/dist/admin/admin.html using the `CODESERVER_ADMIN_USER` and `CODESERVER_ADMIN_PASSWORD` credentials.
## Related Documentation
- [Related Files and Collaboration Documentation](<../../../reference/Applications/Files and Collaboration/index.md>) — Find the connected deployments, procedures, and references for this subject.
@@ -0,0 +1,174 @@
---
tags:
- Nextcloud AIO
- Nextcloud
- Productivity
- Docker
---
## Purpose
Deploy a Nextcloud AIO Server. [Official Nextcloud All-in-One Documentation](https://github.com/nextcloud/all-in-one).
This version of Nextcloud consists of 12 containers that are centrally managed by a single "master" container. It is more orchestrated and automates the implementation of Nextcloud Office, Nextcloud Talk, and other integrations / apps.
!!! note "Assumptions"
It is assumed you are running Rocky Linux 9.3.
It is also assumed that you are using Traefik as your reverse proxy in front of Nextcloud AIO. If it isnt, refer to the [reverse proxy documentation](https://github.com/nextcloud/all-in-one/blob/main/reverse-proxy.md) to configure other reverse proxies such as NGINX.
=== "Simplified Docker-Compose.yml"
```yaml title="docker-compose.yml"
services:
nextcloud-aio-mastercontainer:
image: nextcloud/all-in-one:latest
init: true
restart: always
container_name: nextcloud-aio-mastercontainer
volumes:
- nextcloud_aio_mastercontainer:/mnt/docker-aio-config
- /var/run/docker.sock:/var/run/docker.sock:ro
ports:
- 8080:8080
dns:
- 1.1.1.1
- 1.0.0.1
environment:
- APACHE_PORT=11000
- APACHE_IP_BINDING=0.0.0.0
- NEXTCLOUD_MEMORY_LIMIT=4096M
- NEXTCLOUD_ADDITIONAL_APKS=imagemagick
- NEXTCLOUD_ADDITIONAL_PHP_EXTENSIONS=imagick
volumes:
nextcloud_aio_mastercontainer:
name: nextcloud_aio_mastercontainer
```
=== "Extended Docker-Compose.yml"
```yaml title="docker-compose.yml"
services:
nextcloud-aio-mastercontainer:
image: nextcloud/all-in-one:latest
init: true
restart: always
container_name: nextcloud-aio-mastercontainer # This line is not allowed to be changed as otherwise AIO will not work correctly
volumes:
- nextcloud_aio_mastercontainer:/mnt/docker-aio-config # This line is not allowed to be changed as otherwise the built-in backup solution will not work
- /var/run/docker.sock:/var/run/docker.sock:ro # May be changed on macOS, Windows or docker rootless. See the applicable documentation. If adjusting, don't forget to also set 'WATCHTOWER_DOCKER_SOCKET_PATH'!
ports:
# - 80:80 # Can be removed when running behind a web server or reverse proxy (like Apache, Nginx, Cloudflare Tunnel and else). See https://github.com/nextcloud/all-in-one/blob/main/reverse-proxy.md
- 8080:8080
# - 8443:8443 # Can be removed when running behind a web server or reverse proxy (like Apache, Nginx, Cloudflare Tunnel and else). See https://github.com/nextcloud/all-in-one/blob/main/reverse-proxy.md
dns:
- 1.1.1.1
- 1.0.0.1
environment: # Is needed when using any of the options below
# AIO_DISABLE_BACKUP_SECTION: false # Setting this to true allows to hide the backup section in the AIO interface. See https://github.com/nextcloud/all-in-one#how-to-disable-the-backup-section
- APACHE_PORT=11000 # Is needed when running behind a web server or reverse proxy (like Apache, Nginx, Cloudflare Tunnel and else). See https://github.com/nextcloud/all-in-one/blob/main/reverse-proxy.md
- APACHE_IP_BINDING=0.0.0.0 # Should be set when running behind a web server or reverse proxy (like Apache, Nginx, Cloudflare Tunnel and else) that is running on the same host. See https://github.com/nextcloud/all-in-one/blob/main/reverse-proxy.md
# BORG_RETENTION_POLICY: --keep-within=7d --keep-weekly=4 --keep-monthly=6 # Allows to adjust borgs retention policy. See https://github.com/nextcloud/all-in-one#how-to-adjust-borgs-retention-policy
# COLLABORA_SECCOMP_DISABLED: false # Setting this to true allows to disable Collabora's Seccomp feature. See https://github.com/nextcloud/all-in-one#how-to-disable-collaboras-seccomp-feature
# NEXTCLOUD_DATADIR: /mnt/ncdata # Allows to set the host directory for Nextcloud's datadir. ⚠️⚠️⚠️ Warning: do not set or adjust this value after the initial Nextcloud installation is done! See https://github.com/nextcloud/all-in-one#how-to-change-the-default-location-of-nextclouds-datadir
# NEXTCLOUD_MOUNT: /mnt/ # Allows the Nextcloud container to access the chosen directory on the host. See https://github.com/nextcloud/all-in-one#how-to-allow-the-nextcloud-container-to-access-directories-on-the-host
# NEXTCLOUD_UPLOAD_LIMIT: 10G # Can be adjusted if you need more. See https://github.com/nextcloud/all-in-one#how-to-adjust-the-upload-limit-for-nextcloud
# NEXTCLOUD_MAX_TIME: 3600 # Can be adjusted if you need more. See https://github.com/nextcloud/all-in-one#how-to-adjust-the-max-execution-time-for-nextcloud
- NEXTCLOUD_MEMORY_LIMIT=4096M # Can be adjusted if you need more. See https://github.com/nextcloud/all-in-one#how-to-adjust-the-php-memory-limit-for-nextcloud
# NEXTCLOUD_TRUSTED_CACERTS_DIR: /path/to/my/cacerts # CA certificates in this directory will be trusted by the OS of the nexcloud container (Useful e.g. for LDAPS) See See https://github.com/nextcloud/all-in-one#how-to-trust-user-defined-certification-authorities-ca
# NEXTCLOUD_STARTUP_APPS="deck twofactor_totp tasks calendar contacts notes" # Allows to modify the Nextcloud apps that are installed on starting AIO the first time. See https://github.com/nextcloud/all-in-one#how-to-change-the-nextcloud-apps-that-are-installed-on-the-first-startup
- NEXTCLOUD_ADDITIONAL_APKS=imagemagick # This allows to add additional packages to the Nextcloud container permanently. Default is imagemagick but can be overwritten by modifying this value. See https://github.com/nextcloud/all-in-one#how-to-add-os-packages-permanently-to-the-nextcloud-container
- NEXTCLOUD_ADDITIONAL_PHP_EXTENSIONS=imagick # This allows to add additional php extensions to the Nextcloud container permanently. Default is imagick but can be overwritten by modifying this value. See https://github.com/nextcloud/all-in-one#how-to-add-php-extensions-permanently-to-the-nextcloud-container
# NEXTCLOUD_ENABLE_DRI_DEVICE: true # This allows to enable the /dev/dri device in the Nextcloud container. ⚠️⚠️⚠️ Warning: this only works if the '/dev/dri' device is present on the host! If it should not exist on your host, don't set this to true as otherwise the Nextcloud container will fail to start! See https://github.com/nextcloud/all-in-one#how-to-enable-hardware-transcoding-for-nextcloud
# NEXTCLOUD_KEEP_DISABLED_APPS: false # Setting this to true will keep Nextcloud apps that are disabled in the AIO interface and not uninstall them if they should be installed. See https://github.com/nextcloud/all-in-one#how-to-keep-disabled-apps
# TALK_PORT: 3478 # This allows to adjust the port that the talk container is using. See https://github.com/nextcloud/all-in-one#how-to-adjust-the-talk-port
# WATCHTOWER_DOCKER_SOCKET_PATH: /var/run/docker.sock # Needs to be specified if the docker socket on the host is not located in the default '/var/run/docker.sock'. Otherwise mastercontainer updates will fail. For macos it needs to be '/var/run/docker.sock'
# networks: # Is needed when you want to create the nextcloud-aio network with ipv6-support using this file, see the network config at the bottom of the file
# - nextcloud-aio # Is needed when you want to create the nextcloud-aio network with ipv6-support using this file, see the network config at the bottom of the file
# security_opt: ["label:disable"] # Is needed when using SELinux
# # Optional: Caddy reverse proxy. See https://github.com/nextcloud/all-in-one/blob/main/reverse-proxy.md
# # You can find further examples here: https://github.com/nextcloud/all-in-one/discussions/588
# caddy:
# image: caddy:alpine
# restart: always
# container_name: caddy
# volumes:
# - ./Caddyfile:/etc/caddy/Caddyfile
# - ./certs:/certs
# - ./config:/config
# - ./data:/data
# - ./sites:/srv
# network_mode: "host"
volumes: # If you want to store the data on a different drive, see https://github.com/nextcloud/all-in-one#how-to-store-the-filesinstallation-on-a-separate-drive
nextcloud_aio_mastercontainer:
name: nextcloud_aio_mastercontainer # This line is not allowed to be changed as otherwise the built-in backup solution will not work
# # Optional: If you need ipv6, follow step 1 and 2 of https://github.com/nextcloud/all-in-one/blob/main/docker-ipv6-support.md first and then uncomment the below config in order to activate ipv6 for the internal nextcloud-aio network.
# # Please make sure to uncomment also the networking lines of the mastercontainer above in order to actually create the network with docker-compose
# networks:
# nextcloud-aio:
# name: nextcloud-aio # This line is not allowed to be changed as otherwise the created network will not be used by the other containers of AIO
# driver: bridge
# enable_ipv6: true
# ipam:
# driver: default
# config:
# - subnet: fd12:3456:789a:2::/64 # IPv6 subnet to use
```
## Traefik Reverse Proxy Configuration
```yaml title="cloud.bunny-lab.io.yml"
http:
routers:
nextcloud-aio:
entryPoints:
- websecure
tls:
certResolver: letsencrypt
http2:
service: nextcloud-aio
middlewares:
- nextcloud-chain
rule: Host(`cloud.bunny-lab.io`)
services:
nextcloud-aio:
loadBalancer:
servers:
- url: http://192.168.3.29:11000
middlewares:
nextcloud-secure-headers:
headers:
hostsProxyHeaders:
- "X-Forwarded-Host"
referrerPolicy: "same-origin"
https-redirect:
redirectscheme:
scheme: https
nextcloud-chain:
chain:
middlewares:
# - ... (e.g. rate limiting middleware)
- https-redirect
- nextcloud-secure-headers
```
## Initial Setup
You will need to navigate to https://192.168.3.29:8080 to access the Nextcloud AIO configuration tool. This is where you will get the AIO password, encryption passphrase for backups, and be able to configure the timezone, among other things.
### Domain Validation
It will ask you to provide a domain name. In this example, we will use `cloud.bunny-lab.io`. Assuming you have configured the Traefik reverse proxy as seen above, when you press the "**Validate Domain**" button, Nextcloud will spin up a container named something similar to `domain-validator`. This will spin up a server listening on https://cloud.bunny-lab.io. If you visit that address, it should give you something similar to `f940935260b41691ac2246ba9e7823a301a1605ae8a023ee`. This will confirm that the domain validation will succeed.
!!! warning "Domain Validation Failing"
If visiting the web server at https://cloud.bunny-lab.io results in an error 502 or 404, try to destroy the domain validation container in Portainer / Docker, then click the validation button in the Nextcloud AIO WebUI to spin up a new container automatically, at which point it should be function.
### Configuring Additional Packages
At this point, the rest of the setup is fairly straightforward. You just check every checkbox for the apps you want to install automatically, and be patient while Nextcloud deploys about 11 containers. You can track the progress more accurately if you log into Portainer and watch the container listing and logs to follow-along until every container reports "**Healthy**" indicating everything is ready, then press the "**Refresh**" button on the Nextcloud AIO WebUI to confirm it's ready to be used.
## Related Documentation
- [Collabora Office Integration](<Collabora Code Server.md>) — Review the standalone office-server option and its Nextcloud requirements.
- [Related Files and Collaboration Documentation](<../../../reference/Applications/Files and Collaboration/index.md>) — Find the connected deployments, procedures, and references for this subject.
- [Traefik Deployment](<../../Networking and Access/Reverse Proxies/Traefik.md>) — Prepare the reverse proxy before applying this page's routing configuration.
@@ -0,0 +1,76 @@
---
tags:
- Nextcloud
- Productivity
- Docker
---
## Purpose
Deploy a Nextcloud and PostgreSQL database together.
```yaml title="docker-compose.yml"
version: "2.1"
services:
app:
image: nextcloud:apache
labels:
- "traefik.enable=true"
- "traefik.http.routers.nextcloud.rule=Host(`files.bunny-lab.io`)"
- "traefik.http.routers.nextcloud.entrypoints=websecure"
- "traefik.http.routers.nextcloud.tls.certresolver=letsencrypt"
- "traefik.http.services.nextcloud.loadbalancer.server.port=80"
environment:
- TZ=${TZ}
- POSTGRES_DB=${POSTGRES_DB}
- POSTGRES_USER=${POSTGRES_USER}
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
- POSTGRES_HOST=${POSTGRES_HOST}
- OVERWRITEPROTOCOL=https
- NEXTCLOUD_ADMIN_USER=${NEXTCLOUD_ADMIN_USER}
- NEXTCLOUD_ADMIN_PASSWORD=${NEXTCLOUD_ADMIN_PASSWORD}
- NEXTCLOUD_TRUSTED_DOMAINS=${NEXTCLOUD_TRUSTED_DOMAINS}
volumes:
- /srv/containers/nextcloud/html:/var/www/html
ports:
- 443:443
- 80:80
restart: always
depends_on:
- db
networks:
docker_network:
ipv4_address: 192.168.5.17
db:
image: postgres:12-alpine
environment:
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
- POSTGRES_USER=${POSTGRES_USER}
- POSTGRES_DB=${POSTGRES_DB}
volumes:
- /srv/containers/nextcloud/db:/var/lib/postgresql/data
ports:
- 5432:5432
restart: always
networks:
docker_network:
ipv4_address: 192.168.5.18
networks:
docker_network:
external: true
```
```yaml title=".env"
TZ=America/Denver
POSTGRES_PASSWORD=SomeSecurePassword
POSTGRES_USER=ncadmin
POSTGRES_HOST=192.168.5.18
POSTGRES_DB=nextcloud
NEXTCLOUD_ADMIN_USER=admin
NEXTCLOUD_ADMIN_PASSWORD=SomeSuperSecurePassword
NEXTCLOUD_TRUSTED_DOMAINS=cloud.bunny-lab.io
```
## Related Documentation
- [Docker Network Prerequisite](<../../Containers/Docker/Create the Docker Network.md>) — The configuration references the external `docker_network`; prepare it on the intended Docker host.
- [Related Files and Collaboration Documentation](<../../../reference/Applications/Files and Collaboration/index.md>) — Find the connected deployments, procedures, and references for this subject.
@@ -0,0 +1,76 @@
---
tags:
- OnlyOffice
- Productivity
- Docker
---
## Purpose
ONLYOFFICE offers a secure online office suite highly compatible with MS Office formats. Generally used with Nextcloud to edit documents directly within the web browser.
```yaml title="docker-compose.yml"
version: '3'
services:
app:
image: onlyoffice/documentserver-ee
ports:
- 80:80
- 443:443
volumes:
- /srv/containers/onlyoffice/DocumentServer/logs:/var/log/onlyoffice
- /srv/containers/onlyoffice/DocumentServer/data:/var/www/onlyoffice/Data
- /srv/containers/onlyoffice/DocumentServer/lib:/var/lib/onlyoffice
- /srv/containers/onlyoffice/DocumentServer/db:/var/lib/postgresql
- /srv/containers/onlyoffice/DocumentServer/fonts:/usr/share/fonts/truetype/custom
- /srv/containers/onlyoffice/DocumentServer/forgotten:/var/lib/onlyoffice/documentserver/App_Data/cache/files/forgotten
- /srv/containers/onlyoffice/DocumentServer/rabbitmq:/var/lib/rabbitmq
- /srv/containers/onlyoffice/DocumentServer/redis:/var/lib/redis
labels:
- "traefik.enable=true"
- "traefik.http.routers.cyberstrawberry-onlyoffice.rule=Host(`office.cyberstrawberry.net`)"
- "traefik.http.routers.cyberstrawberry-onlyoffice.entrypoints=websecure"
- "traefik.http.routers.cyberstrawberry-onlyoffice.tls.certresolver=myresolver"
- "traefik.http.services.cyberstrawberry-onlyoffice.loadbalancer.server.port=80"
- "traefik.http.routers.cyberstrawberry-onlyoffice.middlewares=onlyoffice-headers"
- "traefik.http.middlewares.onlyoffice-headers.headers.customrequestheaders.X-Forwarded-Proto=https"
#- "traefik.http.middlewares.onlyoffice-headers.headers.accessControlAllowOrigin=*"
environment:
- JWT_ENABLED=true
- JWT_SECRET=REDACTED #SET THIS TO SOMETHING SECURE
restart: always
networks:
docker_network:
ipv4_address: 192.168.5.143
networks:
default:
external:
name: docker_network
docker_network:
external: true
```
```yaml title=".env"
Not Applicable
```
!!! tip "Tip"
If you wish to use this in a non-commercial homelab environment without limits, [this script](https://wiki.muwahhid.ru/ru/Unraid/Docker/Onlyoffice-Document-Server) does an endless trial without functionality limits.
```text
docker stop office-document-server-ee
docker rm office-document-server-ee
rm -r /mnt/user/appdata/onlyoffice/DocumentServer
sleep 5
<USE A PORTAINER WEBHOOK TO RECREATE THE CONTAINER OR REFERENCE THE DOCKER RUN METHOD BELOW>
```
Docker Run Method:
```text
docker run -d --name='office-document-server-ee' --net='bridge' -e TZ="Europe/Moscow" -e HOST_OS="Unraid" -e 'JWT_ENABLED'='true' -e 'JWT_SECRET'='mySecret' -p '8082:80/tcp' -p '4432:443/tcp' -v '/mnt/user/appdata/onlyoffice/DocumentServer/logs':'/var/log/onlyoffice':'rw' -v '/mnt/user/appdata/onlyoffice/DocumentServer/data':'/var/www/onlyoffice/Data':'rw' -v '/mnt/user/appdata/onlyoffice/DocumentServer/lib':'/var/lib/onlyoffice':'rw' -v '/mnt/user/appdata/onlyoffice/DocumentServer/db':'/var/lib/postgresql':'rw' -v '/mnt/user/appdata/onlyoffice/DocumentServer/fonts':'/usr/share/fonts/truetype/custom':'rw' -v '/mnt/user/appdata/onlyoffice/DocumentServer/forgotten':'/var/lib/onlyoffice/documentserver/App_Data/cache/files/forgotten':'rw' -v '/mnt/user/appdata/onlyoffice/DocumentServer/rabbitmq':'/var/lib/rabbitmq':'rw' -v '/mnt/user/appdata/onlyoffice/DocumentServer/redis':'/var/lib/redis':'rw' 'onlyoffice/documentserver-ee'
```
## Related Documentation
- [Docker Network Prerequisite](<../../Containers/Docker/Create the Docker Network.md>) — The configuration references the external `docker_network`; prepare it on the intended Docker host.
- [Related Files and Collaboration Documentation](<../../../reference/Applications/Files and Collaboration/index.md>) — Find the connected deployments, procedures, and references for this subject.
@@ -0,0 +1,92 @@
---
tags:
- Pyload
- Media
- Gaming
- Docker
---
## Purpose
pyLoad-ng is a Free and Open Source download manager written in Python and designed to be extremely lightweight, easily extensible and fully manageable via web.
[Detailed LinuxServer.io Deployment Info](https://docs.linuxserver.io/images/docker-pyload-ng/)
## Docker Configuration
```yaml title="docker-compose.yml"
version: '3.9'
services:
pyload-ng:
image: lscr.io/linuxserver/pyload-ng:latest
container_name: pyload-ng
environment:
- PUID=1000
- PGID=1000
- TZ=America/Denver
volumes:
- /srv/containers/pyload-ng/config:/config
- nfs-share:/downloads
ports:
- 8000:8000
- 9666:9666 #optional
restart: unless-stopped
networks:
docker_network:
ipv4_address: 192.168.5.30
volumes:
nfs-share:
driver: local
driver_opts:
type: nfs
o: addr=192.168.3.3,nolock,soft,rw # Options for the NFS mount
device: ":/mnt/STORAGE/Downloads" # NFS path on the server
networks:
docker_network:
external: true
```
1. Set this to your own timezone.
2. This is optional. Additional documentation needed to convey what this port is used for. Possibly API access.
3. This assumes you want your download folder to be a SMB network share, this section allows you to connect to the share so Pyload can download content directly into the network folder. Replace the username and `REDACTED` password with your actual credentials. Remove the `domain` argument if the SMB server is not domain-joined.
4. This is the destination network share to target with the given credentials in section 3.
!!! note "NFS Mount Assumptions"
The NFS folder in this example is both exported via NFS on a TrueNAS Core server, while also being exported as an NFS export. `mapall user` and `mapall group` is configured to the user and group owners of the folder set in the permissions of the dataset in TrueNAS Core. In this case, the mapall user is `BUNNY-LAB\nicole.rappe` and the mapall group is `BUNNY-LAB\Domain Admins`.
```yaml title=".env"
N/A
```
## Traefik Reverse Proxy Configuration
If the container does not run on the same host as Traefik, you will need to manually add configuration to Traefik's dynamic config file, outlined below.
```yaml
http:
routers:
pyload:
entryPoints:
- websecure
tls:
certResolver: letsencrypt
http2:
service: pyload
rule: Host(`pyload.bunny-lab.io`)
services:
pyload:
loadBalancer:
servers:
- url: http://192.168.5.30:8000
passHostHeader: true
```
!!! warning "Change Default Admin Credentials"
Pyload ships with the username `pyload` and password `pyload`. Make sure you change the credentials immediately after initial login.
Navigate to "**Settings > Users > Pyload:"Change Password"**"
## Related Documentation
- [Docker Network Prerequisite](<../../Containers/Docker/Create the Docker Network.md>) — The configuration references the external `docker_network`; prepare it on the intended Docker host.
- [Related Files and Collaboration Documentation](<../../../reference/Applications/Files and Collaboration/index.md>) — Find the connected deployments, procedures, and references for this subject.
- [Traefik Deployment](<../../Networking and Access/Reverse Proxies/Traefik.md>) — Prepare the reverse proxy before applying this page's routing configuration.
@@ -0,0 +1,73 @@
---
tags:
- Stirling PDF
- Productivity
- Docker
---
## Purpose
This is a powerful locally hosted web based PDF manipulation tool using docker that allows you to perform various operations on PDF files, such as splitting merging, converting, reorganizing, adding images, rotating, compressing, and more. This locally hosted web application started as a 100% ChatGPT-made application and has evolved to include a wide range of features to handle all your PDF needs.
## Docker Configuration
```yaml title="docker-compose.yml"
version: "3.8"
services:
app:
image: frooodle/s-pdf:latest
container_name: stirling-pdf
environment:
- TZ=America/Denver
- DOCKER_ENABLE_SECURITY=false
volumes:
- /srv/containers/stirling-pdf/datastore:/datastore
- /srv/containers/stirling-pdf/trainingData:/usr/share/tesseract-ocr/5/tessdata #Required for extra OCR languages
- /srv/containers/stirling-pdf/extraConfigs:/configs
- /srv/containers/stirling-pdf/customFiles:/customFiles/
- /srv/containers/stirling-pdf/logs:/logs/
ports:
- 8080:8080
restart: always
networks:
docker_network:
ipv4_address: 192.168.5.54
networks:
default:
external:
name: docker_network
docker_network:
external: true
```
```yaml title=".env"
N/A
```
## Traefik Reverse Proxy Configuration
If the container does not run on the same host as Traefik, you will need to manually add configuration to Traefik's dynamic config file, outlined below.
```yaml
http:
routers:
stirling-pdf:
entryPoints:
- websecure
tls:
certResolver: letsencrypt
http2:
service: stirling-pdf
rule: Host(`pdf.bunny-lab.io`)
services:
stirling-pdf:
loadBalancer:
servers:
- url: http://192.168.5.54:8080
passHostHeader: true
```
## Related Documentation
- [Docker Network Prerequisite](<../../Containers/Docker/Create the Docker Network.md>) — The configuration references the external `docker_network`; prepare it on the intended Docker host.
- [Related Files and Collaboration Documentation](<../../../reference/Applications/Files and Collaboration/index.md>) — Find the connected deployments, procedures, and references for this subject.
- [Traefik Deployment](<../../Networking and Access/Reverse Proxies/Traefik.md>) — Prepare the reverse proxy before applying this page's routing configuration.
@@ -0,0 +1,62 @@
---
tags:
- Trilium
- Productivity
- Docker
---
## Purpose
Build your personal knowledge base with [Trilium Notes](https://github.com/zadam/trilium/tree/master).
```yaml title="docker-compose.yml"
version: '2.1'
services:
trilium:
image: zadam/trilium
restart: always
environment:
- TRILIUM_DATA_DIR=/home/node/trilium-data
ports:
- "8080:8080"
volumes:
- /srv/containers/trilium:/home/node/trilium-data
networks:
docker_network:
ipv4_address: 192.168.5.11
networks:
default:
external:
name: docker_network
docker_network:
external: true
```
```yaml title=".env"
N/A
```
## Traefik Configuration
```yaml title="notes.bunny-lab.io.yml"
http:
routers:
notes:
entryPoints:
- websecure
tls:
certResolver: letsencrypt
http2:
service: notes
rule: Host(`notes.bunny-lab.io`)
services:
notes:
loadBalancer:
servers:
- url: http://192.168.5.11:8080
passHostHeader: true
```
## Related Documentation
- [Docker Network Prerequisite](<../../Containers/Docker/Create the Docker Network.md>) — The configuration references the external `docker_network`; prepare it on the intended Docker host.
- [Related Files and Collaboration Documentation](<../../../reference/Applications/Files and Collaboration/index.md>) — Find the connected deployments, procedures, and references for this subject.
- [Traefik Deployment](<../../Networking and Access/Reverse Proxies/Traefik.md>) — Prepare the reverse proxy before applying this page's routing configuration.
@@ -0,0 +1,134 @@
---
tags:
- DFS
- Windows Server
- Windows
- File Services
---
## Purpose
If you want data available from a single, consistent UNC path while hosting it on multiple file servers, use **DFS Namespaces (DFSN)**. A namespace presents a *virtual* folder tree (for example, `\\bunny-lab.io\Projects`) whose folders point to one or more **folder targets** (actual SMB shares on your servers).
**DFS Replication (DFSR)** is a *separate* feature you configure to keep the contents of those targets in sync.
This document walks through creating a domain-based DFS namespace and enabling DFS Replication for two servers.
!!! info "Assumptions"
You have two Windows Server machines (e.g., `LAB-FPS-01` and `LAB-FPS-02`) running an edition that supports DFS (Standard or Datacenter), both activated, domain-joined, and using static IPs.
### Installing Server Roles
Install the roles on **both servers**:
- **Server Manager → Manage → Add Roles and Features**
- Click **Next** to **Server Roles**
- Expand **File and Storage Services**
- Expand **File and iSCSI Services**
- Check **File Server**
- Check **DFS Namespaces**
- Check **DFS Replication**
- **Next → Next → Install**, then finish.
### Create and Configure Network Shares
Create (or identify) the folders you want to publish in the namespace, and share them on **each** server. Be sure to enable **Access-based Enumeration** on all of the folder shares for additional security. You only need to ensure that the files exist on one of the file servers,then you need to create empty top-level folders with the same names on the replica servers, data will be replicated automatically from the file server to the empty folders.
Additionally, it is recommended (if possible) to set the share names to be hidden. For example `\\LAB-FPS-01\Projects$`, that way it ensures that users access the share via DFS at `\\bunny-lab.io\Projects` and users don't accidentally access the network shares directly, bypassing DFS. For example, the local path would be `Z:\Projects` but the network share would be `\\LAB-FPS-01\Projects$`. *This wouldn't break things like replication, but it would muck things up a little bit organizationally. The data would still be replicated between both servers, we just dont want users using direct server shares like that, which bypasses the high-availability and load-balancing features of DFS*
!!! warning "What must match vs. what can differ"
- **Must exist on each server:** a shared folder to act as the *folder target* (path can differ per server).
- **Share permissions:** are **not replicated**; set them on each server.
- **NTFS permissions inside the replicated folder:** **are replicated** by DFSR and should be consistent.
- Targets do **not** have to use identical share names/paths, but keeping them consistent simplifies things.
| **Permission Type** | **User / Group** | **Access** | Level** |
| :---- | :---- | :---- | :---- |
| Share | `Everyone` (or `Authenticated Users`) | Full Control | Best practice is to grant broad Full Control on the **share** and enforce access with NTFS. |
| NTFS | `SYSTEM` | Full Control | Required for DFSR service. |
| NTFS | `Share_Admins` | Full Control | Optional admin group for data management. |
| NTFS | *Business groups needing access* | Modify | Grant least privilege to required users/groups. |
!!! info "Note On Inheritance"
Disabling inheritance is **not required** for DFS/DFSR. Keep it enabled unless you have a clear reason to flatten ACLs; inheritance often reduces long-term admin overhead.
### DFS Breakdown
A **namespace** is a logical view like `\\bunny-lab.io\Projects`. Inside it, you create DFS **folders** (e.g., `Scripting`) that point to one or more **folder targets**, such as:
- `\\LAB-FPS-01\Projects$\Scripting`
- `\\LAB-FPS-02\Projects$\Scripting`
The namespace root itself isn't where you store data; it's a directory of links. Place data in the folder targets the DFS folder points to.
### DFS Configuration
You can run these steps from either server (or any admin workstation with the RSAT tools). DFSN configuration is stored in AD and on namespace servers and applies across members automatically.
#### Create Namespace
- **Server Manager → Tools → DFS Management**
- Right-click **Namespaces** → **New Namespace...**
- Choose a server to host the namespace (e.g., `LAB-FPS-01`) → **Next**
- Name the namespace (e.g., `Projects`) → **Next**
- You can leave **Edit Settings** at defaults; those control the local folder that backs the namespace root, not your data.
- Choose **Domain-based namespace** and check **Enable Windows Server 2008 mode** (required for larger scale and Access-based enumeration).
- Resulting path: `\\bunny-lab.io\Projects`
- **Next → Create**
#### Make Namespace Highly-Available
We have to perform an extra step to ensure that every file server can act as within a multi-master context, allowing for high availability. To do this in this example, we will add `LAB-FPS-02` as a secondary namespace server for every namespace that we create.
- Right-Click **DFS Management** > **Namespaces** > `\\bunny-lab.io\Projects`
- Click **Add Namespace Server...**
- Under "Namespace Server" enter `LAB-FPS-02` then click **OK**.
#### Enable Access-Based Enumeration on Namespace
- Right-Click **DFS Management** > **Namespaces** > `\\bunny-lab.io\Projects`
- Click **Properties**
- Click **Advanced**
- Check **Enable access-based enumeration for this namespace**
- Click **OK**
#### Link Folders to Namespace
Create the DFS folders and add folder targets:
- Right-click the new namespace (e.g., `\\bunny-lab.io\Projects`) → **New Folder...**
- **Name:** `Scripting`
- **Add** folder targets (one per server), e.g.:
- `\\LAB-FPS-01\Projects$\Scripting`
- `\\LAB-FPS-02\Projects$\Scripting`
- You can simply copy-paste the previous server location and substitute the hostname (e.g. switching `01` to `02`) instead of browsing for the folder.
- You *may* be prompted to create the folder because it does not exist on `LAB-FPS-02`, in this circumstance, you can tell it to create the folder automatically with read-only permissions. *Don't worry, when replication from `LAB-FPS-01` occurs, NTFS permissions will be overwritten to the correct users and groups.*
- When prompted *"Create a replication group to synchronize the folder targets?"*, click **Yes** to launch the DFS Replication wizard.
!!! info "**Be patient**"
The Replication wizard can take ~1 minute to appear.
#### Configure Replication Group
In the Replication wizard that appears after about a minute, you can configure the replication group for the folder:
!!! bug "If Wizard did Not Appear (or Crashed)"
In my homelab testing, I had two times when the wizard crashed or simply never opened. If this happens to you, you can manually re-trigger the wizard for the target folder by right-clicking the folder (e.g. `\\bunny-lab.io\Projects\Scripting`) and selecting **Replicate Folder**.
- **Replication Group Name**: *(leave as suggested)*
- **Replicated Folder Name**: *(leave as suggested)*
- **Next → Next**
- **Primary member**: pick the server with the **most up-to-date** copy of the data (e.g., `LAB-FPS-01`).
!!! abstract "Replication Behavior and Expectations"
When you first create a replication group, DFSR needs a baseline copy of the data to start from. You designate one server as the Primary Member to serve as that baseline. (e.g. `LAB-FPS-01`) During the first sync, DFSR assumes that whatever exists on the primary member's folder is the "truth." So if the same file exists on another server (e.g. `LAB-FPS-02`) but with different timestamps, sizes, or hashes, the primary member's copy wins - but only during this first synchronization. After that initial sync is complete, the "primary" flag loses all authority. Replication becomes multi-master, meaning every member can make changes, and DFSR uses its conflict resolution algorithm (based on version vectors, update sequence numbers, and timestamps) to decide which change wins going forward. In other words, no server remains “the boss” after initialization. Files unique to other member servers that only exist on them will not be wiped and will be replicated across all member servers including the primary member.
- **Topology**: `Full mesh` (good for two servers; for many sites, consider hub-and-spoke).
- **Replication schedule**: leave **Full** (24x7) unless you need bandwidth windows.
- **Create**
!!! success "Replication group created"
You should see green ticks for the following. Give everything some time to replicate as it depends on active directory replication speeds to push out the configuration across the DFS member servers and begin the replication.
- ✅Create replication group
- ✅Create members
- ✅Update folder security
- ✅Create replicated folder
- ✅Create membership objects
- ✅Update folder properties
- ✅Create connections
## Validate and Maintain DFS
Use [the namespace and replication report](<../../../../scripts/Applications/Files and Collaboration/DFS/Report DFS Namespaces and Replication.md>) to inspect the deployed structure, then [check the directional replication backlog](<../../../../scripts/Applications/Files and Collaboration/DFS/Report DFS Replication Backlog.md>). If the management console shows inconsistent objects, follow [the console repair workflow](<../../../../workflows/Applications/Files and Collaboration/DFS/Repair an Inconsistent DFS Management Console.md>).
## Related Documentation
- [Related Files and Collaboration Documentation](<../../../../reference/Applications/Files and Collaboration/index.md>) — Find the connected deployments, procedures, and references for this subject.
@@ -0,0 +1,61 @@
---
tags:
- WordPress
- Productivity
- Docker
---
## Purpose
At its core, WordPress is the simplest, most popular way to create your own website or blog. In fact, WordPress powers over 43.3% of all the websites on the Internet. Yes – more than one in four websites that you visit are likely powered by WordPress.
```yaml title="docker-compose.yml"
version: '3.7'
services:
wordpress:
image: wordpress:latest
restart: always
ports:
- 80:80
environment:
WORDPRESS_DB_HOST: 192.168.5.216
WORDPRESS_DB_USER: wordpress
WORDPRESS_DB_PASSWORD: ${WORDPRESS_DB_PASSWORD}
WORDPRESS_DB_NAME: wordpress
volumes:
- /srv/Containers/WordPress/Server:/var/www/html
networks:
docker_network:
ipv4_address: 192.168.5.217
depends_on:
- db
db:
image: lscr.io/linuxserver/mariadb
restart: always
ports:
- 3306:3306
environment:
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
MYSQL_DATABASE: wordpress
MYSQL_USER: wordpress
REMOTE_SQL: http://URL1/your.sql,https://URL2/your.sql
volumes:
- /srv/Containers/WordPress/DB:/config
networks:
docker_network:
ipv4_address: 192.168.5.216
networks:
default:
external:
name: docker_network
docker_network:
external: true
```
```yaml title=".env"
WORDPRESS_DB_PASSWORD=SecurePassword101
MYSQL_ROOT_PASSWORD=SecurePassword202
```
## Related Documentation
- [Docker Network Prerequisite](<../../Containers/Docker/Create the Docker Network.md>) — The configuration references the external `docker_network`; prepare it on the intended Docker host.
- [Related Files and Collaboration Documentation](<../../../reference/Applications/Files and Collaboration/index.md>) — Find the connected deployments, procedures, and references for this subject.
@@ -0,0 +1,75 @@
---
tags:
- ARK
- Gaming
---
## Purpose
This document outlines some of the prerequisites as well as deployment process for an ARK: Survival Ascended Server
## Prerequisites
We need to install the Visual C++ Redistributable for both x86 and x64
- [Download Visual C++ Redistributable (x64)](https://aka.ms/vs/17/release/vc_redist.x64.exe)
- [Download Visual C++ Redistributable (x86)](https://aka.ms/vs/17/release/vc_redist.x86.exe)
## Run Unreal Engine Certificate Trust Script
There is an issue where if you run a dedicated server, part of that requires API access to Epic Games and that will not work without installing a few certificates. The original Github page can be found [here](https://github.com/Ch4r0ne/UnrealEngine_Dedicated_Server_Install_CA/tree/main), which details the reason for it in more detail.
!!! note "Run as Administrator"
You need to run the command as an administrator. This command will download the script automatically and temporarily bypass the script execution policy to run the script:
```text
PowerShell -ExecutionPolicy Bypass -Command "irm 'https://raw.githubusercontent.com/Ch4r0ne/UnrealEngine_Dedicated_Server_Install_CA/main/Install_Certificate.ps1' | iex"
```
## SteamCMD Deployment Script
You will need to make a folder somewhere on the computer, such as the desktop, and name it something like "ARK Updater", then put the following script into it. You will need to run this script before you can proceed to the next step.
```text title="C:\Users\nicole.rappe\Desktop\ARK_Updater\Update_Server.bat"
@echo off
set STEAMCMDDIR="C:\SteamCMD\"
set SERVERDIR="C:\ASAServer\"
set ARKAPPID=2430930
cd /d %STEAMCMDDIR%
del steamcmd.exe
timeout /t 5 /nobreak
curl -o steamcmd.zip https://steamcdn-a.akamaihd.net/client/installer/steamcmd.zip
powershell Expand-Archive -Path .\steamcmd.zip -DestinationPath .\
start "" /wait steamcmd.exe +force_install_dir "%SERVERDIR%" +login anonymous +app_update %ARKAPPID% validate +quit
exit
```
## Launch Script
Now you need to configure a launch script to actually start the dedicated server. This can be placed anywhere, but I suggest putting it into `C:\asaserver\ShooterGame\Saved` along with the world save data.
```text title="C:\asaserver\ShooterGame\Saved\Launch_Server.bat"
@echo off
start C:\asaserver\ShooterGame\Binaries\Win64\ArkAscendedServer.exe ScorchedEarth_WP?listen?SessionName=BunnyLab?Port=7777?QueryPort=27015?ServerPassword=SomethingSecure?ServerAdminPassword=SomethingVerySecure -WinLiveMaxPlayers=50 -log -crossplay-enable-pc -crossplay-enable-wingdk -mods=928548,928621,928597,928818,929543,937546,930684,930404,940022,941697,930851,948051,932365,929420,967786,930494
exit
```
!!! tip "Adding Mods"
When you are adding mods, you will notice they are found on [CurseForge](https://www.curseforge.com/ark-survival-ascended). When you are looking for the mod ID, it is actually listed under CurseForge as the `Project ID`. Just copy that number and put it in a comma-separated list such as what is seen in the example above.
## Dump Configuration .ini Files
At this point, you will want to launch the server and have someone join it so it can generate the necessary world files / configuration data. Then you will run the following commands in the console (from the server hosting the ARK server) in order to dump the configuration (ini) files to disk.
```text
enablecheats <AdminPassword>
cheat SaveWorld
cheat DoExit
```
You will find the dumped configuration files at `C:\asaserver\ShooterGame\Saved\Config\WindowsServer`. The files you care about are `Game.ini` and `GameUserSettings.ini`.
!!! warning "Do not modify while server is running"
If you modify these configuration files while the server is running, it will overwrite the values when the server is stopped again. Be sure to either set the variables in-game via the console so it dumps them to disk, or wait until the server is stopped to make configuration ini file changes.
!!! info "Optional: Generate Files from Singleplayer World"
You may want to start a singleplayer world and set all of the configuration variables to your desired values, then load into the world. Once you have made landfall, quit out of the game to shut down the singleplayer world.
From this point, you can find your `Game.ini` and `GameUserSettings.ini` files in `steamapps\common\ARK Survival Ascended\ShooterGame\Saved\Config\Windows`. Simply copy these two files into your server's configuration folder located at `C:\asaserver\ShooterGame\Saved\Config\WindowsServer` and launch the server.
## Related Documentation
- [Related Applications Documentation](<../../../reference/Applications/index.md>) — Find the connected deployments, procedures, and references for this subject.
@@ -0,0 +1,75 @@
---
tags:
- EmulatorJS
- Media
- Gaming
- Docker
---
## Purpose
Emulatorjs is a browser web based emulation portable to nearly any device for many retro consoles. A mix of emulators is used between Libretro and EmulatorJS.
## Docker Configuration
```yaml title="docker-compose.yml"
---
services:
emulatorjs:
image: lscr.io/linuxserver/emulatorjs:latest
container_name: emulatorjs
environment:
- PUID=1000
- PGID=1000
- TZ=America/Denver
- SUBFOLDER=/ #optional
volumes:
- /srv/containers/emulatorjs/config:/config
- /srv/containers/emulatorjs/data:/data
ports:
- 3000:3000
- 80:80
- 4001:4001 #optional
restart: unless-stopped
networks:
docker_network:
ipv4_address: 192.168.5.200
networks:
docker_network:
external: true
```
```yaml title=".env"
N/A
```
## Traefik Reverse Proxy Configuration
If the container does not run on the same host as Traefik, you will need to manually add configuration to Traefik's dynamic config file, outlined below.
```yaml
http:
routers:
git:
entryPoints:
- websecure
tls:
certResolver: letsencrypt
http2:
service: emulatorjs
rule: Host(`emulatorjs.bunny-lab.io`)
services:
emulatorjs:
loadBalancer:
servers:
- url: http://192.168.5.200:80
passHostHeader: true
```
!!! note
Port 80 = Frontend
Port 3000 = Management Backend
## Related Documentation
- [Docker Network Prerequisite](<../../Containers/Docker/Create the Docker Network.md>) — The configuration references the external `docker_network`; prepare it on the intended Docker host.
- [Related Applications Documentation](<../../../reference/Applications/index.md>) — Find the connected deployments, procedures, and references for this subject.
- [Traefik Deployment](<../../Networking and Access/Reverse Proxies/Traefik.md>) — Prepare the reverse proxy before applying this page's routing configuration.
@@ -0,0 +1,62 @@
---
tags:
- Pterodactyl
- Gaming
---
## Purpose
Pterodactyl is the open-source game server management panel built with PHP, React, and Go. Designed with security in mind, Pterodactyl runs all game servers in isolated Docker containers while exposing a beautiful and intuitive UI to administrators and users.
[Official Website](https://pterodactyl.io/panel/1.0/getting_started.html)
!!! note
This documentation assumes you are running Rocky Linux 9.3 or higher.
**Install EPEL Repository and other tools**:
```bash
sudo yum -y install epel-release curl ca-certificates gnupg
```
**Add Redis Repository**:
```bash
sudo rpm --import https://packages.redis.io/gpg
echo "[redis6]
name=Redis 6 repository
baseurl=https://packages.redis.io/rpm/6/rhel/8/\$basearch/
enabled=1
gpgcheck=1
gpgkey=https://packages.redis.io/gpg" | sudo tee /etc/yum.repos.d/redis.repo
```
**Add MariaDB Repository**:
```bash
sudo curl -LsS https://downloads.mariadb.com/MariaDB/mariadb_repo_setup | sudo bash
```
**Update Repositories List**:
```bash
sudo yum update
```
**Install Dependencies**:
Before installing PHP, check the available PHP versions in your enabled repositories. Install PHP and other dependencies as follows:
```bash
sudo yum -y install php php-{common,cli,gd,mysql,mbstring,bcmath,xml,fpm,curl,zip} mariadb-server nginx tar unzip git redis
```
7. **Installing Composer**:
```bash
curl -sS https://getcomposer.org/installer | php
sudo mv composer.phar /usr/local/bin/composer
chmod +x /usr/local/bin/composer
```
This script should work well with Rocky Linux and similar RHEL-based distributions, using `yum` for package management. However, keep in mind that package names and versions may vary between repositories, so you might need to adjust them based on what's available in your system's repositories.
## Related Documentation
- [Related Applications Documentation](<../../../reference/Applications/index.md>) — Find the connected deployments, procedures, and references for this subject.
@@ -0,0 +1,42 @@
---
tags:
- Valheim
- Gaming
---
## Purpose
This document outlines some of the prerequisites as well as deployment process for an dedicated Valheim server.
## Prerequisites
We need to install the Visual C++ Redistributable for both x86 and x64
- [Download Visual C++ Redistributable (x64)](https://download.visualstudio.microsoft.com/download/pr/1754ea58-11a6-44ab-a262-696e194ce543/3642E3F95D50CC193E4B5A0B0FFBF7FE2C08801517758B4C8AEB7105A091208A/VC_redist.x64.exe)
- [Download Visual C++ Redistributable (x86)](https://download.visualstudio.microsoft.com/download/pr/b4834f47-d829-4e11-80f6-6e65081566b5/A32DD41EAAB0C5E1EAA78BE3C0BB73B48593DE8D97A7510B97DE3FD993538600/VC_redist.x86.exe)
## SteamCMD Deployment Script
You will need to make a folder somewhere on the computer, such as the desktop, and name it something like "ARK Updater", then put the following script into it. You will need to run this script before you can proceed to the next step.
```text title="C:\Users\nicole.rappe\Downloads\SteamCMD\Update_Server.bat"
@echo off
steamcmd.exe +force_install_dir "C:\Valheim_Dedicated_Server" +login anonymous +app_update 896660 -beta public validate +quit
```
## Launch Script
Now you need to configure a launch script to actually start the dedicated server. This can be placed anywhere, but I suggest putting it into `C:\asaserver\ShooterGame\Saved` along with the world save data.
```text title="C:\valheim_dedicated_server\Launch_Server.bat"
@echo off
set SteamAppId=892970
echo "Starting server PRESS CTRL-C to exit"
valheim_server -nographics -batchmode -name "Bunny Lab" -port 2456 -world "Dedicated" -password "SomethingVerySecure" -crossplay -saveinterval 300 -backups 72 -backupshort 600 -backuplong 21600
```
!!! warning "Launch Script Considerations"
- Make a local copy of this script to avoid it being overwritten by steam.
- Minimum password length is 5 characters & Password cant be in the server name.
- You need to make sure the ports TCP/UDP 2456-2457 is being forwarded to your server through your server VM & firewall.
## Related Documentation
- [Related Applications Documentation](<../../../reference/Applications/index.md>) — Find the connected deployments, procedures, and references for this subject.
@@ -0,0 +1,61 @@
---
tags:
- Frigate
- IoT
- Docker
---
## Purpose
A complete and local NVR designed for Home Assistant with AI object detection. Uses OpenCV and Tensorflow to perform realtime object detection locally for IP cameras.
```yaml title="docker-compose.yml"
version: "3.9"
services:
frigate:
container_name: frigate
privileged: true # this may not be necessary for all setups
restart: unless-stopped
image: blakeblackshear/frigate:stable
shm_size: "256mb" # update for your cameras based on calculation above
# devices:
# - /dev/bus/usb:/dev/bus/usb # passes the USB Coral, needs to be modified for other versions
# - /dev/apex_0:/dev/apex_0 # passes a PCIe Coral, follow driver instructions here https://coral.ai/docs/m2/get-started/#2a-on-linux
# - /dev/dri/renderD128 # for intel hwaccel, needs to be updated for your hardware
volumes:
- /etc/localtime:/etc/localtime:ro
- /mnt/1TB_STORAGE/frigate/config.yml:/config/config.yml:ro
- /mnt/1TB_STORAGE/frigate/media:/media/frigate
- type: tmpfs # Optional: 1GB of memory, reduces SSD/SD Card wear
target: /tmp/cache
tmpfs:
size: 4000000000
ports:
- "5000:5000"
- "1935:1935" # RTMP feeds
environment:
FRIGATE_RTSP_PASSWORD: ${FRIGATE_RTSP_PASSWORD}
networks:
docker_network:
ipv4_address: 192.168.5.201
mqtt:
container_name: mqtt
image: eclipse-mosquitto:1.6
ports:
- "1883:1883"
networks:
docker_network:
ipv4_address: 192.168.5.202
networks:
docker_network:
external: true
```
```yaml title=".env"
FRIGATE_RTSP_PASSWORD=SomethingSecure101
```
## Related Documentation
- [Docker Network Prerequisite](<../../Containers/Docker/Create the Docker Network.md>) — The configuration references the external `docker_network`; prepare it on the intended Docker host.
- [Related Applications Documentation](<../../../reference/Applications/index.md>) — Find the connected deployments, procedures, and references for this subject.
@@ -0,0 +1,52 @@
---
tags:
- Home Assistant
- IoT
- Docker
---
## Purpose
Open source home automation that puts local control and privacy first. Powered by a worldwide community of tinkerers and DIY enthusiasts.
```yaml title="docker-compose.yml"
version: '3'
services:
homeassistant:
container_name: homeassistant
image: "ghcr.io/home-assistant/home-assistant:stable"
environment:
- TZ=America/Denver
volumes:
- /srv/containers/Home-Assistant-Core:/config
- /etc/localtime:/etc/localtime:ro
restart: always
privileged: true
ports:
- 8123:8123
networks:
docker_network:
ipv4_address: 192.168.5.252
labels:
- "traefik.enable=true"
- "traefik.http.routers.homeassistant.rule=Host(`automation.cyberstrawberry.net`)"
- "traefik.http.routers.homeassistant.entrypoints=websecure"
- "traefik.http.routers.homeassistant.tls.certresolver=myresolver"
- "traefik.http.services.homeassistant.loadbalancer.server.port=8123"
networks:
default:
external:
name: docker_network
docker_network:
external: true
```
```yaml title=".env"
Not Applicable
```
## Related Documentation
- [Docker Network Prerequisite](<../../Containers/Docker/Create the Docker Network.md>) — The configuration references the external `docker_network`; prepare it on the intended Docker host.
- [Docker Macvlan Subinterface](<../../../workflows/Containers/Docker/Create a Macvlan Subinterface.md>) — Review the network setup documented for the home-automation environment.
- [Tuya Device Integration](<../../../workflows/Applications/Home Automation/Connect Tuya Smart Lights.md>) — Find the device reservations and local integration notes.
- [Frigate](<Frigate.md>) — Find the separately documented camera service.
- [Related Applications Documentation](<../../../reference/Applications/index.md>) — Find the connected deployments, procedures, and references for this subject.
@@ -0,0 +1,88 @@
---
tags:
- Gatus
- Monitoring
- Docker
---
## Purpose
Gatus Service Status Server.
## Docker Configuration
```yaml title="docker-compose.yml"
version: "3.9"
services:
postgres:
image: postgres
restart: always
volumes:
- /srv/containers/gatus/database:/var/lib/postgresql
ports:
- "5432:5432"
env_file:
- stack.env
networks:
docker_network:
ipv4_address: 192.168.5.9
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-postgres} -d ${POSTGRES_DB:-postgres}"]
interval: 10s
retries: 5
start_period: 30s
gatus:
image: twinproduction/gatus:latest
restart: always
ports:
- "8080:8080"
env_file:
- stack.env
volumes:
- /srv/containers/gatus/config:/config
depends_on:
postgres:
condition: service_healthy
dns:
- 192.168.3.25
- 192.168.3.26
networks:
docker_network:
ipv4_address: 192.168.5.8
networks:
docker_network:
external: true
```
```yaml title=".env"
N/A
```
## Traefik Reverse Proxy Configuration
If the container does not run on the same host as Traefik, you will need to manually add configuration to Traefik's dynamic config file, outlined below.
```yaml
http:
routers:
status-bunny-lab:
entryPoints:
- websecure
tls:
certResolver: letsencrypt
service: status-bunny-lab
rule: Host(`status.bunny-lab.io`)
middlewares:
- "auth-bunny-lab-io" # Referencing the Keycloak Server
services:
status-bunny-lab:
loadBalancer:
servers:
- url: http://192.168.5.8:8080
passHostHeader: true
```
## Related Documentation
- [Docker Network Prerequisite](<../../Containers/Docker/Create the Docker Network.md>) — The configuration references the external `docker_network`; prepare it on the intended Docker host.
- [Related Applications Documentation](<../../../reference/Applications/index.md>) — Find the connected deployments, procedures, and references for this subject.
- [Traefik Deployment](<../../Networking and Access/Reverse Proxies/Traefik.md>) — Prepare the reverse proxy before applying this page's routing configuration.
@@ -0,0 +1,48 @@
---
tags:
- ntfy
- Notifications
- Docker
---
## Purpose
ntfy (pronounced notify) is a simple HTTP-based pub-sub notification service. It allows you to send notifications to your phone or desktop via scripts from any computer, and/or using a REST API. It's infinitely flexible, and 100% free software.
```yaml title="docker-compose.yml"
version: "2.1"
services:
ntfy:
image: binwiederhier/ntfy
container_name: ntfy
command:
- serve
environment:
- NTFY_ATTACHMENT_CACHE_DIR=/var/lib/ntfy/attachments
- NTFY_BASE_URL=https://ntfy.bunny-lab.io
- TZ=America/Denver # optional: Change to your desired timezone
#user: UID:GID # optional: Set custom user/group or uid/gid
volumes:
- /srv/containers/ntfy/cache:/var/cache/ntfy
- /srv/containers/ntfy/etc:/etc/ntfy
ports:
- 80:80
restart: always
networks:
docker_network:
ipv4_address: 192.168.5.45
networks:
default:
external:
name: docker_network
docker_network:
external: true
```
```yaml title=".env"
Not Applicable
```
## Related Documentation
- [Docker Network Prerequisite](<../../Containers/Docker/Create the Docker Network.md>) — The configuration references the external `docker_network`; prepare it on the intended Docker host.
- [Related Applications Documentation](<../../../reference/Applications/index.md>) — Find the connected deployments, procedures, and references for this subject.
@@ -0,0 +1,114 @@
---
tags:
- Speedtest Tracker
- Monitoring
- Docker
---
## Purpose
Speedtest Tracker is a self-hosted application that monitors the performance and uptime of your internet connection over time.
[Detailed Configuration Reference](https://docs.speedtest-tracker.dev/getting-started/installation)
## Docker Configuration
```yaml title="docker-compose.yml"
services:
speedtest-tracker:
image: lscr.io/linuxserver/speedtest-tracker:latest
restart: unless-stopped
container_name: speedtest-tracker
ports:
- 8080:80
- 8443:443
environment:
- PUID=1000
- PGID=1000
- TZ=${TIMEZONE}
- ASSET_URL=${PUBLIC_FQDN}
- APP_TIMEZONE=${TIMEZONE}
- DISPLAY_TIMEZONE=${TIMEZONE}
- SPEEDTEST_SCHEDULE=*/15 * * * * # (1)
- SPEEDTEST_SERVERS=61622 # (3)
- APP_KEY=${BASE64_APPKEY} # (2)
- DB_CONNECTION=pgsql
- DB_HOST=db
- DB_PORT=5432
- DB_DATABASE=${DB_DATABASE}
- DB_USERNAME=${DB_USERNAME}
- DB_PASSWORD=${DB_PASSWORD}
volumes:
- /srv/containers/speedtest-tracker/config:/config
- /srv/containers/speedtest-tracker/custom-ssl-keys:/config/keys
depends_on:
- db
networks:
docker_network:
ipv4_address: 192.168.5.38
db:
image: postgres:17
restart: always
environment:
- POSTGRES_DB=${DB_DATABASE}
- POSTGRES_USER=${DB_USERNAME}
- POSTGRES_PASSWORD=${DB_PASSWORD}
- TZ=${TIMEZONE}
volumes:
- /srv/containers/speedtest-tracker/db:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER} -d ${POSTGRES_DB}"]
interval: 5s
retries: 5
timeout: 5s
networks:
docker_network:
ipv4_address: 192.168.5.39
networks:
default:
external:
name: docker_network
docker_network:
external: true
```
1. You can use [Crontab Guru](https://crontab.guru) to generate a cron expression to schedule automatic speedtests. e.g. `*/15 * * * *` runs a speedtest every 15 minutes.
2. You can generate a secure appkey with the following command: `echo -n 'base64:'; openssl rand -base64 32;` > Copy this key including the `base64:` prefix and paste it as your APP_KEY environment variable value.
3. This restricts the speedtest target to a specific speedtest server. In this example, it is a Missoula, MT speedtest server. You can get these codes from the yellow Speedtest button menu in the WebUI and then come back and redeploy the stack with the number entered here.
```yaml title=".env"
DB_PASSWORD=SecurePassword
DB_DATABASE=speedtest_tracker
DB_USERNAME=speedtest_tracker
TIMEZONE=America/Denver
PUBLIC_FQDN=https://speedtest.bunny-lab.io
BASE64_APPKEY=SECUREAPPKEY
```
## Traefik Reverse Proxy Configuration
If the container does not run on the same host as Traefik, you will need to manually add configuration to Traefik's dynamic config file, outlined below.
```yaml
http:
routers:
speedtest-tracker:
entryPoints:
- websecure
tls:
certResolver: letsencrypt
http2:
service: speedtest-tracker
rule: Host(`speedtest.bunny-lab.io`)
services:
speedtest-tracker:
loadBalancer:
servers:
- url: http://192.168.5.38:80
passHostHeader: true
```
## Related Documentation
- [Docker Network Prerequisite](<../../Containers/Docker/Create the Docker Network.md>) — The configuration references the external `docker_network`; prepare it on the intended Docker host.
- [Related Applications Documentation](<../../../reference/Applications/index.md>) — Find the connected deployments, procedures, and references for this subject.
- [Traefik Deployment](<../../Networking and Access/Reverse Proxies/Traefik.md>) — Prepare the reverse proxy before applying this page's routing configuration.
@@ -0,0 +1,45 @@
---
tags:
- Uptime Kuma
- Monitoring
- Docker
---
## Purpose
Deploy Uptime Kuma uptime monitor to monitor services in the homelab and send notifications to various services.
```yaml title="docker-compose.yml"
version: '3'
services:
uptimekuma:
image: louislam/uptime-kuma
ports:
- 3001:3001
volumes:
- /mnt/uptimekuma:/app/data
- /var/run/docker.sock:/var/run/docker.sock
environment:
# Allow status page to exist within an iframe
- UPTIME_KUMA_DISABLE_FRAME_SAMEORIGIN=1
restart: always
labels:
- "traefik.enable=true"
- "traefik.http.routers.uptime-kuma.rule=Host(`status.cyberstrawberry.net`)"
- "traefik.http.routers.uptime-kuma.entrypoints=websecure"
- "traefik.http.routers.uptime-kuma.tls.certresolver=letsencrypt"
- "traefik.http.services.uptime-kuma.loadbalancer.server.port=3001"
networks:
docker_network:
ipv4_address: 192.168.5.211
networks:
docker_network:
external: true
```
```yaml title=".env"
Not Applicable
```
## Related Documentation
- [Docker Network Prerequisite](<../../Containers/Docker/Create the Docker Network.md>) — The configuration references the external `docker_network`; prepare it on the intended Docker host.
- [Related Applications Documentation](<../../../reference/Applications/index.md>) — Find the connected deployments, procedures, and references for this subject.
@@ -0,0 +1,73 @@
---
tags:
- ChangeDetection
- Security
- Docker
---
## Purpose
Detect website content changes and perform meaningful actions - trigger notifications via Discord, Email, Slack, Telegram, API calls and many more.
## Docker Configuration
```yaml title="docker-compose.yml"
version: "3.8"
services:
app:
image: dgtlmoon/changedetection.io
container_name: changedetection.io
environment:
- TZ=America/Denver
volumes:
- /srv/containers/changedetection/datastore:/datastore
ports:
- 5000:5000
restart: always
labels:
- "traefik.enable=true"
- "traefik.http.routers.changedetection.rule=Host(`changedetection.bunny-lab.io`)"
- "traefik.http.routers.changedetection.entrypoints=websecure"
- "traefik.http.routers.changedetection.tls.certresolver=letsencrypt"
- "traefik.http.services.changedetection.loadbalancer.server.port=5000"
networks:
docker_network:
ipv4_address: 192.168.5.49
networks:
default:
external:
name: docker_network
docker_network:
external: true
```
```ini title=".env"
N/A
```
## Traefik Reverse Proxy Configuration
If the container does not run on the same host as Traefik, you will need to manually add configuration to Traefik's dynamic config file, outlined below.
```yaml
http:
routers:
changedetection:
entryPoints:
- websecure
tls:
certResolver: letsencrypt
http2:
service: changedetection
rule: Host(`changedetection.bunny-lab.io`)
services:
changedetection:
loadBalancer:
servers:
- url: http://192.168.5.49:5000
passHostHeader: true
```
## Related Documentation
- [Docker Network Prerequisite](<../../Containers/Docker/Create the Docker Network.md>) — The configuration references the external `docker_network`; prepare it on the intended Docker host.
- [Related Applications Documentation](<../../../reference/Applications/index.md>) — Find the connected deployments, procedures, and references for this subject.
- [Traefik Deployment](<../../Networking and Access/Reverse Proxies/Traefik.md>) — Prepare the reverse proxy before applying this page's routing configuration.
@@ -0,0 +1,40 @@
---
tags:
- CyberChef
- Security
- Docker
---
## Purpose
The Cyber Swiss Army Knife - a web app for encryption, encoding, compression and data analysis.
```yaml title="docker-compose.yml"
version: "3.8"
services:
app:
image: mpepping/cyberchef:latest
container_name: cyberchef
environment:
- TZ=America/Denver
ports:
- 8000:8000
restart: always
networks:
docker_network:
ipv4_address: 192.168.5.55
networks:
default:
external:
name: docker_network
docker_network:
external: true
```
```ini title=".env"
N/A
```
## Related Documentation
- [Docker Network Prerequisite](<../../Containers/Docker/Create the Docker Network.md>) — The configuration references the external `docker_network`; prepare it on the intended Docker host.
- [Related Applications Documentation](<../../../reference/Applications/index.md>) — Find the connected deployments, procedures, and references for this subject.
@@ -0,0 +1,38 @@
---
tags:
- IT-Tools
- Security
- Docker
---
## Purpose
Collection of handy online tools for developers, with great UX.
```yaml title="docker-compose.yml"
version: "3"
services:
server:
image: corentinth/it-tools:latest
container_name: it-tools
environment:
- TZ=America/Denver
restart: always
ports:
- "80:80"
networks:
docker_network:
ipv4_address: 192.168.5.16
networks:
docker_network:
external: true
```
```yaml title=".env"
Not Applicable
```
## Related Documentation
- [Docker Network Prerequisite](<../../Containers/Docker/Create the Docker Network.md>) — The configuration references the external `docker_network`; prepare it on the intended Docker host.
- [Related Applications Documentation](<../../../reference/Applications/index.md>) — Find the connected deployments, procedures, and references for this subject.
@@ -0,0 +1,65 @@
---
tags:
- Searx
- Security
- Docker
---
## Purpose
Deploys a SearX Meta Search Engine Server
## Docker Configuration
```yaml title="docker-compose.yml"
version: '3'
services:
searx:
image: searx/searx:latest
ports:
- 8080:8080
volumes:
- /srv/containers/searx/:/etc/searx
restart: always
labels:
- "traefik.enable=true"
- "traefik.http.routers.searx.rule=Host(`searx.bunny-lab.io`)"
- "traefik.http.routers.searx.entrypoints=websecure"
- "traefik.http.routers.searx.tls.certresolver=letsencrypt"
- "traefik.http.services.searx.loadbalancer.server.port=8080"
networks:
docker_network:
ipv4_address: 192.168.5.124
networks:
docker_network:
external: true
```
```yaml title=".env"
Not Applicable
```
## Traefik Reverse Proxy Configuration
If the container does not run on the same host as Traefik, you will need to manually add configuration to Traefik's dynamic config file, outlined below.
```yaml
http:
routers:
searx:
entryPoints:
- websecure
tls:
certResolver: letsencrypt
service: searx
rule: Host(`searx.bunny-lab.io`)
services:
searx:
loadBalancer:
servers:
- url: http://192.168.5.124:8080
passHostHeader: true
```
## Related Documentation
- [Docker Network Prerequisite](<../../Containers/Docker/Create the Docker Network.md>) — The configuration references the external `docker_network`; prepare it on the intended Docker host.
- [Related Applications Documentation](<../../../reference/Applications/index.md>) — Find the connected deployments, procedures, and references for this subject.
- [Traefik Deployment](<../../Networking and Access/Reverse Proxies/Traefik.md>) — Prepare the reverse proxy before applying this page's routing configuration.
+24
View File
@@ -0,0 +1,24 @@
---
tags:
- Applications
- Deployments
- Documentation
---
# Applications
## Purpose
Find deployments for applications. Follow the subject guide to choose the relevant environment and connect this material to the other document types.
## Includes
- Asset Management
- Communication
- Dashboards
- Email
- Files and Collaboration
- Gaming and Media
- Home Automation
- Monitoring
- Utilities
## Follow the Subject
[Applications](<../../reference/Applications/index.md>) explains the relationships and offers starting points for the documented tasks.