362 lines
11 KiB
Bash
362 lines
11 KiB
Bash
#!/bin/bash
|
|
|
|
# Exit on critical errors, continue for non-critical
|
|
set -e
|
|
|
|
# Define directories and log file
|
|
SETUP_DIR="/srv/Files/Notesnook/setup"
|
|
DB_DIR="/srv/Files/Notesnook/db"
|
|
S3_DIR="/srv/Files/Notesnook/s3"
|
|
LOG_FILE="$SETUP_DIR/setup.log"
|
|
|
|
# Create log file
|
|
mkdir -p "$SETUP_DIR"
|
|
touch "$LOG_FILE"
|
|
chmod 600 "$LOG_FILE"
|
|
|
|
# Function to log messages
|
|
log() {
|
|
echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" >> "$LOG_FILE"
|
|
echo "$1"
|
|
}
|
|
|
|
# Default values
|
|
BASE_DOMAIN="example.com"
|
|
INSTANCE_NAME="Notesnook"
|
|
DISABLE_SIGNUPS="false"
|
|
SMTP_HOST="smtp.gmail.com"
|
|
SMTP_PORT="587"
|
|
SMTP_USERNAME="your_email@gmail.com"
|
|
SMTP_PASSWORD="your_app_specific_password"
|
|
|
|
# Detect local IP
|
|
log "Detecting local IP..."
|
|
LOCAL_IP=$(ip addr show | grep -oP 'inet \K[\d.]+(?=/.*scope global)' | head -1 || echo "192.168.1.100")
|
|
if [ "$LOCAL_IP" = "192.168.1.100" ]; then
|
|
log "Warning: Failed to detect local IP, defaulting to 192.168.1.100"
|
|
fi
|
|
log "Detected local IP: ${LOCAL_IP}"
|
|
|
|
# Prompt for user input
|
|
read -p "Enter your domain (e.g., example.com): " BASE_DOMAIN
|
|
read -p "Enter instance name [${INSTANCE_NAME}]: " input_instance
|
|
INSTANCE_NAME=${input_instance:-$INSTANCE_NAME}
|
|
read -p "Disable signups? (true/false) [${DISABLE_SIGNUPS}]: " input_signups
|
|
DISABLE_SIGNUPS=${input_signups:-$DISABLE_SIGNUPS}
|
|
read -p "Enter Gmail SMTP username [${SMTP_USERNAME}]: " input_smtp_username
|
|
SMTP_USERNAME=${input_smtp_username:-$SMTP_USERNAME}
|
|
read -p "Enter Gmail app-specific password: " SMTP_PASSWORD
|
|
|
|
# Generate random secrets
|
|
MINIO_ROOT_PASSWORD=$(openssl rand -base64 12)
|
|
NOTESNOOK_API_SECRET=$(openssl rand -base64 32)
|
|
SERVICE_DISCOVERY_TOKEN=$(openssl rand -base64 32)
|
|
|
|
# Install dependencies
|
|
log "Installing dependencies..."
|
|
if ! apt update >> "$LOG_FILE" 2>&1; then
|
|
log "Warning: Failed to update package lists, continuing..."
|
|
fi
|
|
for pkg in podman python3-pip dos2unix; do
|
|
if ! dpkg -l "$pkg" &> /dev/null; then
|
|
log "Installing $pkg..."
|
|
if ! apt install -y "$pkg" >> "$LOG_FILE" 2>&1; then
|
|
log "Warning: Failed to install $pkg, continuing..."
|
|
fi
|
|
else
|
|
log "$pkg already installed"
|
|
fi
|
|
done
|
|
if ! pip3 install --upgrade podman-compose >> "$LOG_FILE" 2>&1; then
|
|
log "Warning: Failed to upgrade podman-compose, trying git install..."
|
|
pip3 install git+https://github.com/containers/podman-compose.git >> "$LOG_FILE" 2>&1 || log "Warning: Failed to install podman-compose, continuing..."
|
|
fi
|
|
|
|
# Fix registries.conf
|
|
log "Checking /etc/containers/registries.conf..."
|
|
if ! podman info --debug &>> "$LOG_FILE"; then
|
|
log "Fixing registries.conf due to parsing error..."
|
|
sudo mv /etc/containers/registries.conf /etc/containers/registries.conf.bak 2>> "$LOG_FILE" || true
|
|
sudo bash -c 'cat > /etc/containers/registries.conf << EOF
|
|
[registries.search]
|
|
registries = ["docker.io", "quay.io"]
|
|
|
|
[registries.insecure]
|
|
registries = []
|
|
|
|
[registries.block]
|
|
registries = []
|
|
EOF' || { log "Error: Failed to create registries.conf"; exit 1; }
|
|
if ! podman info --debug &>> "$LOG_FILE"; then
|
|
log "Error: Failed to fix registries.conf"
|
|
exit 1
|
|
fi
|
|
log "registries.conf fixed"
|
|
fi
|
|
|
|
# Create directories
|
|
log "Creating directories..."
|
|
mkdir -p "$SETUP_DIR" "$DB_DIR" "$S3_DIR" || log "Warning: Failed to create directories, continuing..."
|
|
chmod 700 "$DB_DIR" "$S3_DIR" 2>> "$LOG_FILE" || log "Warning: Failed to set directory permissions, continuing..."
|
|
|
|
# Create .env file
|
|
log "Generating .env file..."
|
|
cat > "$SETUP_DIR/.env" << EOF
|
|
MINIO_ROOT_PASSWORD=${MINIO_ROOT_PASSWORD}
|
|
NOTESNOOK_API_SECRET=${NOTESNOOK_API_SECRET}
|
|
SERVICE_DISCOVERY_TOKEN=${SERVICE_DISCOVERY_TOKEN}
|
|
SERVICE_DISCOVERY_URL=https://syncnotesnook.${BASE_DOMAIN}:5264
|
|
AUTH_SERVER_PUBLIC_URL=https://authnotesnook.${BASE_DOMAIN}:8264
|
|
NOTESNOOK_APP_PUBLIC_URL=https://syncnotesnook.${BASE_DOMAIN}:5264
|
|
EVENTS_SERVER_URL=https://eventsnotesnook.${BASE_DOMAIN}:7264
|
|
ATTACHMENTS_SERVER_PUBLIC_URL=https://s3notesnook.${BASE_DOMAIN}:9001
|
|
MONOGRAPH_PUBLIC_URL=https://monographnotesnook.${BASE_DOMAIN}:3000
|
|
BASE_DOMAIN=${BASE_DOMAIN}
|
|
LOCAL_IP=${LOCAL_IP}
|
|
SMTP_HOST=${SMTP_HOST}
|
|
SMTP_PORT=${SMTP_PORT}
|
|
SMTP_USERNAME=${SMTP_USERNAME}
|
|
SMTP_PASSWORD=${SMTP_PASSWORD}
|
|
DISABLE_SIGNUPS=${DISABLE_SIGNUPS}
|
|
INSTANCE_NAME=${INSTANCE_NAME}
|
|
NOTESNOOK_IDENTITY_IMAGE=streetwriters/identity:latest
|
|
NOTESNOOK_SYNC_IMAGE=streetwriters/notesnook-sync:latest
|
|
NOTESNOOK_SSE_IMAGE=streetwriters/sse:latest
|
|
NOTESNOOK_MONOGRAPH_IMAGE=streetwriters/monograph:latest
|
|
EOF
|
|
chmod 600 "$SETUP_DIR/.env" 2>> "$LOG_FILE" || log "Warning: Failed to set .env permissions, continuing..."
|
|
|
|
# Create docker-compose.yml
|
|
log "Generating docker-compose.yml..."
|
|
cat > "$SETUP_DIR/docker-compose.yml" << EOF
|
|
version: '3.8'
|
|
|
|
services:
|
|
validate:
|
|
image: vandot/alpine-bash
|
|
container_name: validate
|
|
entrypoint: /bin/bash
|
|
environment:
|
|
- INSTANCE_NAME=\${INSTANCE_NAME}
|
|
- NOTESNOOK_API_SECRET=\${NOTESNOOK_API_SECRET}
|
|
- DISABLE_SIGNUPS=\${DISABLE_SIGNUPS}
|
|
- SMTP_USERNAME=\${SMTP_USERNAME}
|
|
- SMTP_PASSWORD=\${SMTP_PASSWORD}
|
|
- SMTP_HOST=\${SMTP_HOST}
|
|
- SMTP_PORT=\${SMTP_PORT}
|
|
- AUTH_SERVER_PUBLIC_URL=\${AUTH_SERVER_PUBLIC_URL}
|
|
- NOTESNOOK_APP_PUBLIC_URL=\${NOTESNOOK_APP_PUBLIC_URL}
|
|
- MONOGRAPH_PUBLIC_URL=\${MONOGRAPH_PUBLIC_URL}
|
|
- ATTACHMENTS_SERVER_PUBLIC_URL=\${ATTACHMENTS_SERVER_PUBLIC_URL}
|
|
command:
|
|
- -c
|
|
- |
|
|
required_vars=(
|
|
"INSTANCE_NAME"
|
|
"NOTESNOOK_API_SECRET"
|
|
"DISABLE_SIGNUPS"
|
|
"SMTP_USERNAME"
|
|
"SMTP_PASSWORD"
|
|
"SMTP_HOST"
|
|
"SMTP_PORT"
|
|
"AUTH_SERVER_PUBLIC_URL"
|
|
"NOTESNOOK_APP_PUBLIC_URL"
|
|
"MONOGRAPH_PUBLIC_URL"
|
|
"ATTACHMENTS_SERVER_PUBLIC_URL"
|
|
)
|
|
for var in "\${required_vars[@]}"; do
|
|
if [ -z "\${!var}" ]; then
|
|
echo "Error: Required environment variable \$var is not set."
|
|
exit 1
|
|
fi
|
|
done
|
|
echo "All required environment variables are set."
|
|
networks:
|
|
- notesnook
|
|
restart: "no"
|
|
|
|
notesnook-db:
|
|
image: mongo:7.0.12
|
|
container_name: notesnook-db
|
|
volumes:
|
|
- /srv/Files/Notesnook/db:/data/db
|
|
- /srv/Files/Notesnook/db:/data/configdb
|
|
networks:
|
|
- notesnook
|
|
command: --replSet rs0 --bind_ip_all
|
|
depends_on:
|
|
validate:
|
|
condition: service_completed_successfully
|
|
healthcheck:
|
|
test: echo 'db.runCommand("ping").ok' | mongosh mongodb://localhost:27017 --quiet
|
|
interval: 40s
|
|
timeout: 30s
|
|
retries: 3
|
|
start_period: 60s
|
|
restart: unless-stopped
|
|
|
|
initiate-rs0:
|
|
image: mongo:7.0.12
|
|
container_name: initiate-rs0
|
|
networks:
|
|
- notesnook
|
|
depends_on:
|
|
notesnook-db:
|
|
condition: service_healthy
|
|
entrypoint: /bin/sh
|
|
command: -c "mongosh mongodb://notesnook-db:27017 <<EOF\nrs.initiate();\nrs.status();\nEOF"
|
|
restart: "no"
|
|
|
|
minio:
|
|
image: minio/minio:RELEASE.2024-07-29T22-14-52Z
|
|
container_name: minio
|
|
environment:
|
|
- MINIO_ROOT_USER=admin
|
|
- MINIO_ROOT_PASSWORD=\${MINIO_ROOT_PASSWORD}
|
|
- MINIO_BROWSER=on
|
|
command: server /data/s3 --console-address ":9001"
|
|
volumes:
|
|
- /srv/Files/Notesnook/s3:/data/s3
|
|
ports:
|
|
- "\${LOCAL_IP}:9001:9001"
|
|
- "\${LOCAL_IP}:9000:9000"
|
|
networks:
|
|
- notesnook
|
|
healthcheck:
|
|
test: timeout 5s bash -c ':> /dev/tcp/127.0.0.1/9001' || exit 1
|
|
interval: 40s
|
|
timeout: 30s
|
|
retries: 3
|
|
start_period: 60s
|
|
restart: unless-stopped
|
|
|
|
setup-s3:
|
|
image: minio/mc:RELEASE.2024-07-26T13-08-44Z
|
|
container_name: setup-s3
|
|
depends_on:
|
|
- minio
|
|
networks:
|
|
- notesnook
|
|
entrypoint: /bin/bash
|
|
environment:
|
|
- MINIO_ROOT_USER=admin
|
|
- MINIO_ROOT_PASSWORD=\${MINIO_ROOT_PASSWORD}
|
|
command: -c "until mc alias set minio http://minio:9000 \${MINIO_ROOT_USER} \${MINIO_ROOT_PASSWORD}; do sleep 1; done; mc mb minio/attachments -p"
|
|
restart: "no"
|
|
|
|
identity-server:
|
|
image: \${NOTESNOOK_IDENTITY_IMAGE}
|
|
container_name: identity-server
|
|
environment:
|
|
- NOTESNOOK_SERVER_PORT=5264
|
|
- NOTESNOOK_SERVER_HOST=notesnook-server
|
|
- IDENTITY_SERVER_PORT=8264
|
|
- IDENTITY_SERVER_HOST=identity-server
|
|
- SSE_SERVER_PORT=7264
|
|
- SSE_SERVER_HOST=sse-server
|
|
- SELF_HOSTED=1
|
|
- IDENTITY_SERVER_URL=\${AUTH_SERVER_PUBLIC_URL}
|
|
- NOTESNOOK_APP_HOST=\${NOTESNOOK_APP_PUBLIC_URL}
|
|
- NOTESNOOK_API_SECRET=\${NOTESNOOK_API_SECRET}
|
|
- MONGODB_CONNECTION_STRING=mongodb://notesnook-db:27017/identity?replSet=rs0
|
|
- MONGODB_DATABASE_NAME=identity
|
|
- SMTP_HOST=\${SMTP_HOST}
|
|
- SMTP_PORT=\${SMTP_PORT}
|
|
- SMTP_USERNAME=\${SMTP_USERNAME}
|
|
- SMTP_PASSWORD=\${SMTP_PASSWORD}
|
|
- DISABLE_SIGNUPS=\${DISABLE_SIGNUPS}
|
|
- INSTANCE_NAME=\${INSTANCE_NAME}
|
|
ports:
|
|
- "\${LOCAL_IP}:8264:8264"
|
|
networks:
|
|
- notesnook
|
|
depends_on:
|
|
- notesnook-db
|
|
healthcheck:
|
|
test: wget --tries=1 -nv -q http://localhost:8264/health -O- || exit 1
|
|
interval: 40s
|
|
timeout: 30s
|
|
retries: 3
|
|
start_period: 60s
|
|
restart: unless-stopped
|
|
|
|
notesnook-sync:
|
|
image: \${NOTESNOOK_SYNC_IMAGE}
|
|
container_name: notesnook-sync
|
|
environment:
|
|
- NOTESNOOK_SERVER_PORT=5264
|
|
- NOTESNOOK_SERVER_HOST=notesnook-server
|
|
- IDENTITY_SERVER_PORT=8264
|
|
- IDENTITY_SERVER_HOST=identity-server
|
|
- SSE_SERVER_PORT=7264
|
|
- SSE_SERVER_HOST=sse-server
|
|
- SELF_HOSTED=1
|
|
- IDENTITY_SERVER_URL=\${AUTH_SERVER_PUBLIC_URL}
|
|
- NOTESNOOK_APP_HOST=\${NOTESNOOK_APP_PUBLIC_URL}
|
|
- NOTESNOOK_API_SECRET=\${NOTESNOOK_API_SECRET}
|
|
- MONGODB_CONNECTION_STRING=mongodb://notesnook-db:27017/?replSet=rs0
|
|
- MONGODB_DATABASE_NAME=notesnook
|
|
- S3_INTERNAL_SERVICE_URL=http://minio:9000/
|
|
- S3_INTERNAL_BUCKET_NAME=attachments
|
|
- S3_ACCESS_KEY_ID=admin
|
|
- S3_ACCESS_KEY=\${MINIO_ROOT_PASSWORD}
|
|
- S3_SERVICE_URL=\${ATTACHMENTS_SERVER_PUBLIC_URL}
|
|
- S3_REGION=us-east-1
|
|
- S3_BUCKET_NAME=attachments
|
|
ports:
|
|
- "\${LOCAL_IP}:5264:5264"
|
|
networks:
|
|
- notesnook
|
|
depends_on:
|
|
- minio
|
|
- setup-s3
|
|
- identity-server
|
|
healthcheck:
|
|
test: wget --tries=1 -nv -q http://localhost:5264/health -O- || exit 1
|
|
interval: 40s
|
|
timeout: 30s
|
|
retries: 3
|
|
start_period: 60s
|
|
restart: unless-stopped
|
|
|
|
sse-server:
|
|
image: \${NOTESNOOK_SSE_IMAGE}
|
|
container_name: sse-server
|
|
environment:
|
|
- NOTESNOOK_SERVER_PORT=5264
|
|
- NOTESNOOK_SERVER_HOST=notesnook-server
|
|
- IDENTITY_SERVER_PORT=8264
|
|
- IDENTITY_SERVER_HOST=identity-server
|
|
- SSE_SERVER_PORT=7264
|
|
- SSE_SERVER_HOST=sse-server
|
|
- SELF_HOSTED=1
|
|
- IDENTITY_SERVER_URL=\${AUTH_SERVER_PUBLIC_URL}
|
|
- NOTESNOOK_APP_HOST=\${NOTESNOOK_APP_PUBLIC_URL}
|
|
- NOTESNOOK_API_SECRET=\${NOTESNOOK_API_SECRET}
|
|
ports:
|
|
- "\${LOCAL_IP}:7264:7264"
|
|
networks:
|
|
- notesnook
|
|
depends_on:
|
|
- identity-server
|
|
- notesnook-sync
|
|
healthcheck:
|
|
test: wget --tries=1 -nv -q http://localhost:7264/health -O- || exit 1
|
|
interval: 40s
|
|
timeout: 30s
|
|
retries: 3
|
|
start_period: 60s
|
|
restart: unless-stopped
|
|
|
|
monograph:
|
|
image: \${NOTESNOOK_MONOGRAPH_IMAGE}
|
|
container_name: monograph
|
|
environment:
|
|
- NOTESNOOK_SERVER_PORT=5264
|
|
- NOTESNOOK_SERVER_HOST=notesnook-server
|
|
- IDENTITY_SERVER_PORT=8264
|
|
- IDENTITY_SERVER_HOST=identity-server
|
|
- SSE_SERVER_PORT=7264
|
|
- SSE_SERVER_HOST=sse-server
|
|
- SELF_HOSTED=1
|
|
- |