initial commit

This commit is contained in:
admin 2025-05-28 09:47:43 -06:00
commit ab81a74ed8
177 changed files with 25799 additions and 0 deletions

8
.gitignore vendored Normal file
View File

@ -0,0 +1,8 @@
/configs/code-server/.local/*
!/configs/code-server/.local/.gitkeep
/configs/code-server/.config/*
!/configs/code-server/.config/.gitkeep
.env
.env*

84
Dockerfile.code-server Normal file
View File

@ -0,0 +1,84 @@
FROM codercom/code-server:latest
USER root
# Install Python and dependencies
RUN apt-get update && apt-get install -y \
python3 \
python3-pip \
python3-venv \
python3-full \
pipx \
# Dependencies for CairoSVG and Pillow (PIL)
libcairo2-dev \
libfreetype6-dev \
libffi-dev \
libjpeg-dev \
libpng-dev \
libz-dev \
python3-dev \
pkg-config \
# Additional dependencies for advanced image processing
libwebp-dev \
libtiff5-dev \
libopenjp2-7-dev \
liblcms2-dev \
libxml2-dev \
libxslt1-dev \
# PDF generation dependencies
weasyprint \
fonts-roboto \
# Git for git-based plugins
git \
# For lxml
zlib1g-dev \
# Required for some plugins
build-essential \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*
# Switch to non-root user (coder)
USER coder
# Set up a virtual environment for mkdocs
RUN mkdir -p /home/coder/.venv
RUN python3 -m venv /home/coder/.venv/mkdocs
# Install mkdocs-material in the virtual environment with all extras
RUN /home/coder/.venv/mkdocs/bin/pip install "mkdocs-material[imaging,recommended,git]"
# Install additional useful MkDocs plugins
RUN /home/coder/.venv/mkdocs/bin/pip install \
mkdocs-minify-plugin \
mkdocs-git-revision-date-localized-plugin \
mkdocs-glightbox \
mkdocs-redirects \
mkdocs-awesome-pages-plugin \
mkdocs-blog-plugin \
mkdocs-rss-plugin \
mkdocs-meta-descriptions-plugin \
mkdocs-swagger-ui-tag \
mkdocs-macros-plugin \
mkdocs-material-extensions \
mkdocs-section-index \
mkdocs-table-reader-plugin \
mkdocs-pdf-export-plugin \
mkdocs-mermaid2-plugin \
pymdown-extensions \
pygments \
pillow \
cairosvg
# Add the virtual environment bin to PATH
ENV PATH="/home/coder/.venv/mkdocs/bin:${PATH}"
# Add shell configuration to activate the virtual environment in .bashrc
RUN echo 'export PATH="/home/coder/.venv/mkdocs/bin:$PATH"' >> ~/.bashrc
RUN echo 'export PATH="/home/coder/.local/bin:$PATH"' >> ~/.bashrc
# Create a convenience script to simplify running mkdocs commands
RUN mkdir -p /home/coder/.local/bin \
&& echo '#!/bin/bash\ncd /home/coder/mkdocs\nmkdocs "$@"' > /home/coder/.local/bin/run-mkdocs \
&& chmod +x /home/coder/.local/bin/run-mkdocs
WORKDIR /home/coder

53
README.md Normal file
View File

@ -0,0 +1,53 @@
# Changemaker Lite
Changemaker Lite is a streamlined documentation and development platform featuring essential self-hosted services for creating, managing, and automating content workflows.
## Features
- **Homepage**: Modern dashboard for accessing all services
- **Code Server**: VS Code in your browser for remote development
- **MkDocs Material**: Beautiful documentation with live preview
- **Static Site Server**: High-performance hosting for built sites
- **Listmonk**: Self-hosted newsletter and email campaign management
- **PostgreSQL**: Reliable database backend
- **n8n**: Workflow automation and service integration
- **NocoDB**: No-code database platform and smart spreadsheet interface
- **Silex**: Visual website editor for drag-and-drop web design
## Quick Start
```bash
# Clone the repository
git clone https://gitea.bnkops.com/admin/Changemaker.git
cd changemaker.lite
# Configure environment (creates .env file)
./config.sh
# Start all services
docker compose up -d
```
## Service Access
After starting, access services at:
- **Homepage Dashboard**: http://localhost:3010
- **Documentation (Dev)**: http://localhost:4000
- **Documentation (Built)**: http://localhost:4001
- **Code Server**: http://localhost:8888
- **Silex Editor**: http://localhost:6805
- **Listmonk**: http://localhost:9000
- **n8n**: http://localhost:5678
- **NocoDB**: http://localhost:8090
## Documentation
Complete documentation is available in the MkDocs site, including:
- Service configuration guides
- Integration examples
- Workflow automation tutorials
- Troubleshooting guides
Visit http://localhost:4000 after starting services to access the full documentation.

302
add-cname-records.sh Executable file
View File

@ -0,0 +1,302 @@
#!/bin/bash
echo "#############################################################"
echo "# "
echo "# DNS Setup for Changemaker.lite Services "
echo "# "
echo "# This script will ADD DNS records for your services. "
echo "# Existing DNS records will NOT be deleted. "
echo "# "
echo "#############################################################"
echo ""
echo "-------------------------------------------------------------"
echo "Cloudflare Credentials Required"
echo "Please ensure your .env file contains the following variables:"
echo " CF_API_TOKEN=your_cloudflare_api_token"
echo " CF_ZONE_ID=your_cloudflare_zone_id"
echo " CF_TUNNEL_ID=your_cloudflared_tunnel_id"
echo " CF_DOMAIN=yourdomain.com"
echo ""
echo "You can find these values in your Cloudflare dashboard:"
echo " - API Token: https://dash.cloudflare.com/profile/api-tokens (Create a token with Zone:DNS:Edit and Access:Apps:Edit permissions for your domain)"
echo " - Zone ID: On your domain's overview page"
echo " - Tunnel ID: In the Zero Trust dashboard under Access > Tunnels"
echo " - Domain: The domain you want to use for your services"
echo ""
echo "-------------------------------------------------------------"
echo ""
read -p "Type 'y' to continue or any other key to abort: " consent
if [[ "$consent" != "y" && "$consent" != "Y" ]]; then
echo "Aborted by user."
exit 1
fi
# Source environment variables from the .env file in the same directory
ENV_FILE="$(dirname "$0")/.env"
if [ -f "$ENV_FILE" ]; then
export $(grep -v '^#' "$ENV_FILE" | xargs)
else
echo "Error: .env file not found at $ENV_FILE"
exit 1
fi
# Check if required Cloudflare variables are set
if [ -z "$CF_API_TOKEN" ] || [ -z "$CF_ZONE_ID" ] || [ -z "$CF_TUNNEL_ID" ] || [ -z "$CF_DOMAIN" ]; then
echo "Error: One or more required Cloudflare environment variables (CF_API_TOKEN, CF_ZONE_ID, CF_TUNNEL_ID, CF_DOMAIN) are not set in $ENV_FILE."
exit 1
fi
# Check if jq is installed
if ! command -v jq &> /dev/null; then
echo "Error: jq is required but not installed. Please install jq to continue."
echo "On Debian/Ubuntu: sudo apt-get install jq"
echo "On RHEL/CentOS: sudo yum install jq"
exit 1
fi
# Array of subdomains that need DNS records
SUBDOMAINS=(
"homepage"
"excalidraw"
"listmonk"
"monica"
"flatnotes"
"code-server"
"ollama"
"open-webui"
"gitea"
"mini-qr"
"ferdium"
"answer"
"nocodb"
"n8n"
"convertx"
"rocket"
"live"
"vw"
)
# Function to check if DNS record already exists
record_exists() {
local subdomain=$1
local records=$(curl -s -X GET "https://api.cloudflare.com/client/v4/zones/$CF_ZONE_ID/dns_records?name=$subdomain.$CF_DOMAIN" \
-H "Authorization: Bearer $CF_API_TOKEN" \
-H "Content-Type: application/json")
local count=$(echo $records | jq -r '.result | length')
[ "$count" -gt 0 ]
}
# Add CNAME records for each subdomain (only if they don't exist)
echo "Adding DNS records for services..."
for subdomain in "${SUBDOMAINS[@]}"; do
if record_exists "$subdomain"; then
echo "DNS record for $subdomain.$CF_DOMAIN already exists, skipping..."
else
echo "Adding CNAME record for $subdomain.$CF_DOMAIN..."
response=$(curl -s -X POST "https://api.cloudflare.com/client/v4/zones/$CF_ZONE_ID/dns_records" \
-H "Authorization: Bearer $CF_API_TOKEN" \
-H "Content-Type: application/json" \
--data "{
\"type\": \"CNAME\",
\"name\": \"$subdomain\",
\"content\": \"$CF_TUNNEL_ID.cfargotunnel.com\",
\"ttl\": 1,
\"proxied\": true
}")
success=$(echo $response | jq -r '.success')
if [ "$success" == "true" ]; then
echo "✓ Successfully added CNAME record for $subdomain.$CF_DOMAIN"
else
echo "✗ Failed to add CNAME record for $subdomain.$CF_DOMAIN"
echo "Error: $(echo $response | jq -r '.errors[0].message')"
fi
fi
done
# Add root domain record if it doesn't exist
if record_exists "@"; then
echo "Root domain DNS record already exists, skipping..."
else
echo "Adding root domain CNAME record..."
response=$(curl -s -X POST "https://api.cloudflare.com/client/v4/zones/$CF_ZONE_ID/dns_records" \
-H "Authorization: Bearer $CF_API_TOKEN" \
-H "Content-Type: application/json" \
--data "{
\"type\": \"CNAME\",
\"name\": \"@\",
\"content\": \"$CF_TUNNEL_ID.cfargotunnel.com\",
\"ttl\": 1,
\"proxied\": true
}")
success=$(echo $response | jq -r '.success')
if [ "$success" == "true" ]; then
echo "✓ Successfully added root domain CNAME record"
else
echo "✗ Failed to add root domain CNAME record"
echo "Error: $(echo $response | jq -r '.errors[0].message')"
fi
fi
echo ""
echo "DNS records setup complete!"
echo ""
# Prompt for admin email for secured services
echo "-------------------------------------------------------------"
echo "Setting up Cloudflare Access Protection"
echo "-------------------------------------------------------------"
echo ""
echo "The following services will be protected with authentication:"
echo " - homepage.$CF_DOMAIN"
echo " - code-server.$CF_DOMAIN"
echo " - live.$CF_DOMAIN"
echo ""
echo "Please enter the admin email address that should have access:"
read ADMIN_EMAIL
# Validate email format
if [[ ! "$ADMIN_EMAIL" =~ ^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$ ]]; then
echo "Error: Invalid email format. Please provide a valid email address."
exit 1
fi
# Services that require authentication
PROTECTED_SERVICES=("homepage" "code-server" "live")
# Services that should have bypass policies (public access)
BYPASS_SERVICES=("excalidraw" "listmonk" "monica" "flatnotes" "ollama" "open-webui" "gitea" "mini-qr" "ferdium" "answer" "nocodb" "n8n" "convertx" "rocket" "vw")
# Function to create access application with email authentication
create_protected_app() {
local service=$1
echo "Setting up authentication for $service.$CF_DOMAIN..."
app_response=$(curl -s -X POST "https://api.cloudflare.com/client/v4/zones/$CF_ZONE_ID/access/apps" \
-H "Authorization: Bearer $CF_API_TOKEN" \
-H "Content-Type: application/json" \
--data "{
\"name\": \"$service $CF_DOMAIN\",
\"domain\": \"$service.$CF_DOMAIN\",
\"type\": \"self_hosted\",
\"session_duration\": \"24h\",
\"app_launcher_visible\": true,
\"skip_interstitial\": true
}")
app_id=$(echo $app_response | jq -r '.result.id')
if [ -z "$app_id" ] || [ "$app_id" == "null" ]; then
echo "✗ Error creating access application for $service"
return 1
fi
echo "✓ Created access application for $service (ID: $app_id)"
# Create authentication policy
policy_response=$(curl -s -X POST "https://api.cloudflare.com/client/v4/zones/$CF_ZONE_ID/access/apps/$app_id/policies" \
-H "Authorization: Bearer $CF_API_TOKEN" \
-H "Content-Type: application/json" \
--data "{
\"name\": \"Admin Access\",
\"decision\": \"allow\",
\"include\": [{
\"email\": {
\"email\": \"$ADMIN_EMAIL\"
}
}],
\"require\": [],
\"exclude\": []
}")
policy_success=$(echo $policy_response | jq -r '.success')
if [ "$policy_success" == "true" ]; then
echo "✓ Created authentication policy for $service"
else
echo "✗ Failed to create authentication policy for $service"
fi
}
# Function to create bypass application (public access)
create_bypass_app() {
local service=$1
echo "Setting up public access for $service.$CF_DOMAIN..."
app_response=$(curl -s -X POST "https://api.cloudflare.com/client/v4/zones/$CF_ZONE_ID/access/apps" \
-H "Authorization: Bearer $CF_API_TOKEN" \
-H "Content-Type: application/json" \
--data "{
\"name\": \"$service $CF_DOMAIN\",
\"domain\": \"$service.$CF_DOMAIN\",
\"type\": \"self_hosted\",
\"session_duration\": \"24h\",
\"app_launcher_visible\": false,
\"skip_interstitial\": true
}")
app_id=$(echo $app_response | jq -r '.result.id')
if [ -z "$app_id" ] || [ "$app_id" == "null" ]; then
echo "✗ Error creating access application for $service"
return 1
fi
echo "✓ Created access application for $service (ID: $app_id)"
# Create bypass policy
policy_response=$(curl -s -X POST "https://api.cloudflare.com/client/v4/zones/$CF_ZONE_ID/access/apps/$app_id/policies" \
-H "Authorization: Bearer $CF_API_TOKEN" \
-H "Content-Type: application/json" \
--data "{
\"name\": \"Public Access\",
\"decision\": \"bypass\",
\"include\": [{
\"everyone\": {}
}],
\"require\": [],
\"exclude\": []
}")
policy_success=$(echo $policy_response | jq -r '.success')
if [ "$policy_success" == "true" ]; then
echo "✓ Created public access policy for $service"
else
echo "✗ Failed to create public access policy for $service"
fi
}
echo "Creating Cloudflare Access applications..."
echo ""
# Create protected applications
for service in "${PROTECTED_SERVICES[@]}"; do
create_protected_app "$service"
echo ""
done
# Create bypass applications for public services
for service in "${BYPASS_SERVICES[@]}"; do
create_bypass_app "$service"
echo ""
done
echo "-------------------------------------------------------------"
echo "Setup Complete!"
echo "-------------------------------------------------------------"
echo ""
echo "Protected services (require authentication with $ADMIN_EMAIL):"
for service in "${PROTECTED_SERVICES[@]}"; do
echo " - https://$service.$CF_DOMAIN"
done
echo ""
echo "Public services (no authentication required):"
for service in "${BYPASS_SERVICES[@]}"; do
echo " - https://$service.$CF_DOMAIN"
done
echo ""
echo "All services should be accessible through your Cloudflare tunnel."

562
config.sh Executable file
View File

@ -0,0 +1,562 @@
#!/bin/bash
cat << "EOF"
██████╗██╗ ██╗ █████╗ ███╗ ██╗ ██████╗ ███████╗
██╔════╝██║ ██║██╔══██╗████╗ ██║██╔════╝ ██╔════╝
██║ ███████║███████║██╔██╗ ██║██║ ███╗█████╗
██║ ██╔══██║██╔══██║██║╚██╗██║██║ ██║██╔══╝
╚██████╗██║ ██║██║ ██║██║ ╚████║╚██████╔╝███████╗
╚═════╝╚═╝ ╚═╝╚═╝ ╚═╝╚═╝ ╚═══╝ ╚═════╝ ╚══════╝
███╗ ███╗ █████╗ ██╗ ██╗███████╗██████╗
████╗ ████║██╔══██╗██║ ██╔╝██╔════╝██╔══██╗
██╔████╔██║███████║█████╔╝ █████╗ ██████╔╝
██║╚██╔╝██║██╔══██║██╔═██╗ ██╔══╝ ██╔══██╗
██║ ╚═╝ ██║██║ ██║██║ ██╗███████╗██║ ██║
╚═╝ ╚═╝╚═╝ ╚═╝╚═╝ ╚═╝╚══════╝╚═╝ ╚═╝
Configuration Wizard
EOF
# Get the absolute path of the script directory
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
ENV_FILE="$SCRIPT_DIR/.env"
MKDOCS_YML="$SCRIPT_DIR/mkdocs/docs/mkdocs.yml"
echo "Looking for .env file at: $ENV_FILE"
# Function to generate a random secure password
generate_password() {
local length=${1:-16}
openssl rand -base64 48 | tr -dc 'a-zA-Z0-9!@#$%^&*()-_=+' | head -c "$length"
}
# Function to safely update environment variables in .env file
update_env_var() {
local key=$1
local value=$2
local escaped_value=$(echo "$value" | sed 's/[\/&]/\\&/g')
if grep -q "^$key=" "$ENV_FILE"; then
sed -i "s/^$key=.*/$key=$escaped_value/" "$ENV_FILE"
echo "Updated $key in .env file"
else
echo "$key=$escaped_value" >> "$ENV_FILE"
echo "Added $key to .env file"
fi
}
# Function to create a timestamped backup of the .env file
backup_env_file() {
if [ -f "$ENV_FILE" ]; then
local timestamp=$(date +"%Y%m%d_%H%M%S")
local backup_file="$ENV_FILE.backup_$timestamp"
echo "Creating backup of current .env file to: $backup_file"
if cp "$ENV_FILE" "$backup_file"; then
echo "Backup created successfully!"
return 0
else
echo "Failed to create backup file. Proceeding with caution..."
return 1
fi
fi
}
# Function to initialize the .env file with default values
initialize_env_file() {
echo "Initializing new .env file with default values..."
cat > "$ENV_FILE" << EOL
# Never share this file publicly. It contains sensitive information.
# This file is used to configure various applications and services.
# Generated by Changemaker Config Wizard on $(date)
# User and Group Configuration
USER_NAME=coder
USER_ID=1000
GROUP_ID=1000
# Port Configuration
CODE_SERVER_PORT=8888
LISTMONK_PORT=9000
LISTMONK_DB_PORT=5432
MKDOCS_PORT=4000
MKDOCS_SITE_SERVER_PORT=4001
N8N_PORT=5678
NOCODB_PORT=8090
HOMEPAGE_PORT=3010
SILEX_PORT=6805
# Domain Configuration
BASE_DOMAIN=https://changeme.org
DOMAIN=changeme.org
LISTMONK_HOSTNAME=listmonk.changeme.org
N8N_HOST=n8n.changeme.org
SILEX_HOST=silex.changeme.org
# Cloudflare Configuration
CF_API_TOKEN=your_cloudflare_api_token
CF_ZONE_ID=your_cloudflare_zone_id
CF_TUNNEL_ID=your_cloudflared_tunnel_id
CF_DOMAIN=changeme.org
# Database Configuration (PostgreSQL for Listmonk)
POSTGRES_USER=listmonk
POSTGRES_PASSWORD=changeMe
POSTGRES_DB=listmonk
# Listmonk Admin Configuration
LISTMONK_ADMIN_USER=admin
LISTMONK_ADMIN_PASSWORD=changeMe
# N8N Configuration
N8N_USER_EMAIL=admin@example.com
N8N_USER_PASSWORD=changeMe
N8N_ENCRYPTION_KEY=changeMe
GENERIC_TIMEZONE=UTC
# Nocodb Configuration
NOCODB_PORT=8090
NOCODB_JWT_SECRET=changeMe
NOCODB_DB_NAME=nocodb
NOCODB_DB_USER=noco
NOCODB_DB_PASSWORD=changeMe
# Listmonk SMTP Configuration
LISTMONK_SMTP_HOST=smtp.example.com
LISTMONK_SMTP_PORT=587
LISTMONK_SMTP_AUTH_PROTOCOL=plain
LISTMONK_SMTP_USERNAME=your-smtp-username
LISTMONK_SMTP_PASSWORD=your-smtp-password
LISTMONK_SMTP_HELLO_HOSTNAME=listmonk.changeme.org
LISTMONK_SMTP_TLS_ENABLED=true
LISTMONK_SMTP_TLS_SKIP_VERIFY=false
LISTMONK_SMTP_MAX_CONNS=10
LISTMONK_SMTP_MAX_MSG_RETRIES=2
LISTMONK_SMTP_IDLE_TIMEOUT=10s
LISTMONK_SMTP_WAIT_TIMEOUT=5s
LISTMONK_SMTP_EMAIL_HEADERS=List-Unsubscribe-Post=List-Unsubscribe=One-Click
EOL
echo "New .env file created with default values."
}
# Function to update the site_url in mkdocs.yml
update_mkdocs_yml() {
local new_domain=$1
if [ ! -f "$MKDOCS_YML" ]; then
echo "Warning: mkdocs.yml not found at $MKDOCS_YML"
return 1
fi
echo "Updating site_url in mkdocs.yml..."
# Create a backup of the mkdocs.yml file
local timestamp=$(date +"%Y%m%d_%H%M%S")
local backup_file="${MKDOCS_YML}.backup_${timestamp}"
cp "$MKDOCS_YML" "$backup_file"
echo "Created backup of mkdocs.yml at $backup_file"
# Update the site_url value
sed -i "s|^site_url:.*|site_url: https://$new_domain|" "$MKDOCS_YML"
if grep -q "site_url: https://$new_domain" "$MKDOCS_YML"; then
echo "Updated site_url in mkdocs.yml to: https://$new_domain"
return 0
else
echo "Warning: Failed to update site_url in mkdocs.yml"
return 1
fi
}
# Function to check if a port is in use
check_port() {
local port=$1
if command -v ss >/dev/null 2>&1; then
ss -tuln | grep -q ":$port "
elif command -v netstat >/dev/null 2>&1; then
netstat -tuln | grep -q ":$port "
else
# Fallback to lsof if available
if command -v lsof >/dev/null 2>&1; then
lsof -i ":$port" >/dev/null 2>&1
else
echo "Warning: Cannot check port availability. Please ensure ports are free manually."
return 1
fi
fi
}
# Function to check all service ports for conflicts
check_port_conflicts() {
echo "Checking for port conflicts..."
local ports_to_check=(
"${CODE_SERVER_PORT:-8888}:Code Server"
"${LISTMONK_PORT:-9000}:Listmonk"
"${LISTMONK_DB_PORT:-5432}:Listmonk Database"
"${MKDOCS_PORT:-4000}:MkDocs"
"${MKDOCS_SITE_SERVER_PORT:-4001}:MkDocs Site Server"
"${N8N_PORT:-5678}:N8N"
"${NOCODB_PORT:-8090}:NocoDB"
"${HOMEPAGE_PORT:-3010}:Homepage"
"${SILEX_PORT:-6805}:Silex"
)
local conflicts_found=false
for port_info in "${ports_to_check[@]}"; do
local port=$(echo "$port_info" | cut -d: -f1)
local service=$(echo "$port_info" | cut -d: -f2)
if check_port "$port"; then
echo "⚠️ Port conflict detected: $port is already in use (assigned to $service)"
conflicts_found=true
else
echo "✅ Port $port is available for $service"
fi
done
if [ "$conflicts_found" = true ]; then
echo ""
echo "Port conflicts detected! Please choose alternative ports or stop conflicting services."
read -p "Do you want to configure alternative ports? [Y/n]: " configure_ports
if [[ "$configure_ports" =~ ^[Nn]$ ]]; then
echo "Configuration cancelled. Please resolve port conflicts and try again."
exit 1
else
configure_alternative_ports
fi
else
echo "✅ All ports are available!"
fi
}
# Function to configure alternative ports
configure_alternative_ports() {
echo ""
echo "---- Port Configuration ----"
# Code Server
if check_port "${CODE_SERVER_PORT:-8888}"; then
read -p "Enter alternative port for Code Server [current: ${CODE_SERVER_PORT:-8888}]: " new_code_port
if [ ! -z "$new_code_port" ]; then
update_env_var "CODE_SERVER_PORT" "$new_code_port"
fi
fi
# Listmonk
if check_port "${LISTMONK_PORT:-9000}"; then
read -p "Enter alternative port for Listmonk [current: ${LISTMONK_PORT:-9000}]: " new_listmonk_port
if [ ! -z "$new_listmonk_port" ]; then
update_env_var "LISTMONK_PORT" "$new_listmonk_port"
fi
fi
# Listmonk DB
if check_port "${LISTMONK_DB_PORT:-5432}"; then
read -p "Enter alternative port for Listmonk Database [current: ${LISTMONK_DB_PORT:-5432}]: " new_db_port
if [ ! -z "$new_db_port" ]; then
update_env_var "LISTMONK_DB_PORT" "$new_db_port"
fi
fi
# MkDocs
if check_port "${MKDOCS_PORT:-4000}"; then
read -p "Enter alternative port for MkDocs [current: ${MKDOCS_PORT:-4000}]: " new_mkdocs_port
if [ ! -z "$new_mkdocs_port" ]; then
update_env_var "MKDOCS_PORT" "$new_mkdocs_port"
fi
fi
# MkDocs Site Server
if check_port "${MKDOCS_SITE_SERVER_PORT:-4001}"; then
read -p "Enter alternative port for MkDocs Site Server [current: ${MKDOCS_SITE_SERVER_PORT:-4001}]: " new_site_port
if [ ! -z "$new_site_port" ]; then
update_env_var "MKDOCS_SITE_SERVER_PORT" "$new_site_port"
fi
fi
# N8N
if check_port "${N8N_PORT:-5678}"; then
read -p "Enter alternative port for N8N [current: ${N8N_PORT:-5678}]: " new_n8n_port
if [ ! -z "$new_n8n_port" ]; then
update_env_var "N8N_PORT" "$new_n8n_port"
fi
fi
# NocoDB
if check_port "${NOCODB_PORT:-8090}"; then
read -p "Enter alternative port for NocoDB [current: ${NOCODB_PORT:-8090}]: " new_nocodb_port
if [ ! -z "$new_nocodb_port" ]; then
update_env_var "NOCODB_PORT" "$new_nocodb_port"
fi
fi
# Homepage
if check_port "${HOMEPAGE_PORT:-3010}"; then
read -p "Enter alternative port for Homepage [current: ${HOMEPAGE_PORT:-3010}]: " new_homepage_port
if [ ! -z "$new_homepage_port" ]; then
update_env_var "HOMEPAGE_PORT" "$new_homepage_port"
fi
fi
# Silex
if check_port "${SILEX_PORT:-6805}"; then
read -p "Enter alternative port for Silex [current: ${SILEX_PORT:-6805}]: " new_silex_port
if [ ! -z "$new_silex_port" ]; then
update_env_var "SILEX_PORT" "$new_silex_port"
fi
fi
echo "Port configuration completed."
}
# Initialize a new .env file if it doesn't exist
if [ ! -f "$ENV_FILE" ]; then
echo "No .env file found. Creating a new one from scratch."
touch "$ENV_FILE"
initialize_env_file
else
echo "Found existing .env file. Will update values."
backup_env_file
fi
echo -e "\n\nWelcome to Changemaker Config!\n"
echo "This script will help you configure your .env file for Changemaker."
echo "Please provide the following information:"
# Domain configuration
read -p "Enter your domain name (without protocol, e.g., example.com): " domain_name
if [ -z "$domain_name" ]; then
echo "Domain name cannot be empty. Using default: changeme.org"
domain_name="changeme.org"
fi
echo -e "\nUpdating domain settings in .env file..."
# Update main domain settings
update_env_var "DOMAIN" "$domain_name"
update_env_var "BASE_DOMAIN" "https://$domain_name"
update_env_var "LISTMONK_HOSTNAME" "listmonk.$domain_name"
update_env_var "N8N_HOST" "n8n.$domain_name"
update_env_var "SILEX_HOST" "silex.$domain_name"
update_env_var "CF_DOMAIN" "$domain_name"
echo "Domain settings updated successfully!"
# Cloudflare Configuration
echo -e "\n---- Cloudflare Configuration ----"
echo "To use the DNS setup script, you'll need Cloudflare credentials."
echo "You can find these values in your Cloudflare dashboard:"
echo " - API Token: https://dash.cloudflare.com/profile/api-tokens"
echo " (Create a token with Zone:DNS:Edit and Access:Apps:Edit permissions)"
echo " - Zone ID: On your domain's overview page"
echo " - Tunnel ID: In the Zero Trust dashboard under Access > Tunnels"
echo ""
read -p "Do you want to configure Cloudflare settings now? [Y/n]: " configure_cf
if [[ ! "$configure_cf" =~ ^[Nn]$ ]]; then
echo ""
echo "Please enter your Cloudflare credentials:"
# CF API Token
read -p "Enter your Cloudflare API Token: " cf_api_token
if [ ! -z "$cf_api_token" ]; then
# Basic validation for API token format
if [[ "$cf_api_token" =~ ^[A-Za-z0-9_-]{40}$ ]]; then
update_env_var "CF_API_TOKEN" "$cf_api_token"
echo "✅ Cloudflare API Token updated"
else
echo "⚠️ Warning: API Token format seems incorrect (should be 40 characters)"
update_env_var "CF_API_TOKEN" "$cf_api_token"
fi
else
echo "⚠️ Cloudflare API Token left unchanged"
fi
# CF Zone ID
read -p "Enter your Cloudflare Zone ID: " cf_zone_id
if [ ! -z "$cf_zone_id" ]; then
# Basic validation for Zone ID format
if [[ "$cf_zone_id" =~ ^[a-f0-9]{32}$ ]]; then
update_env_var "CF_ZONE_ID" "$cf_zone_id"
echo "✅ Cloudflare Zone ID updated"
else
echo "⚠️ Warning: Zone ID format seems incorrect (should be 32 hex characters)"
update_env_var "CF_ZONE_ID" "$cf_zone_id"
fi
else
echo "⚠️ Cloudflare Zone ID left unchanged"
fi
# CF Tunnel ID
read -p "Enter your Cloudflare Tunnel ID: " cf_tunnel_id
if [ ! -z "$cf_tunnel_id" ]; then
# Basic validation for Tunnel ID format (UUID)
if [[ "$cf_tunnel_id" =~ ^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$ ]]; then
update_env_var "CF_TUNNEL_ID" "$cf_tunnel_id"
echo "✅ Cloudflare Tunnel ID updated"
else
echo "⚠️ Warning: Tunnel ID format seems incorrect (should be UUID format)"
update_env_var "CF_TUNNEL_ID" "$cf_tunnel_id"
fi
else
echo "⚠️ Cloudflare Tunnel ID left unchanged"
fi
echo ""
echo "Cloudflare configuration completed!"
echo "You can now run './add-cname-records.sh' to set up DNS records."
else
echo "Skipping Cloudflare configuration. You can run this script again later to configure it."
fi
# Update the site_url in mkdocs.yml
echo -e "\nUpdating site_url in mkdocs.yml..."
update_mkdocs_yml "$domain_name"
# Check for port conflicts
echo -e "\n---- Checking Port Availability ----"
check_port_conflicts
# Listmonk Admin Credentials configuration
echo -e "\n---- Listmonk Admin Credentials ----"
read -p "Enter Listmonk admin username [default: admin]: " listmonk_user
read -sp "Enter Listmonk admin password [default: strongpassword]: " listmonk_password
echo # Add new line after password input
if [ -z "$listmonk_user" ]; then
listmonk_user="admin"
fi
if [ -z "$listmonk_password" ]; then
listmonk_password="strongpassword"
fi
update_env_var "LISTMONK_ADMIN_USER" "$listmonk_user"
update_env_var "LISTMONK_ADMIN_PASSWORD" "$listmonk_password"
echo "Listmonk admin credentials updated."
# N8N User Credentials configuration
echo -e "\n---- N8N Admin Credentials ----"
read -p "Enter N8N admin email [default: admin@example.com]: " n8n_email
read -sp "Enter N8N admin password [default: changeMe]: " n8n_password
echo # Add new line after password input
if [ -z "$n8n_email" ]; then
n8n_email="admin@example.com"
fi
if [ -z "$n8n_password" ]; then
n8n_password="changeMe"
fi
update_env_var "N8N_USER_EMAIL" "$n8n_email"
update_env_var "N8N_USER_PASSWORD" "$n8n_password"
echo "N8N admin credentials updated."
# SMTP Configuration
echo -e "\n---- SMTP Configuration ----"
echo "Configure SMTP settings for sending emails through Listmonk."
read -p "Do you want to configure SMTP settings now? [Y/n]: " configure_smtp
if [[ ! "$configure_smtp" =~ ^[Nn]$ ]]; then
echo ""
echo "Please enter your SMTP server details:"
read -p "SMTP Host (e.g., smtp.gmail.com, smtp.sendgrid.net): " smtp_host
read -p "SMTP Port [default: 587]: " smtp_port
read -p "SMTP Username/Email: " smtp_username
read -sp "SMTP Password: " smtp_password
echo
read -p "Hello Hostname [default: ${LISTMONK_HOSTNAME:-listmonk.changeme.org}]: " smtp_hello
read -p "Enable TLS? [Y/n]: " smtp_tls
# Set defaults
if [ -z "$smtp_port" ]; then
smtp_port="587"
fi
if [ -z "$smtp_hello" ]; then
smtp_hello="${LISTMONK_HOSTNAME:-listmonk.changeme.org}"
fi
if [[ "$smtp_tls" =~ ^[Nn]$ ]]; then
smtp_tls_enabled="false"
else
smtp_tls_enabled="true"
fi
# Update SMTP settings in .env
if [ ! -z "$smtp_host" ]; then
update_env_var "LISTMONK_SMTP_HOST" "$smtp_host"
fi
update_env_var "LISTMONK_SMTP_PORT" "$smtp_port"
if [ ! -z "$smtp_username" ]; then
update_env_var "LISTMONK_SMTP_USERNAME" "$smtp_username"
fi
if [ ! -z "$smtp_password" ]; then
update_env_var "LISTMONK_SMTP_PASSWORD" "$smtp_password"
fi
update_env_var "LISTMONK_SMTP_HELLO_HOSTNAME" "$smtp_hello"
update_env_var "LISTMONK_SMTP_TLS_ENABLED" "$smtp_tls_enabled"
update_env_var "LISTMONK_SMTP_AUTH_PROTOCOL" "plain"
update_env_var "LISTMONK_SMTP_TLS_SKIP_VERIFY" "false"
update_env_var "LISTMONK_SMTP_MAX_CONNS" "10"
update_env_var "LISTMONK_SMTP_MAX_MSG_RETRIES" "2"
update_env_var "LISTMONK_SMTP_IDLE_TIMEOUT" "10s"
update_env_var "LISTMONK_SMTP_WAIT_TIMEOUT" "5s"
echo "✅ SMTP configuration completed!"
else
echo "Skipping SMTP configuration. You can configure this later in the Listmonk admin interface."
fi
# Generate secure passwords for database and encryption
echo -e "\n---- Generating Secure Passwords ----"
echo "Generating secure passwords for database and encryption keys..."
# Generate and update database password
postgres_password=$(generate_password 20)
update_env_var "POSTGRES_PASSWORD" "$postgres_password"
# Generate and update N8N encryption key
n8n_encryption_key=$(generate_password 32)
update_env_var "N8N_ENCRYPTION_KEY" "$n8n_encryption_key"
# Generate and update NocoDB passwords
nocodb_jwt_secret=$(generate_password 32)
update_env_var "NOCODB_JWT_SECRET" "$nocodb_jwt_secret"
nocodb_db_password=$(generate_password 20)
update_env_var "NOCODB_DB_PASSWORD" "$nocodb_db_password"
echo "Secure passwords generated and updated."
echo -e "\n✅ Configuration completed successfully!"
echo "Your .env file has been configured with:"
echo "- Domain: $domain_name"
echo "- Listmonk Admin: $listmonk_user"
echo "- N8N Admin Email: $n8n_email"
echo "- Secure random passwords for database, encryption, and NocoDB"
if [[ ! "$configure_cf" =~ ^[Nn]$ ]]; then
echo "- Cloudflare credentials for DNS management"
fi
echo -e "\nYour .env file is located at: $ENV_FILE"
echo "A backup of your original .env file was created before modifications."
echo -e "\nNext steps:"
echo "1. Run 'docker-compose up -d' to start your services"
if [[ ! "$configure_cf" =~ ^[Nn]$ ]]; then
echo "2. Run './add-cname-records.sh' to set up DNS records and access policies"
fi

View File

View File

50
configs/homepage/bookmarks.yaml Executable file
View File

@ -0,0 +1,50 @@
---
# For configuration options and examples, please see:
# https://gethomepage.dev/configs/bookmarks
- Documentation:
- Code Server:
- abbr: CS
href: https://github.com/coder/code-server
- MkDocs Material:
- abbr: MD
href: https://squidfunk.github.io/mkdocs-material/
- Homepage:
- abbr: HP
href: https://gethomepage.dev/
- Silex:
- abbr: SX
href: https://www.silex.me/
- Services:
- Listmonk:
- abbr: LM
href: https://listmonk.app/docs/
- NocoDB:
- abbr: NC
href: https://docs.nocodb.com/
- n8n:
- abbr: N8
href: https://docs.n8n.io/
- PostgreSQL:
- abbr: PG
href: https://www.postgresql.org/docs/
- Resources:
- Docker:
- abbr: DC
href: https://docs.docker.com/
- Docker Compose:
- abbr: DCC
href: https://docs.docker.com/compose/
- Nginx:
- abbr: NG
href: https://nginx.org/en/docs/
- Development:
- GitHub:
- abbr: GH
href: https://github.com/
- Stack Overflow:
- abbr: SO
href: https://stackoverflow.com/

0
configs/homepage/custom.css Executable file
View File

0
configs/homepage/custom.js Executable file
View File

6
configs/homepage/docker.yaml Executable file
View File

@ -0,0 +1,6 @@
---
# For configuration options and examples, please see:
# https://gethomepage.dev/configs/docker/
my-docker:
socket: /var/run/docker.sock

View File

@ -0,0 +1,2 @@
---
# sample kubernetes config

View File

@ -0,0 +1,192 @@
[2025-05-28T14:48:05.173Z] error: <service-helpers> Error getting services from Docker server 'my-docker': [Error: connect EACCES /var/run/docker.sock] {
errno: -13,
code: 'EACCES',
syscall: 'connect',
address: '/var/run/docker.sock'
}
[2025-05-28T14:48:05.221Z] error: <service-helpers> Error getting services from Docker server 'my-docker': [Error: connect EACCES /var/run/docker.sock] {
errno: -13,
code: 'EACCES',
syscall: 'connect',
address: '/var/run/docker.sock'
}
[2025-05-28T14:48:05.445Z] error: <service-helpers> Error getting services from Docker server 'my-docker': [Error: connect EACCES /var/run/docker.sock] {
errno: -13,
code: 'EACCES',
syscall: 'connect',
address: '/var/run/docker.sock'
}
[2025-05-28T14:48:05.568Z] error: <dockerStatusService> Error: connect EACCES /var/run/docker.sock
at PipeConnectWrap.afterConnect [as oncomplete] (node:net:1636:16)
at PipeConnectWrap.callbackTrampoline (node:internal/async_hooks:130:17)
[2025-05-28T14:48:05.585Z] error: <dockerStatsService> Error: connect EACCES /var/run/docker.sock
at PipeConnectWrap.afterConnect [as oncomplete] (node:net:1636:16)
at PipeConnectWrap.callbackTrampoline (node:internal/async_hooks:130:17)
[2025-05-28T14:48:05.585Z] error: <dockerStatusService> Error: connect EACCES /var/run/docker.sock
at PipeConnectWrap.afterConnect [as oncomplete] (node:net:1636:16)
at PipeConnectWrap.callbackTrampoline (node:internal/async_hooks:130:17)
[2025-05-28T14:48:05.586Z] error: <dockerStatsService> Error: connect EACCES /var/run/docker.sock
at PipeConnectWrap.afterConnect [as oncomplete] (node:net:1636:16)
at PipeConnectWrap.callbackTrampoline (node:internal/async_hooks:130:17)
[2025-05-28T14:48:05.586Z] error: <dockerStatusService> Error: connect EACCES /var/run/docker.sock
at PipeConnectWrap.afterConnect [as oncomplete] (node:net:1636:16)
at PipeConnectWrap.callbackTrampoline (node:internal/async_hooks:130:17)
[2025-05-28T14:48:05.587Z] error: <dockerStatsService> Error: connect EACCES /var/run/docker.sock
at PipeConnectWrap.afterConnect [as oncomplete] (node:net:1636:16)
at PipeConnectWrap.callbackTrampoline (node:internal/async_hooks:130:17)
[2025-05-28T14:48:05.601Z] error: <dockerStatsService> Error: connect EACCES /var/run/docker.sock
at PipeConnectWrap.afterConnect [as oncomplete] (node:net:1636:16)
at PipeConnectWrap.callbackTrampoline (node:internal/async_hooks:130:17)
[2025-05-28T14:48:05.601Z] error: <dockerStatusService> Error: connect EACCES /var/run/docker.sock
at PipeConnectWrap.afterConnect [as oncomplete] (node:net:1636:16)
at PipeConnectWrap.callbackTrampoline (node:internal/async_hooks:130:17)
[2025-05-28T14:48:05.602Z] error: <dockerStatsService> Error: connect EACCES /var/run/docker.sock
at PipeConnectWrap.afterConnect [as oncomplete] (node:net:1636:16)
at PipeConnectWrap.callbackTrampoline (node:internal/async_hooks:130:17)
[2025-05-28T14:48:05.602Z] error: <dockerStatusService> Error: connect EACCES /var/run/docker.sock
at PipeConnectWrap.afterConnect [as oncomplete] (node:net:1636:16)
at PipeConnectWrap.callbackTrampoline (node:internal/async_hooks:130:17)
[2025-05-28T14:48:05.602Z] error: <dockerStatsService> Error: connect EACCES /var/run/docker.sock
at PipeConnectWrap.afterConnect [as oncomplete] (node:net:1636:16)
at PipeConnectWrap.callbackTrampoline (node:internal/async_hooks:130:17)
[2025-05-28T14:48:05.603Z] error: <dockerStatusService> Error: connect EACCES /var/run/docker.sock
at PipeConnectWrap.afterConnect [as oncomplete] (node:net:1636:16)
at PipeConnectWrap.callbackTrampoline (node:internal/async_hooks:130:17)
[2025-05-28T14:48:05.622Z] error: <dockerStatusService> Error: connect EACCES /var/run/docker.sock
at PipeConnectWrap.afterConnect [as oncomplete] (node:net:1636:16)
at PipeConnectWrap.callbackTrampoline (node:internal/async_hooks:130:17)
[2025-05-28T14:48:05.622Z] error: <dockerStatsService> Error: connect EACCES /var/run/docker.sock
at PipeConnectWrap.afterConnect [as oncomplete] (node:net:1636:16)
at PipeConnectWrap.callbackTrampoline (node:internal/async_hooks:130:17)
[2025-05-28T14:48:05.623Z] error: <dockerStatusService> Error: connect EACCES /var/run/docker.sock
at PipeConnectWrap.afterConnect [as oncomplete] (node:net:1636:16)
at PipeConnectWrap.callbackTrampoline (node:internal/async_hooks:130:17)
[2025-05-28T14:48:05.623Z] error: <dockerStatsService> Error: connect EACCES /var/run/docker.sock
at PipeConnectWrap.afterConnect [as oncomplete] (node:net:1636:16)
at PipeConnectWrap.callbackTrampoline (node:internal/async_hooks:130:17)
[2025-05-28T14:48:05.623Z] error: <dockerStatusService> Error: connect EACCES /var/run/docker.sock
at PipeConnectWrap.afterConnect [as oncomplete] (node:net:1636:16)
at PipeConnectWrap.callbackTrampoline (node:internal/async_hooks:130:17)
[2025-05-28T14:48:05.624Z] error: <dockerStatsService> Error: connect EACCES /var/run/docker.sock
at PipeConnectWrap.afterConnect [as oncomplete] (node:net:1636:16)
at PipeConnectWrap.callbackTrampoline (node:internal/async_hooks:130:17)
[2025-05-28T14:56:53.099Z] error: <dockerStatusService> Error: connect EACCES /var/run/docker.sock
at PipeConnectWrap.afterConnect [as oncomplete] (node:net:1636:16)
at PipeConnectWrap.callbackTrampoline (node:internal/async_hooks:130:17)
[2025-05-28T14:56:53.111Z] error: <dockerStatsService> Error: connect EACCES /var/run/docker.sock
at PipeConnectWrap.afterConnect [as oncomplete] (node:net:1636:16)
at PipeConnectWrap.callbackTrampoline (node:internal/async_hooks:130:17)
[2025-05-28T14:56:53.116Z] error: <dockerStatusService> Error: connect EACCES /var/run/docker.sock
at PipeConnectWrap.afterConnect [as oncomplete] (node:net:1636:16)
at PipeConnectWrap.callbackTrampoline (node:internal/async_hooks:130:17)
[2025-05-28T14:56:53.128Z] error: <dockerStatusService> Error: connect EACCES /var/run/docker.sock
at PipeConnectWrap.afterConnect [as oncomplete] (node:net:1636:16)
at PipeConnectWrap.callbackTrampoline (node:internal/async_hooks:130:17)
[2025-05-28T14:56:53.129Z] error: <dockerStatsService> Error: connect EACCES /var/run/docker.sock
at PipeConnectWrap.afterConnect [as oncomplete] (node:net:1636:16)
at PipeConnectWrap.callbackTrampoline (node:internal/async_hooks:130:17)
[2025-05-28T14:56:53.137Z] error: <service-helpers> Error getting services from Docker server 'my-docker': [Error: connect EACCES /var/run/docker.sock] {
errno: -13,
code: 'EACCES',
syscall: 'connect',
address: '/var/run/docker.sock'
}
[2025-05-28T14:56:53.138Z] error: <dockerStatsService> Error: connect EACCES /var/run/docker.sock
at PipeConnectWrap.afterConnect [as oncomplete] (node:net:1636:16)
at PipeConnectWrap.callbackTrampoline (node:internal/async_hooks:130:17)
[2025-05-28T14:56:53.158Z] error: <dockerStatusService> Error: connect EACCES /var/run/docker.sock
at PipeConnectWrap.afterConnect [as oncomplete] (node:net:1636:16)
at PipeConnectWrap.callbackTrampoline (node:internal/async_hooks:130:17)
[2025-05-28T14:56:53.159Z] error: <dockerStatsService> Error: connect EACCES /var/run/docker.sock
at PipeConnectWrap.afterConnect [as oncomplete] (node:net:1636:16)
at PipeConnectWrap.callbackTrampoline (node:internal/async_hooks:130:17)
[2025-05-28T14:56:53.160Z] error: <dockerStatusService> Error: connect EACCES /var/run/docker.sock
at PipeConnectWrap.afterConnect [as oncomplete] (node:net:1636:16)
at PipeConnectWrap.callbackTrampoline (node:internal/async_hooks:130:17)
[2025-05-28T14:56:53.176Z] error: <dockerStatusService> Error: connect EACCES /var/run/docker.sock
at PipeConnectWrap.afterConnect [as oncomplete] (node:net:1636:16)
at PipeConnectWrap.callbackTrampoline (node:internal/async_hooks:130:17)
[2025-05-28T14:56:53.177Z] error: <dockerStatsService> Error: connect EACCES /var/run/docker.sock
at PipeConnectWrap.afterConnect [as oncomplete] (node:net:1636:16)
at PipeConnectWrap.callbackTrampoline (node:internal/async_hooks:130:17)
[2025-05-28T14:56:53.177Z] error: <dockerStatusService> Error: connect EACCES /var/run/docker.sock
at PipeConnectWrap.afterConnect [as oncomplete] (node:net:1636:16)
at PipeConnectWrap.callbackTrampoline (node:internal/async_hooks:130:17)
[2025-05-28T14:56:53.178Z] error: <dockerStatsService> Error: connect EACCES /var/run/docker.sock
at PipeConnectWrap.afterConnect [as oncomplete] (node:net:1636:16)
at PipeConnectWrap.callbackTrampoline (node:internal/async_hooks:130:17)
[2025-05-28T14:56:53.188Z] error: <dockerStatsService> Error: connect EACCES /var/run/docker.sock
at PipeConnectWrap.afterConnect [as oncomplete] (node:net:1636:16)
at PipeConnectWrap.callbackTrampoline (node:internal/async_hooks:130:17)
[2025-05-28T14:56:53.189Z] error: <dockerStatusService> Error: connect EACCES /var/run/docker.sock
at PipeConnectWrap.afterConnect [as oncomplete] (node:net:1636:16)
at PipeConnectWrap.callbackTrampoline (node:internal/async_hooks:130:17)
[2025-05-28T14:56:53.190Z] error: <dockerStatsService> Error: connect EACCES /var/run/docker.sock
at PipeConnectWrap.afterConnect [as oncomplete] (node:net:1636:16)
at PipeConnectWrap.callbackTrampoline (node:internal/async_hooks:130:17)
[2025-05-28T14:56:53.201Z] error: <dockerStatusService> Error: connect EACCES /var/run/docker.sock
at PipeConnectWrap.afterConnect [as oncomplete] (node:net:1636:16)
at PipeConnectWrap.callbackTrampoline (node:internal/async_hooks:130:17)
[2025-05-28T14:56:53.202Z] error: <dockerStatsService> Error: connect EACCES /var/run/docker.sock
at PipeConnectWrap.afterConnect [as oncomplete] (node:net:1636:16)
at PipeConnectWrap.callbackTrampoline (node:internal/async_hooks:130:17)
[2025-05-28T14:56:56.868Z] error: <dockerStatusService> Error: connect EACCES /var/run/docker.sock
at PipeConnectWrap.afterConnect [as oncomplete] (node:net:1636:16)
at PipeConnectWrap.callbackTrampoline (node:internal/async_hooks:130:17)
[2025-05-28T14:56:56.876Z] error: <service-helpers> Error getting services from Docker server 'my-docker': [Error: connect EACCES /var/run/docker.sock] {
errno: -13,
code: 'EACCES',
syscall: 'connect',
address: '/var/run/docker.sock'
}
[2025-05-28T14:56:56.877Z] error: <dockerStatsService> Error: connect EACCES /var/run/docker.sock
at PipeConnectWrap.afterConnect [as oncomplete] (node:net:1636:16)
at PipeConnectWrap.callbackTrampoline (node:internal/async_hooks:130:17)
[2025-05-28T14:56:56.878Z] error: <dockerStatusService> Error: connect EACCES /var/run/docker.sock
at PipeConnectWrap.afterConnect [as oncomplete] (node:net:1636:16)
at PipeConnectWrap.callbackTrampoline (node:internal/async_hooks:130:17)
[2025-05-28T14:56:56.890Z] error: <dockerStatusService> Error: connect EACCES /var/run/docker.sock
at PipeConnectWrap.afterConnect [as oncomplete] (node:net:1636:16)
at PipeConnectWrap.callbackTrampoline (node:internal/async_hooks:130:17)
[2025-05-28T14:56:56.891Z] error: <dockerStatsService> Error: connect EACCES /var/run/docker.sock
at PipeConnectWrap.afterConnect [as oncomplete] (node:net:1636:16)
at PipeConnectWrap.callbackTrampoline (node:internal/async_hooks:130:17)
[2025-05-28T14:56:56.891Z] error: <dockerStatusService> Error: connect EACCES /var/run/docker.sock
at PipeConnectWrap.afterConnect [as oncomplete] (node:net:1636:16)
at PipeConnectWrap.callbackTrampoline (node:internal/async_hooks:130:17)
[2025-05-28T14:56:56.891Z] error: <dockerStatsService> Error: connect EACCES /var/run/docker.sock
at PipeConnectWrap.afterConnect [as oncomplete] (node:net:1636:16)
at PipeConnectWrap.callbackTrampoline (node:internal/async_hooks:130:17)
[2025-05-28T14:56:56.896Z] error: <dockerStatsService> Error: connect EACCES /var/run/docker.sock
at PipeConnectWrap.afterConnect [as oncomplete] (node:net:1636:16)
at PipeConnectWrap.callbackTrampoline (node:internal/async_hooks:130:17)
[2025-05-28T14:56:56.906Z] error: <dockerStatusService> Error: connect EACCES /var/run/docker.sock
at PipeConnectWrap.afterConnect [as oncomplete] (node:net:1636:16)
at PipeConnectWrap.callbackTrampoline (node:internal/async_hooks:130:17)
[2025-05-28T14:56:56.907Z] error: <dockerStatsService> Error: connect EACCES /var/run/docker.sock
at PipeConnectWrap.afterConnect [as oncomplete] (node:net:1636:16)
at PipeConnectWrap.callbackTrampoline (node:internal/async_hooks:130:17)
[2025-05-28T14:56:56.907Z] error: <dockerStatusService> Error: connect EACCES /var/run/docker.sock
at PipeConnectWrap.afterConnect [as oncomplete] (node:net:1636:16)
at PipeConnectWrap.callbackTrampoline (node:internal/async_hooks:130:17)
[2025-05-28T14:56:56.908Z] error: <dockerStatsService> Error: connect EACCES /var/run/docker.sock
at PipeConnectWrap.afterConnect [as oncomplete] (node:net:1636:16)
at PipeConnectWrap.callbackTrampoline (node:internal/async_hooks:130:17)
[2025-05-28T14:56:56.919Z] error: <dockerStatsService> Error: connect EACCES /var/run/docker.sock
at PipeConnectWrap.afterConnect [as oncomplete] (node:net:1636:16)
at PipeConnectWrap.callbackTrampoline (node:internal/async_hooks:130:17)
[2025-05-28T14:56:56.920Z] error: <dockerStatusService> Error: connect EACCES /var/run/docker.sock
at PipeConnectWrap.afterConnect [as oncomplete] (node:net:1636:16)
at PipeConnectWrap.callbackTrampoline (node:internal/async_hooks:130:17)
[2025-05-28T14:56:56.920Z] error: <dockerStatsService> Error: connect EACCES /var/run/docker.sock
at PipeConnectWrap.afterConnect [as oncomplete] (node:net:1636:16)
at PipeConnectWrap.callbackTrampoline (node:internal/async_hooks:130:17)
[2025-05-28T14:56:56.922Z] error: <dockerStatusService> Error: connect EACCES /var/run/docker.sock
at PipeConnectWrap.afterConnect [as oncomplete] (node:net:1636:16)
at PipeConnectWrap.callbackTrampoline (node:internal/async_hooks:130:17)
[2025-05-28T14:56:56.936Z] error: <dockerStatusService> Error: connect EACCES /var/run/docker.sock
at PipeConnectWrap.afterConnect [as oncomplete] (node:net:1636:16)
at PipeConnectWrap.callbackTrampoline (node:internal/async_hooks:130:17)
[2025-05-28T14:56:56.936Z] error: <dockerStatsService> Error: connect EACCES /var/run/docker.sock
at PipeConnectWrap.afterConnect [as oncomplete] (node:net:1636:16)
at PipeConnectWrap.callbackTrampoline (node:internal/async_hooks:130:17)

View File

@ -0,0 +1,78 @@
---
# For public access, replace "http://localhost" with your domain (e.g., "https://changeme.org")
- Essential Tools:
- Code Server:
href: "http://localhost:8888"
# href: "https://changeme.org:8888" # Uncomment for public access
description: VS Code in the browser
icon: mdi-code-braces
widget:
type: docker
container: code-server-changemaker
server: my-docker
- Listmonk:
href: "http://localhost:9000"
# href: "https://changeme.org:9000" # Uncomment for public access
description: Newsletter & mailing list manager
icon: mdi-email-newsletter
widget:
type: docker
container: listmonk_app
server: my-docker
- NocoDB:
href: "http://localhost:8090"
# href: "https://changeme.org:8090" # Uncomment for public access
description: No-code database platform
icon: mdi-database
widget:
type: docker
container: nocodb
server: my-docker
- Content & Documentation:
- MkDocs (Live):
href: "http://localhost:4000"
# href: "https://changeme.org:4000" # Uncomment for public access
description: Live documentation server with hot reload
icon: mdi-book-open-page-variant
widget:
type: docker
container: mkdocs-changemaker
server: my-docker
- Static Site:
href: "http://localhost:4001"
# href: "https://changeme.org:4001" # Uncomment for public access
description: Built documentation hosting
icon: mdi-web
widget:
type: docker
container: mkdocs-site-server-changemaker
server: my-docker
- Automation & Infrastructure:
- n8n:
href: "http://localhost:5678"
# href: "https://changeme.org:5678" # Uncomment for public access
description: Workflow automation platform
icon: mdi-workflow
widget:
type: docker
container: n8n-changemaker
server: my-docker
- PostgreSQL (Listmonk):
href: "#"
description: Database for Listmonk
icon: mdi-database-outline
widget:
type: docker
container: listmonk-db
server: my-docker
- PostgreSQL (NocoDB):
href: "#"
description: Database for NocoDB
icon: mdi-database-outline
widget:
type: docker
container: root_db
server: my-docker

41
configs/homepage/settings.yaml Executable file
View File

@ -0,0 +1,41 @@
---
# For configuration options and examples, please see:
# https://gethomepage.dev/configs/settings/
title: Changemaker Lite
description: Self-hosted platform for documentation, development, and automation
theme: dark # or light
color: purple
background:
image: /images/background.png
blur: xs # sm, "", md, xl... see https://tailwindcss.com/docs/backdrop-blur
saturate: 100 # 0, 50, 100... see https://tailwindcss.com/docs/backdrop-saturate
brightness: 75 # 0, 50, 75... see https://tailwindcss.com/docs/backdrop-brightness
opacity: 50 # 0-100
cardBlur: xl # xs, md,
headerStyle: boxed
layout:
style: columns
columns: 3
quicklaunch:
searchDescriptions: true
hideInternetSearch: true
showSearchSuggestions: true
hideVisitURL: true
provider: duckduckgo
showStats: true
bookmarks:
showCategories: true
showIcons: true
target: _blank
columns: 3
pinned:
- Essential Tools:Code Server
- Content & Documentation:MkDocs (Live)
- Automation & Infrastructure:n8n

View File

@ -0,0 +1,23 @@
---
# For configuration options and examples, please see:
# https://gethomepage.dev/configs/info-widgets/
- resources:
cpu: true
memory: true
disk: /
- greeting:
text_size: xl
text: "Welcome to Changemaker Lite"
- datetime:
text_size: xl
format:
dateStyle: short
timeStyle: short
hour12: true
- search:
provider: duckduckgo
target: _blank

200
docker-compose.yml Normal file
View File

@ -0,0 +1,200 @@
services:
code-server:
build:
context: .
dockerfile: Dockerfile.code-server
container_name: code-server-changemaker
environment:
- DOCKER_USER=${USER_NAME:-coder}
- DEFAULT_WORKSPACE=/home/coder/mkdocs/
user: "${USER_ID:-1000}:${GROUP_ID:-1000}"
volumes:
- ./configs/code-server/.config:/home/coder/.config
- ./configs/code-server/.local:/home/coder/.local
- ./mkdocs:/home/coder/mkdocs/
ports:
- "${CODE_SERVER_PORT:-8888}:8080"
restart: unless-stopped
networks:
- changemaker
listmonk-app:
image: listmonk/listmonk:latest
container_name: listmonk_app
restart: unless-stopped
ports:
- "${LISTMONK_PORT:-9000}:9000"
networks:
- changemaker
hostname: ${LISTMONK_HOSTNAME}
depends_on:
- listmonk-db
command: [sh, -c, "./listmonk --install --idempotent --yes --config '' && ./listmonk --upgrade --yes --config '' && ./listmonk --config ''"]
environment:
LISTMONK_app__address: 0.0.0.0:9000
LISTMONK_db__user: ${POSTGRES_USER}
LISTMONK_db__password: ${POSTGRES_PASSWORD}
LISTMONK_db__database: ${POSTGRES_DB}
LISTMONK_db__host: listmonk-db
LISTMONK_db__port: 5432
LISTMONK_db__ssl_mode: disable
LISTMONK_db__max_open: 25
LISTMONK_db__max_idle: 25
LISTMONK_db__max_lifetime: 300s
TZ: Etc/UTC
LISTMONK_ADMIN_USER: ${LISTMONK_ADMIN_USER:-}
LISTMONK_ADMIN_PASSWORD: ${LISTMONK_ADMIN_PASSWORD:-}
# SMTP Configuration
LISTMONK_smtp__host: ${LISTMONK_SMTP_HOST:-}
LISTMONK_smtp__port: ${LISTMONK_SMTP_PORT:-587}
LISTMONK_smtp__auth_protocol: ${LISTMONK_SMTP_AUTH_PROTOCOL:-plain}
LISTMONK_smtp__username: ${LISTMONK_SMTP_USERNAME:-}
LISTMONK_smtp__password: ${LISTMONK_SMTP_PASSWORD:-}
LISTMONK_smtp__hello_hostname: ${LISTMONK_SMTP_HELLO_HOSTNAME:-}
LISTMONK_smtp__tls_enabled: ${LISTMONK_SMTP_TLS_ENABLED:-true}
LISTMONK_smtp__tls_skip_verify: ${LISTMONK_SMTP_TLS_SKIP_VERIFY:-false}
LISTMONK_smtp__max_conns: ${LISTMONK_SMTP_MAX_CONNS:-10}
LISTMONK_smtp__max_msg_retries: ${LISTMONK_SMTP_MAX_MSG_RETRIES:-2}
LISTMONK_smtp__idle_timeout: ${LISTMONK_SMTP_IDLE_TIMEOUT:-10s}
LISTMONK_smtp__wait_timeout: ${LISTMONK_SMTP_WAIT_TIMEOUT:-5s}
LISTMONK_smtp__email_headers: ${LISTMONK_SMTP_EMAIL_HEADERS:-}
volumes:
- ./assets/uploads:/listmonk/uploads:rw
listmonk-db:
image: postgres:17-alpine
container_name: listmonk-db
restart: unless-stopped
ports:
- "${LISTMONK_DB_PORT:-5432}:5432"
networks:
- changemaker
environment:
POSTGRES_USER: ${POSTGRES_USER}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
POSTGRES_DB: ${POSTGRES_DB}
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER}"]
interval: 10s
timeout: 5s
retries: 6
volumes:
- type: volume
source: listmonk-data
target: /var/lib/postgresql/data
mkdocs:
image: squidfunk/mkdocs-material
container_name: mkdocs-changemaker
volumes:
- ./mkdocs:/docs:rw
- ./assets/images:/docs/assets/images:rw
user: "${USER_ID:-1000}:${GROUP_ID:-1000}"
ports:
- "${MKDOCS_PORT:-4000}:8000"
environment:
- SITE_URL=${BASE_DOMAIN:-https://changeme.org}
command: serve --dev-addr=0.0.0.0:8000 --watch-theme --livereload
networks:
- changemaker
restart: unless-stopped
mkdocs-site-server:
image: lscr.io/linuxserver/nginx:latest
container_name: mkdocs-site-server-changemaker
environment:
- PUID=${USER_ID:-1000} # Uses USER_ID from your .env file, defaults to 1000
- PGID=${GROUP_ID:-1000} # Uses GROUP_ID from your .env file, defaults to 1000
- TZ=Etc/UTC
volumes:
- ./mkdocs/site:/config/www # Mounts your static site to Nginx's web root
ports:
- "${MKDOCS_SITE_SERVER_PORT:-4001}:80" # Exposes Nginx's port 80 to host port 4001
restart: unless-stopped
networks:
- changemaker
n8n:
image: docker.n8n.io/n8nio/n8n
container_name: n8n-changemaker
restart: unless-stopped
ports:
- "${N8N_PORT:-5678}:5678"
environment:
- N8N_HOST=${N8N_HOST:-n8n.${DOMAIN}}
- N8N_PORT=5678
- N8N_PROTOCOL=https
- NODE_ENV=production
- WEBHOOK_URL=https://${N8N_HOST:-n8n.${DOMAIN}}/
- GENERIC_TIMEZONE=${GENERIC_TIMEZONE:-UTC}
- N8N_ENCRYPTION_KEY=${N8N_ENCRYPTION_KEY:-changeMe}
- N8N_USER_MANAGEMENT_DISABLED=false
- N8N_DEFAULT_USER_EMAIL=${N8N_USER_EMAIL:-admin@example.com}
- N8N_DEFAULT_USER_PASSWORD=${N8N_USER_PASSWORD:-changeMe}
volumes:
- n8n_data:/home/node/.n8n
- ./local-files:/files
networks:
- changemaker
nocodb:
depends_on:
root_db:
condition: service_healthy
environment:
NC_DB: "pg://root_db:5432?u=postgres&p=password&d=root_db"
image: "nocodb/nocodb:latest"
ports:
- "${NOCODB_PORT:-8090}:8080"
restart: always
volumes:
- "nc_data:/usr/app/data"
networks:
- changemaker
root_db:
environment:
POSTGRES_DB: root_db
POSTGRES_PASSWORD: password
POSTGRES_USER: postgres
healthcheck:
interval: 10s
retries: 10
test: "pg_isready -U \"$$POSTGRES_USER\" -d \"$$POSTGRES_DB\""
timeout: 2s
image: postgres:16.6
restart: always
volumes:
- "db_data:/var/lib/postgresql/data"
networks:
- changemaker
# Homepage App
homepage-changemaker:
image: ghcr.io/gethomepage/homepage:latest
container_name: homepage-changemaker
ports:
- "${HOMEPAGE_PORT:-3010}:3000"
volumes:
- ./configs/homepage:/app/config
- ./assets/icons:/app/public/icons
- ./assets/images:/app/public/images
- /var/run/docker.sock:/var/run/docker.sock
environment:
- PUID=${USER_ID:-1000}
- PGID=${DOCKER_GROUP_ID:-984}
- TZ=Etc/UTC
- HOMEPAGE_ALLOWED_HOSTS=*
- HOMEPAGE_VAR_BASE_URL=${HOMEPAGE_VAR_BASE_URL:-http://localhost}
restart: unless-stopped
networks:
- changemaker
networks:
changemaker:
driver: bridge
volumes:
listmonk-data:
n8n_data:
nc_data:
db_data:

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

View File

@ -0,0 +1,231 @@
# Getting Started
Welcome to Changemaker Lite! This guide will help you get up and running quickly.
## Prerequisites
Before starting, ensure you have:
- [Docker](https://docs.docker.com/get-docker/) installed
- [Docker Compose](https://docs.docker.com/compose/install/) installed
- Git for cloning the repository
- Basic familiarity with terminal/command line
## Installation
### 1. Clone Repository
```bash
git clone https://gitea.bnkops.com/admin/Changemaker.git
cd changemaker.lite
```
### 2. Configuration
Run the configuration script to set up environment variables:
```bash
./config.sh
```
This creates a `.env` file with default settings. You can edit this file to customize:
- Service ports
- Database credentials
- User/group IDs
- Domain settings
### 3. Start Services
Launch all services with Docker Compose:
```bash
docker compose up -d
```
Wait a few minutes for all services to start, especially on first run as Docker images need to be downloaded.
### 4. Verify Installation
Check that services are running:
```bash
docker compose ps
```
All services should show as "Up" status.
## First Steps
### Access the Dashboard
Start with the **Homepage Dashboard**: http://localhost:3010
- Central hub for all services
- Live status monitoring
- Quick access to all applications
### Access Documentation
1. **Development Server**: http://localhost:4000
- Live preview with auto-reload
- Used while writing documentation
2. **Production Server**: http://localhost:4001
- Serves built static site
- Optimized for performance
### Start Coding
1. Open **Code Server**: http://localhost:8888
2. Navigate to `/home/coder/mkdocs/` workspace
3. Edit documentation files in `docs/` directory
4. See changes instantly in development server
### Set Up Email Campaigns
1. Access **Listmonk**: http://localhost:9000
2. Log in with admin credentials (set in config)
3. Configure SMTP settings
4. Create your first mailing list
### Create Workflows
1. Open **n8n**: http://localhost:5678
2. Log in with admin credentials
3. Create your first workflow
4. Connect different services together
### Manage Data with NocoDB
1. Access **NocoDB**: http://localhost:8090
2. Complete the initial setup
3. Create your first project
4. Import data or create new tables
### Access All Services via Homepage
1. Open **Homepage**: http://localhost:3010
2. View all services in one dashboard
3. Monitor service status
4. Quick access to all applications
## Configuration Details
### Environment Variables
Key settings in `.env` file:
```env
# Service Ports
HOMEPAGE_PORT=3010
CODE_SERVER_PORT=8888
MKDOCS_PORT=4000
MKDOCS_SITE_SERVER_PORT=4001
LISTMONK_PORT=9000
N8N_PORT=5678
NOCODB_PORT=8090
# Database
POSTGRES_USER=listmonk
POSTGRES_PASSWORD=your_secure_password
POSTGRES_DB=listmonk
# User/Group IDs (match your system)
USER_ID=1000
GROUP_ID=1000
```
### Volume Mounts
Important directories:
- `./mkdocs/`: Documentation source files
- `./configs/`: Service configurations
- `./assets/`: Shared assets and uploads
- Docker volumes for persistent data
## Common Tasks
### Writing Documentation
1. Edit files in `mkdocs/docs/` using Code Server
2. Preview changes at http://localhost:4000
3. Build static site: `docker exec mkdocs-changemaker mkdocs build`
4. View built site at http://localhost:4001
### Managing Services
```bash
# View logs
docker compose logs [service-name]
# Restart service
docker compose restart [service-name]
# Stop all services
docker compose down
# Update services
docker compose pull && docker compose up -d
```
### Backup Important Data
- Export n8n workflows
- Backup PostgreSQL database
- Version control your documentation files
- Save service configurations
## Troubleshooting
### Port Conflicts
If ports are already in use, edit `.env` file:
```env
CODE_SERVER_PORT=8889 # Change from 8888
MKDOCS_PORT=4002 # Change from 4000
```
Then restart: `docker compose down && docker compose up -d`
### Permission Issues
Ensure correct user/group IDs in `.env`:
```bash
# Get your user ID
id -u
# Get your group ID
id -g
```
Update `.env` with these values and restart services.
### Service Won't Start
Check logs for specific errors:
```bash
docker compose logs [service-name]
```
Common issues:
- Port conflicts
- Permission problems
- Missing environment variables
- Network connectivity
## Next Steps
- Explore the [Services](services/index.md) documentation
- Set up your first [n8n workflow](services/n8n.md)
- Configure [Listmonk](services/listmonk.md) for email campaigns
- Customize your [MkDocs](services/mkdocs.md) theme and content
## Getting Help
- Check service-specific documentation
- Review Docker container logs
- Verify environment configuration
- Test network connectivity between services

60
mkdocs/docs/index.md Normal file
View File

@ -0,0 +1,60 @@
# Welcome to Changemaker Lite
A streamlined, self-hosted platform for documentation and development.
## Quick Start
Get up and running in minutes:
```bash
# Clone the repository
git clone https://gitea.bnkops.com/admin/Changemaker.git
cd changemaker.lite
# Configure environment
./config.sh
# Start all services
docker compose up -d
```
## Services
Changemaker Lite includes these essential services:
- **[Homepage](services/homepage.md)** (Port 3010) - Service dashboard and monitoring
- **[Code Server](services/code-server.md)** (Port 8888) - VS Code in your browser
- **[MkDocs](services/mkdocs.md)** (Port 4000) - Documentation with live preview
- **[Static Server](services/static-server.md)** (Port 4001) - Built site hosting
- **[Waypoint Editor](services/waypoint-editor.md)** (Port 3020) - Visual page editor
- **[Listmonk](services/listmonk.md)** (Port 9000) - Newsletter management
- **[PostgreSQL](services/postgresql.md)** (Port 5432) - Database backend
- **[n8n](services/n8n.md)** (Port 5678) - Workflow automation
- **[NocoDB](services/nocodb.md)** (Port 8090) - No-code database platform
## Getting Started
1. **Documentation**: Start writing in [Code Server](http://localhost:8888)
2. **Preview**: See live changes at [MkDocs](http://localhost:4000)
3. **Production**: View built site at [Static Server](http://localhost:4001)
4. **Email**: Set up campaigns with [Listmonk](http://localhost:9000)
5. **Automation**: Create workflows in [n8n](http://localhost:5678)
## Project Structure
```
changemaker.lite/
├── docker-compose.yml # Service definitions
├── config.sh # Setup script
├── mkdocs/ # Documentation source
│ ├── docs/ # Markdown files
│ └── mkdocs.yml # Configuration
├── configs/ # Service configurations
└── assets/ # Shared assets
```
## Learn More
- [Services Overview](services/index.md) - Detailed service documentation
- [Blog](blog/index.md) - Updates and tutorials
- [GitHub Repository](https://gitea.bnkops.com/admin/Changemaker) - Source code and issues

View File

View File

@ -0,0 +1,9 @@
{% extends "base.html" %}
{% block extrahead %}
{% endblock %}
{% block announce %}
<a href="https://homepage.test.com" class="login-button">Login</a>
Changemaker Archive. <a href="https://docs.bnkops.com">Learn more</a>
{% endblock %}

View File

@ -0,0 +1,59 @@
# Code Server
Visual Studio Code in your browser for remote development.
## Overview
Code Server provides a full Visual Studio Code experience in your web browser, allowing you to develop from any device. It runs on your server and provides access to your development environment through a web interface.
## Features
- Full VS Code experience in the browser
- Extensions support
- Terminal access
- Git integration
- File editing and management
- Multi-language support
## Access
- **Default Port**: 8888
- **URL**: `http://localhost:8888`
- **Default Workspace**: `/home/coder/mkdocs/`
## Configuration
### Environment Variables
- `DOCKER_USER`: The user to run code-server as (default: `coder`)
- `DEFAULT_WORKSPACE`: Default workspace directory
- `USER_ID`: User ID for file permissions
- `GROUP_ID`: Group ID for file permissions
### Volumes
- `./configs/code-server/.config`: VS Code configuration
- `./configs/code-server/.local`: Local data
- `./mkdocs`: Main workspace directory
## Usage
1. Access Code Server at `http://localhost:8888`
2. Open the `/home/coder/mkdocs/` workspace
3. Start editing your documentation files
4. Install extensions as needed
5. Use the integrated terminal for commands
## Useful Extensions
Consider installing these extensions for better documentation work:
- Markdown All in One
- Material Design Icons
- GitLens
- Docker
- YAML
## Official Documentation
For more detailed information, visit the [official Code Server documentation](https://coder.com/docs/code-server).

View File

@ -0,0 +1,199 @@
# Homepage
Modern dashboard for accessing all your self-hosted services.
## Overview
Homepage is a modern, fully static, fast, secure fully configurable application dashboard with integrations for over 100 services. It provides a beautiful and customizable interface to access all your Changemaker Lite services from a single location.
## Features
- **Service Dashboard**: Central hub for all your applications
- **Docker Integration**: Automatic service discovery and monitoring
- **Customizable Layout**: Flexible grid-based layout system
- **Service Widgets**: Live status and metrics for services
- **Quick Search**: Fast navigation with built-in search
- **Bookmarks**: Organize frequently used links
- **Dark/Light Themes**: Multiple color schemes available
- **Responsive Design**: Works on desktop and mobile devices
## Access
- **Default Port**: 3010
- **URL**: `http://localhost:3010`
- **Configuration**: YAML-based configuration files
## Configuration
### Environment Variables
- `HOMEPAGE_PORT`: External port mapping (default: 3010)
- `PUID`: User ID for file permissions (default: 1000)
- `PGID`: Group ID for file permissions (default: 1000)
- `TZ`: Timezone setting (default: Etc/UTC)
- `HOMEPAGE_ALLOWED_HOSTS`: Allowed hosts for the dashboard
### Configuration Files
Homepage uses YAML configuration files located in `./configs/homepage/`:
- `settings.yaml`: Global settings and theme configuration
- `services.yaml`: Service definitions and widgets
- `bookmarks.yaml`: Bookmark categories and links
- `widgets.yaml`: Dashboard widgets configuration
- `docker.yaml`: Docker integration settings
### Volumes
- `./configs/homepage:/app/config`: Configuration files
- `./assets/icons:/app/public/icons`: Custom service icons
- `./assets/images:/app/public/images`: Background images and assets
- `/var/run/docker.sock:/var/run/docker.sock`: Docker socket for container monitoring
## Changemaker Lite Services
Homepage is pre-configured with all Changemaker Lite services:
### Essential Tools
- **Code Server** (Port 8888): VS Code in the browser
- **Listmonk** (Port 9000): Newsletter & mailing list manager
- **NocoDB** (Port 8090): No-code database platform
### Content & Documentation
- **MkDocs** (Port 4000): Live documentation server
- **Static Site** (Port 4001): Built documentation hosting
### Automation & Data
- **n8n** (Port 5678): Workflow automation platform
- **PostgreSQL** (Port 5432): Database backends
## Customization
### Adding Custom Services
Edit `configs/homepage/services.yaml` to add new services:
```yaml
- Custom Category:
- My Service:
href: http://localhost:8080
description: Custom service description
icon: mdi-application
widget:
type: ping
url: http://localhost:8080
```
### Custom Icons
Add custom icons to `./assets/icons/` directory and reference them in services.yaml:
```yaml
icon: /icons/my-custom-icon.png
```
### Themes and Styling
Modify `configs/homepage/settings.yaml` to customize appearance:
```yaml
theme: dark # or light
color: purple # slate, gray, zinc, neutral, stone, red, orange, amber, yellow, lime, green, emerald, teal, cyan, sky, blue, indigo, violet, purple, fuchsia, pink, rose
```
### Widgets
Enable live monitoring widgets in `configs/homepage/services.yaml`:
```yaml
- Service Name:
widget:
type: docker
container: container-name
server: my-docker
```
## Service Monitoring
Homepage can display real-time status information for your services:
- **Docker Integration**: Container status and resource usage
- **HTTP Ping**: Service availability monitoring
- **Custom APIs**: Integration with service-specific APIs
## Docker Integration
Homepage monitors Docker containers automatically when configured:
1. Ensure Docker socket is mounted (`/var/run/docker.sock`)
2. Configure container mappings in `docker.yaml`
3. Add widget configurations to `services.yaml`
## Security Considerations
- Homepage runs with limited privileges
- Configuration files should have appropriate permissions
- Consider network isolation for production deployments
- Use HTTPS for external access
- Regularly update the Homepage image
## Troubleshooting
### Common Issues
**Configuration not loading**: Check YAML syntax in configuration files
```bash
docker logs homepage-changemaker
```
**Icons not displaying**: Verify icon paths and file permissions
```bash
ls -la ./assets/icons/
```
**Services not reachable**: Verify network connectivity between containers
```bash
docker exec homepage-changemaker ping service-name
```
**Widget data not updating**: Check Docker socket permissions and container access
```bash
docker exec homepage-changemaker ls -la /var/run/docker.sock
```
## Configuration Examples
### Basic Service Widget
```yaml
- Code Server:
href: http://localhost:8888
description: VS Code in the browser
icon: code-server
widget:
type: docker
container: code-server-changemaker
```
### Custom Dashboard Layout
```yaml
# settings.yaml
layout:
style: columns
columns: 3
# Responsive breakpoints
responsive:
mobile: 1
tablet: 2
desktop: 3
```
## Official Documentation
For comprehensive configuration guides and advanced features:
- [Homepage Documentation](https://gethomepage.dev/)
- [GitHub Repository](https://github.com/gethomepage/homepage)
- [Configuration Examples](https://gethomepage.dev/configs/)
- [Widget Integrations](https://gethomepage.dev/widgets/)

View File

@ -0,0 +1,175 @@
# Services
Changemaker Lite includes several powerful services that work together to provide a complete documentation and development platform. Each service is containerized and can be accessed through its dedicated port.
## Available Services
### [Code Server](code-server.md)
**Port: 8888** | Visual Studio Code in your browser for remote development
- Full IDE experience
- Extensions support
- Git integration
- Terminal access
### [Listmonk](listmonk.md)
**Port: 9000** | Self-hosted newsletter and mailing list manager
- Email campaigns
- Subscriber management
- Analytics
- Template system
### [PostgreSQL](postgresql.md)
**Port: 5432** | Reliable database backend
- Data persistence for Listmonk
- ACID compliance
- High performance
- Backup and restore capabilities
### [MkDocs Material](mkdocs.md)
**Port: 4000** | Documentation site generator with live preview
- Material Design theme
- Live reload
- Search functionality
- Markdown support
### [Static Site Server](static-server.md)
**Port: 4001** | Nginx-powered static site hosting
- High-performance serving
- Built documentation hosting
- Caching and compression
- Security headers
### [Silex](silex.md)
**Port: 6805** | Visual website editor
- Drag-and-drop web design
- Filesystem-based storage
- Template editing for MkDocs
- No-code HTML creation
### [n8n](n8n.md)
**Port: 5678** | Workflow automation tool
- Visual workflow editor
- 400+ integrations
- Custom code execution
- Webhook support
### [NocoDB](nocodb.md)
**Port: 8090** | No-code database platform
- Smart spreadsheet interface
- Form builder and API generation
- Real-time collaboration
- Multi-database support
### [Homepage](homepage.md)
**Port: 3010** | Modern dashboard for all services
- Service dashboard and monitoring
- Docker integration
- Customizable layout
- Quick search and bookmarks
## Service Architecture
```
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ Homepage │ │ Code Server │ │ MkDocs │
│ :3010 │ │ :8888 │ │ :4000 │
└─────────────────┘ └─────────────────┘ └─────────────────┘
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ Static Server │ │ Listmonk │ │ n8n │
│ :4001 │ │ :9000 │ │ :5678 │
└─────────────────┘ └─────────────────┘ └─────────────────┘
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ NocoDB │ │ PostgreSQL │ │ PostgreSQL │
│ :8090 │ │ (listmonk-db) │ │ (root_db) │
└─────────────────┘ │ :5432 │ │ :5432 │
│ └─────────────────┘ └─────────────────┘
└──────────────────────────────────────────────────────┘
```
## Getting Started
1. **Start all services**: `docker compose up -d`
2. **Check service status**: `docker compose ps`
3. **View logs**: `docker compose logs [service-name]`
4. **Stop services**: `docker compose down`
## Service Dependencies
- **Listmonk** depends on **PostgreSQL** (listmonk-db)
- **NocoDB** depends on **PostgreSQL** (root_db)
- **Static Server** serves content built by **MkDocs**
- **n8n** can integrate with all other services
- All services share the `changemaker` network
## Environment Configuration
Services are configured through environment variables in your `.env` file:
```env
# Port configurations
CODE_SERVER_PORT=8888
LISTMONK_PORT=9000
LISTMONK_DB_PORT=5432
MKDOCS_PORT=4000
MKDOCS_SITE_SERVER_PORT=4001
N8N_PORT=5678
# User and group IDs
USER_ID=1000
GROUP_ID=1000
# Database configuration
POSTGRES_USER=listmonk
POSTGRES_PASSWORD=your_password
POSTGRES_DB=listmonk
# n8n configuration
N8N_ENCRYPTION_KEY=your_encryption_key
N8N_USER_EMAIL=admin@example.com
N8N_USER_PASSWORD=your_password
```
## Monitoring and Maintenance
### Health Checks
```bash
# Check all services
docker compose ps
# Check specific service logs
docker compose logs listmonk-app
docker compose logs code-server
```
### Updates
```bash
# Pull latest images
docker compose pull
# Restart with new images
docker compose down && docker compose up -d
```
### Backups
- **PostgreSQL**: Regular database backups
- **n8n**: Export workflows and credentials
- **Code Server**: Backup configuration and workspace
- **MkDocs**: Version control your documentation
## Troubleshooting
### Common Issues
1. **Port Conflicts**: Ensure ports are not used by other applications
2. **Permission Issues**: Check `USER_ID` and `GROUP_ID` settings
3. **Network Issues**: Verify services can communicate through the `changemaker` network
4. **Data Persistence**: Ensure volumes are properly mounted
### Getting Help
- Check individual service documentation
- Review container logs for error messages
- Verify environment variable configuration
- Test network connectivity between services

View File

@ -0,0 +1,66 @@
# Listmonk
Self-hosted newsletter and mailing list manager.
## Overview
Listmonk is a modern, feature-rich newsletter and mailing list manager designed for high performance and easy management. It provides a complete solution for email campaigns, subscriber management, and analytics.
## Features
- Newsletter and email campaign management
- Subscriber list management
- Template system with HTML/markdown support
- Campaign analytics and tracking
- API for integration
- Multi-list support
- Bounce handling
- Privacy-focused design
## Access
- **Default Port**: 9000
- **URL**: `http://localhost:9000`
- **Admin User**: Set via `LISTMONK_ADMIN_USER` environment variable
- **Admin Password**: Set via `LISTMONK_ADMIN_PASSWORD` environment variable
## Configuration
### Environment Variables
- `LISTMONK_ADMIN_USER`: Admin username
- `LISTMONK_ADMIN_PASSWORD`: Admin password
- `POSTGRES_USER`: Database username
- `POSTGRES_PASSWORD`: Database password
- `POSTGRES_DB`: Database name
### Database
Listmonk uses PostgreSQL as its backend database. The database is automatically configured through the docker-compose setup.
### Uploads
- Upload directory: `./assets/uploads`
- Used for media files, templates, and attachments
## Getting Started
1. Access Listmonk at `http://localhost:9000`
2. Log in with your admin credentials
3. Set up your first mailing list
4. Configure SMTP settings for sending emails
5. Import subscribers or create subscription forms
6. Create your first campaign
## Important Notes
- Configure SMTP settings before sending emails
- Set up proper domain authentication (SPF, DKIM) for better deliverability
- Regularly backup your subscriber data and campaigns
- Monitor bounce rates and maintain list hygiene
## Official Documentation
For comprehensive guides and API documentation, visit:
- [Listmonk Documentation](https://listmonk.app/docs/)
- [GitHub Repository](https://github.com/knadh/listmonk)

View File

@ -0,0 +1,124 @@
# MkDocs Material
Modern documentation site generator with live preview.
## Overview
MkDocs Material is a powerful documentation framework built on top of MkDocs, providing a beautiful Material Design theme and advanced features for creating professional documentation sites.
## Features
- Material Design theme
- Live preview during development
- Search functionality
- Navigation and organization
- Code syntax highlighting
- Mathematical expressions support
- Responsive design
- Customizable themes and colors
## Access
- **Development Port**: 4000
- **Development URL**: `http://localhost:4000`
- **Live Reload**: Automatically refreshes on file changes
## Configuration
### Main Configuration
Configuration is managed through `mkdocs.yml` in the project root.
### Volumes
- `./mkdocs`: Documentation source files
- `./assets/images`: Shared images directory
### Environment Variables
- `SITE_URL`: Base domain for the site
- `USER_ID`: User ID for file permissions
- `GROUP_ID`: Group ID for file permissions
## Directory Structure
```
mkdocs/
├── mkdocs.yml # Configuration file
├── docs/ # Documentation source
│ ├── index.md # Homepage
│ ├── services/ # Service documentation
│ ├── blog/ # Blog posts
│ └── overrides/ # Template overrides
└── site/ # Built static site
```
## Writing Documentation
### Markdown Basics
- Use standard Markdown syntax
- Support for tables, code blocks, and links
- Mathematical expressions with MathJax
- Admonitions for notes and warnings
### Example Page
```markdown
# Page Title
This is a sample documentation page.
## Section
Content goes here with **bold** and *italic* text.
### Code Example
```python
def hello_world():
print("Hello, World!")
```
!!! note
This is an informational note.
```
## Building and Deployment
### Development
The development server runs automatically with live reload.
### Building Static Site
```bash
docker exec mkdocs-changemaker mkdocs build
```
The built site will be available in the `mkdocs/site/` directory.
## Customization
### Themes and Colors
Customize appearance in `mkdocs.yml`:
```yaml
theme:
name: material
palette:
primary: blue
accent: indigo
```
### Custom CSS
Add custom styles in `docs/stylesheets/extra.css`.
## Official Documentation
For comprehensive MkDocs Material documentation:
- [MkDocs Material](https://squidfunk.github.io/mkdocs-material/)
- [MkDocs Documentation](https://www.mkdocs.org/)
- [Markdown Guide](https://www.markdownguide.org/)

145
mkdocs/docs/services/n8n.md Normal file
View File

@ -0,0 +1,145 @@
# n8n
Workflow automation tool for connecting services and automating tasks.
## Overview
n8n is a powerful workflow automation tool that allows you to connect various apps and services together. It provides a visual interface for creating automated workflows, making it easy to integrate different systems and automate repetitive tasks.
## Features
- Visual workflow editor
- 400+ integrations
- Custom code execution (JavaScript/Python)
- Webhook support
- Scheduled workflows
- Error handling and retries
- User management
- API access
- Self-hosted and privacy-focused
## Access
- **Default Port**: 5678
- **URL**: `http://localhost:5678`
- **Default User Email**: Set via `N8N_DEFAULT_USER_EMAIL`
- **Default User Password**: Set via `N8N_DEFAULT_USER_PASSWORD`
## Configuration
### Environment Variables
- `N8N_HOST`: Hostname for n8n (default: `n8n.${DOMAIN}`)
- `N8N_PORT`: Internal port (5678)
- `N8N_PROTOCOL`: Protocol for webhooks (https)
- `NODE_ENV`: Environment (production)
- `WEBHOOK_URL`: Base URL for webhooks
- `GENERIC_TIMEZONE`: Timezone setting
- `N8N_ENCRYPTION_KEY`: Encryption key for credentials
- `N8N_USER_MANAGEMENT_DISABLED`: Enable/disable user management
- `N8N_DEFAULT_USER_EMAIL`: Default admin email
- `N8N_DEFAULT_USER_PASSWORD`: Default admin password
### Volumes
- `n8n_data`: Persistent data storage
- `./local-files`: Local file access for workflows
## Getting Started
1. Access n8n at `http://localhost:5678`
2. Log in with your admin credentials
3. Create your first workflow
4. Add nodes for different services
5. Configure connections between nodes
6. Test and activate your workflow
## Common Use Cases
### Documentation Automation
- Auto-generate documentation from code comments
- Sync documentation between different platforms
- Notify team when documentation is updated
### Email Campaign Integration
- Connect Listmonk with external data sources
- Automate subscriber management
- Trigger campaigns based on events
### Database Management with NocoDB
- Sync data between NocoDB and external APIs
- Automate data entry and validation
- Create backup workflows for database content
- Generate reports from NocoDB data
### Development Workflows
- Auto-deploy documentation on git push
- Sync code changes with documentation
- Backup automation
### Data Processing
- Process CSV files and import to databases
- Transform data between different formats
- Schedule regular data updates
## Example Workflows
### Simple Webhook to Email
```
Webhook → Email
```
### Scheduled Documentation Backup
```
Schedule → Read Files → Compress → Upload to Storage
```
### Git Integration
```
Git Webhook → Process Changes → Update Documentation → Notify Team
```
## Security Considerations
- Use strong encryption keys
- Secure webhook URLs
- Regularly update credentials
- Monitor workflow executions
- Implement proper error handling
## Integration with Other Services
n8n can integrate with all services in your Changemaker Lite setup:
- **Listmonk**: Manage subscribers and campaigns
- **PostgreSQL**: Read/write database operations
- **Code Server**: File operations and git integration
- **MkDocs**: Documentation generation and updates
## Troubleshooting
### Common Issues
- **Workflow Execution Errors**: Check node configurations and credentials
- **Webhook Issues**: Verify URLs and authentication
- **Connection Problems**: Check network connectivity between services
### Debugging
```bash
# Check container logs
docker logs n8n-changemaker
# Access container shell
docker exec -it n8n-changemaker sh
# Check workflow executions in the UI
# Visit http://localhost:5678 → Executions
```
## Official Documentation
For comprehensive n8n documentation:
- [n8n Documentation](https://docs.n8n.io/)
- [Community Workflows](https://n8n.io/workflows/)
- [Node Reference](https://docs.n8n.io/integrations/builtin/)
- [GitHub Repository](https://github.com/n8n-io/n8n)

View File

@ -0,0 +1,153 @@
# NocoDB
No-code database platform that turns any database into a smart spreadsheet.
## Overview
NocoDB is an open-source no-code platform that transforms any database into a smart spreadsheet interface. It provides a user-friendly way to manage data, create forms, build APIs, and collaborate on database operations without requiring extensive technical knowledge.
## Features
- **Smart Spreadsheet Interface**: Transform databases into intuitive spreadsheets
- **Form Builder**: Create custom forms for data entry
- **API Generation**: Auto-generated REST APIs for all tables
- **Collaboration**: Real-time collaboration with team members
- **Access Control**: Role-based permissions and sharing
- **Data Visualization**: Charts and dashboard creation
- **Webhooks**: Integration with external services
- **Import/Export**: Support for CSV, Excel, and other formats
- **Multi-Database Support**: Works with PostgreSQL, MySQL, SQLite, and more
## Access
- **Default Port**: 8090
- **URL**: `http://localhost:8090`
- **Database**: PostgreSQL (dedicated `root_db` instance)
## Configuration
### Environment Variables
- `NOCODB_PORT`: External port mapping (default: 8090)
- `NC_DB`: Database connection string for PostgreSQL backend
### Database Backend
NocoDB uses a dedicated PostgreSQL instance (`root_db`) with the following configuration:
- **Database Name**: `root_db`
- **Username**: `postgres`
- **Password**: `password`
- **Host**: `root_db` (internal container name)
### Volumes
- `nc_data`: Application data and configuration storage
- `db_data`: PostgreSQL database files
## Getting Started
1. **Access NocoDB**: Navigate to `http://localhost:8090`
2. **Initial Setup**: Complete the onboarding process
3. **Create Project**: Start with a new project or connect existing databases
4. **Add Tables**: Import data or create new tables
5. **Configure Views**: Set up different views (Grid, Form, Gallery, etc.)
6. **Set Permissions**: Configure user access and sharing settings
## Common Use Cases
### Content Management
- Create content databases for blogs and websites
- Manage product catalogs and inventories
- Track customer information and interactions
### Project Management
- Task and project tracking systems
- Team collaboration workspaces
- Resource and timeline management
### Data Collection
- Custom forms for surveys and feedback
- Event registration and management
- Lead capture and CRM systems
### Integration with Other Services
NocoDB can integrate well with other Changemaker Lite services:
- **n8n Integration**: Use NocoDB as a data source/destination in automation workflows
- **Listmonk Integration**: Manage subscriber lists and campaign data
- **Documentation**: Store and manage documentation metadata
## API Usage
NocoDB automatically generates REST APIs for all your tables:
```bash
# Get all records from a table
GET http://localhost:8090/api/v1/db/data/v1/{project}/table/{table}
# Create a new record
POST http://localhost:8090/api/v1/db/data/v1/{project}/table/{table}
# Update a record
PATCH http://localhost:8090/api/v1/db/data/v1/{project}/table/{table}/{id}
```
## Backup and Data Management
### Database Backup
Since NocoDB uses PostgreSQL, you can backup the database:
```bash
# Backup NocoDB database
docker exec root_db pg_dump -U postgres root_db > nocodb_backup.sql
# Restore from backup
docker exec -i root_db psql -U postgres root_db < nocodb_backup.sql
```
### Application Data
Application settings and metadata are stored in the `nc_data` volume.
## Security Considerations
- Change default database credentials in production
- Configure proper access controls within NocoDB
- Use HTTPS for production deployments
- Regularly backup both database and application data
- Monitor access logs and user activities
## Performance Tips
- Regular database maintenance and optimization
- Monitor memory usage for large datasets
- Use appropriate indexing for frequently queried fields
- Consider database connection pooling for high-traffic scenarios
## Troubleshooting
### Common Issues
**Service won't start**: Check if the PostgreSQL database is healthy
```bash
docker logs root_db
```
**Database connection errors**: Verify database credentials and network connectivity
```bash
docker exec nocodb nc_data nc
```
**Performance issues**: Monitor resource usage and optimize queries
```bash
docker stats nocodb root_db
```
## Official Documentation
For comprehensive guides and advanced features:
- [NocoDB Documentation](https://docs.nocodb.com/)
- [GitHub Repository](https://github.com/nocodb/nocodb)
- [Community Forum](https://community.nocodb.com/)

Some files were not shown because too many files have changed in this diff Show More