initial commit
8
.gitignore
vendored
Normal 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
@ -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
@ -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
@ -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
@ -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
|
||||||
0
configs/code-server/.config/.gitkeep
Normal file
0
configs/code-server/.local/.gitkeep
Normal file
50
configs/homepage/bookmarks.yaml
Executable 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
0
configs/homepage/custom.js
Executable file
6
configs/homepage/docker.yaml
Executable file
@ -0,0 +1,6 @@
|
|||||||
|
---
|
||||||
|
# For configuration options and examples, please see:
|
||||||
|
# https://gethomepage.dev/configs/docker/
|
||||||
|
|
||||||
|
my-docker:
|
||||||
|
socket: /var/run/docker.sock
|
||||||
2
configs/homepage/kubernetes.yaml
Executable file
@ -0,0 +1,2 @@
|
|||||||
|
---
|
||||||
|
# sample kubernetes config
|
||||||
192
configs/homepage/logs/homepage.log
Normal 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)
|
||||||
78
configs/homepage/services.yaml
Normal 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
@ -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
|
||||||
23
configs/homepage/widgets.yaml
Normal 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
@ -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:
|
||||||
BIN
mkdocs/.cache/plugin/social/0ee943db87dfa39f1d8b8882384425da.png
Normal file
|
After Width: | Height: | Size: 30 KiB |
BIN
mkdocs/.cache/plugin/social/13b7450908684a452205d94a249e3e4d.png
Normal file
|
After Width: | Height: | Size: 33 KiB |
BIN
mkdocs/.cache/plugin/social/1ba54b15aedf0426dba781e37512dce1.png
Normal file
|
After Width: | Height: | Size: 28 KiB |
BIN
mkdocs/.cache/plugin/social/3a2fd3f826d2a906ed92c3970b25cb7d.png
Normal file
|
After Width: | Height: | Size: 34 KiB |
BIN
mkdocs/.cache/plugin/social/431ab4f4662987971222ad7fc4583df8.png
Normal file
|
After Width: | Height: | Size: 43 KiB |
BIN
mkdocs/.cache/plugin/social/668c246629c618cf956e7cea78d4037d.png
Normal file
|
After Width: | Height: | Size: 26 KiB |
BIN
mkdocs/.cache/plugin/social/721bd151e1ec0d1e48006634b8ff2e38.png
Normal file
|
After Width: | Height: | Size: 29 KiB |
BIN
mkdocs/.cache/plugin/social/740e1015f23d88c791e7cd6c726e1081.png
Normal file
|
After Width: | Height: | Size: 24 KiB |
BIN
mkdocs/.cache/plugin/social/83db91be2c8770ec6e0cad47805127ef.png
Normal file
|
After Width: | Height: | Size: 28 KiB |
BIN
mkdocs/.cache/plugin/social/96a422da08dcb28205d2e584a7c620ca.png
Normal file
|
After Width: | Height: | Size: 31 KiB |
BIN
mkdocs/.cache/plugin/social/9fdd03d6602a201cef87a201f27fc715.png
Normal file
|
After Width: | Height: | Size: 31 KiB |
BIN
mkdocs/.cache/plugin/social/a5775bbacaf158405defcb68416ea8bd.png
Normal file
|
After Width: | Height: | Size: 27 KiB |
BIN
mkdocs/.cache/plugin/social/aa0707be07fb7b02ab3372711d954d83.png
Normal file
|
After Width: | Height: | Size: 28 KiB |
BIN
mkdocs/.cache/plugin/social/af754735b566f6d264e3f21b80a2d139.png
Normal file
|
After Width: | Height: | Size: 32 KiB |
BIN
mkdocs/.cache/plugin/social/ca7a35746e5b24c6195659a5ce3f5a0d.png
Normal file
|
After Width: | Height: | Size: 26 KiB |
BIN
mkdocs/.cache/plugin/social/d988b15f28c148e32971e4f12f707389.png
Normal file
|
After Width: | Height: | Size: 33 KiB |
BIN
mkdocs/.cache/plugin/social/fb97f0bfe74bea4659ea90c0a851c2ec.png
Normal file
|
After Width: | Height: | Size: 34 KiB |
BIN
mkdocs/.cache/plugin/social/fonts/Roboto/Black Italic.ttf
Normal file
BIN
mkdocs/.cache/plugin/social/fonts/Roboto/Black.ttf
Normal file
BIN
mkdocs/.cache/plugin/social/fonts/Roboto/Bold Italic.ttf
Normal file
BIN
mkdocs/.cache/plugin/social/fonts/Roboto/Bold.ttf
Normal file
BIN
mkdocs/.cache/plugin/social/fonts/Roboto/Condensed Black.ttf
Normal file
BIN
mkdocs/.cache/plugin/social/fonts/Roboto/Condensed Bold.ttf
Normal file
BIN
mkdocs/.cache/plugin/social/fonts/Roboto/Condensed ExtraBold.ttf
Normal file
BIN
mkdocs/.cache/plugin/social/fonts/Roboto/Condensed Italic.ttf
Normal file
BIN
mkdocs/.cache/plugin/social/fonts/Roboto/Condensed Light.ttf
Normal file
BIN
mkdocs/.cache/plugin/social/fonts/Roboto/Condensed Medium.ttf
Normal file
BIN
mkdocs/.cache/plugin/social/fonts/Roboto/Condensed Regular.ttf
Normal file
BIN
mkdocs/.cache/plugin/social/fonts/Roboto/Condensed SemiBold.ttf
Normal file
BIN
mkdocs/.cache/plugin/social/fonts/Roboto/Condensed Thin.ttf
Normal file
BIN
mkdocs/.cache/plugin/social/fonts/Roboto/ExtraBold Italic.ttf
Normal file
BIN
mkdocs/.cache/plugin/social/fonts/Roboto/ExtraBold.ttf
Normal file
BIN
mkdocs/.cache/plugin/social/fonts/Roboto/ExtraLight Italic.ttf
Normal file
BIN
mkdocs/.cache/plugin/social/fonts/Roboto/ExtraLight.ttf
Normal file
BIN
mkdocs/.cache/plugin/social/fonts/Roboto/Italic.ttf
Normal file
BIN
mkdocs/.cache/plugin/social/fonts/Roboto/Light Italic.ttf
Normal file
BIN
mkdocs/.cache/plugin/social/fonts/Roboto/Light.ttf
Normal file
BIN
mkdocs/.cache/plugin/social/fonts/Roboto/Medium Italic.ttf
Normal file
BIN
mkdocs/.cache/plugin/social/fonts/Roboto/Medium.ttf
Normal file
BIN
mkdocs/.cache/plugin/social/fonts/Roboto/Regular.ttf
Normal file
BIN
mkdocs/.cache/plugin/social/fonts/Roboto/SemiBold Italic.ttf
Normal file
BIN
mkdocs/.cache/plugin/social/fonts/Roboto/SemiBold.ttf
Normal file
BIN
mkdocs/.cache/plugin/social/fonts/Roboto/SemiCondensed Black.ttf
Normal file
BIN
mkdocs/.cache/plugin/social/fonts/Roboto/SemiCondensed Bold.ttf
Normal file
BIN
mkdocs/.cache/plugin/social/fonts/Roboto/SemiCondensed Light.ttf
Normal file
BIN
mkdocs/.cache/plugin/social/fonts/Roboto/SemiCondensed Thin.ttf
Normal file
BIN
mkdocs/.cache/plugin/social/fonts/Roboto/Thin Italic.ttf
Normal file
BIN
mkdocs/.cache/plugin/social/fonts/Roboto/Thin.ttf
Normal file
0
mkdocs/docs/blog/index.md
Normal file
231
mkdocs/docs/getting-started.md
Normal 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
@ -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
|
||||||
0
mkdocs/docs/overrides/home.html
Normal file
9
mkdocs/docs/overrides/main.html
Normal 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 %}
|
||||||
59
mkdocs/docs/services/code-server.md
Normal 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).
|
||||||
199
mkdocs/docs/services/homepage.md
Normal 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/)
|
||||||
175
mkdocs/docs/services/index.md
Normal 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
|
||||||
66
mkdocs/docs/services/listmonk.md
Normal 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)
|
||||||
124
mkdocs/docs/services/mkdocs.md
Normal 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
@ -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)
|
||||||
153
mkdocs/docs/services/nocodb.md
Normal 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/)
|
||||||