Add Notesnook-install.sh

bash -c "$(curl -fsSL )"
This commit is contained in:
maq
2025-08-23 12:40:06 -07:00
commit 37da2c11dc

383
Notesnook-install.sh Normal file
View File

@@ -0,0 +1,383 @@
```bash
#!/bin/bash
# Notesnook Sync Server Deployment Script
# Run this in your Proxmox LXC container with Docker installed
# Exit on any error
set -e
# Configuration variables
INSTALL_DIR="/srv/notesnook"
DOMAIN=""
ACME_EMAIL=""
MINIO_ROOT_USER=""
MINIO_ROOT_PASSWORD=""
SERVICE_DISCOVERY_TOKEN=""
# Function to prompt for user input
prompt_for_input() {
read -p "Enter your domain (e.g., yourdomain.com): " DOMAIN
read -p "Enter your email for Let's Encrypt (e.g., your-email@example.com): " ACME_EMAIL
read -p "Enter MinIO root user: " MINIO_ROOT_USER
read -s -p "Enter MinIO root password: " MINIO_ROOT_PASSWORD
echo
read -s -p "Enter service discovery token: " SERVICE_DISCOVERY_TOKEN
echo
# Validate inputs
if [[ -z "$DOMAIN" || -z "$ACME_EMAIL" || -z "$MINIO_ROOT_USER" || -z "$MINIO_ROOT_PASSWORD" || -z "$SERVICE_DISCOVERY_TOKEN" ]]; then
echo "Error: All inputs are required."
exit 1
fi
}
# Function to create directories
create_directories() {
echo "Creating directories..."
mkdir -p "$INSTALL_DIR/traefik" "$INSTALL_DIR/certs"
chmod 600 "$INSTALL_DIR/certs/acme.json"
touch "$INSTALL_DIR/certs/acme.json"
}
# Function to create .env file
create_env_file() {
echo "Creating .env file..."
cat > "$INSTALL_DIR/.env" << EOF
ACME_EMAIL=$ACME_EMAIL
MINIO_ROOT_USER=$MINIO_ROOT_USER
MINIO_ROOT_PASSWORD=$MINIO_ROOT_PASSWORD
ATTACHMENTS_SERVER_PUBLIC_URL=https://s3.$DOMAIN
MONOGRAPH_PUBLIC_URL=https://monograph.$DOMAIN
SERVICE_DISCOVERY_URL=https://sse.$DOMAIN
SERVICE_DISCOVERY_TOKEN=$SERVICE_DISCOVERY_TOKEN
EOF
}
# Function to create Traefik configuration
create_traefik_config() {
echo "Creating Traefik configuration..."
cat > "$INSTALL_DIR/traefik/traefik.yml" << 'EOF'
global:
checkNewVersion: true
sendAnonymousUsage: false
log:
level: INFO
filePath: /etc/traefik/traefik.log
accessLog:
filePath: /etc/traefik/access.log
api:
dashboard: false
entryPoints:
websecure:
address: ":443"
providers:
docker:
exposedByDefault: false
network: notesnook
certificatesResolvers:
myresolver:
acme:
email: ${ACME_EMAIL}
storage: /certs/acme.json
tlsChallenge: {}
EOF
}
# Function to create Docker Compose file
create_docker_compose() {
echo "Creating docker-compose.yml..."
cat > "$INSTALL_DIR/docker-compose.yml" << EOF
version: '3.8'
x-common-env: &env-files
- .env
x-server-discovery: &server-discovery
SERVICE_DISCOVERY_URL: "\${SERVICE_DISCOVERY_URL}"
SERVICE_DISCOVERY_TOKEN: "\${SERVICE_DISCOVERY_TOKEN}"
services:
traefik:
image: traefik:v3.1
networks:
- notesnook
ports:
- "443:443"
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- ./traefik:/etc/traefik
- ./certs:/certs
command:
- "--api.insecure=false"
- "--providers.docker=true"
- "--providers.docker.exposedbydefault=false"
- "--entrypoints.websecure.address=:443"
- "--certificatesresolvers.myresolver.acme.tlschallenge=true"
- "--certificatesresolvers.myresolver.acme.email=\${ACME_EMAIL}"
- "--certificatesresolvers.myresolver.acme.storage=/certs/acme.json"
healthcheck:
test: ["CMD", "traefik", "healthcheck"]
interval: 30s
timeout: 10s
retries: 3
start_period: 20s
notesnook-db:
image: mongo:7.0
networks:
- notesnook
volumes:
- dbdata:/data/db
command: mongod --replSet rs0
healthcheck:
test: test \$\$(mongosh --quiet --eval "db.adminCommand('ping').ok") -eq 1
interval: 10s
timeout: 10s
retries: 3
start_period: 20s
init-replica:
image: mongo:7.0
depends_on:
- notesnook-db
networks:
- notesnook
command:
- /bin/bash
- -c
- |
until mongosh --host notesnook-db:27017 --eval 'rs.initiate()'; do
sleep 1;
done
healthcheck:
test: mongosh --host notesnook-db:27017 --eval 'rs.status()' || exit 1
interval: 10s
timeout: 10s
retries: 3
start_period: 20s
notesnook-s3:
image: minio/minio:RELEASE.2024-08-03T04-33-23Z
networks:
- notesnook
env_file: *env-files
command: server /data --console-address ":9009"
volumes:
- s3data:/data
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"]
interval: 30s
timeout: 20s
retries: 3
start_period: 20s
environment:
MINIO_ROOT_USER: "\${MINIO_ROOT_USER}"
MINIO_ROOT_PASSWORD: "\${MINIO_ROOT_PASSWORD}"
labels:
- "traefik.enable=true"
- "traefik.http.routers.minio-api.rule=Host(\`s3.$DOMAIN\`)"
- "traefik.http.routers.minio-api.entrypoints=websecure"
- "traefik.http.routers.minio-api.tls=true"
- "traefik.http.routers.minio-api.tls.certresolver=myresolver"
- "traefik.http.services.minio-api.loadbalancer.server.port=9000"
- "traefik.http.routers.minio-console.rule=Host(\`s3.$DOMAIN\`) && PathPrefix(\`/minio\`)"
- "traefik.http.routers.minio-console.entrypoints=websecure"
- "traefik.http.routers.minio-console.tls=true"
- "traefik.http.routers.minio-console.tls.certresolver=myresolver"
- "traefik.http.services.minio-console.loadbalancer.server.port=9009"
setup-s3:
image: minio/mc:RELEASE.2024-07-26T13-08-44Z
depends_on:
- notesnook-s3
networks:
- notesnook
entrypoint: /bin/bash
env_file: *env-files
command:
- -c
- |
until mc alias set minio http://notesnook-s3:9000 \${MINIO_ROOT_USER} \${MINIO_ROOT_PASSWORD}; do
sleep 1;
done;
mc mb minio/attachments -p
identity-server:
image: streetwriters/identity:latest
networks:
- notesnook
env_file: *env-files
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
environment:
<<: *server-discovery
MONGODB_CONNECTION_STRING: mongodb://notesnook-db:27017/identity?replSet=rs0
MONGODB_DATABASE_NAME: identity
labels:
- "traefik.enable=true"
- "traefik.http.routers.identity.rule=Host(\`identity.$DOMAIN\`)"
- "traefik.http.routers.identity.entrypoints=websecure"
- "traefik.http.routers.identity.tls=true"
- "traefik.http.routers.identity.tls.certresolver=myresolver"
- "traefik.http.services.identity.loadbalancer.server.port=8264"
notesnook-server:
image: streetwriters/notesnook-sync:latest
networks:
- notesnook
env_file: *env-files
depends_on:
- notesnook-s3
- 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
environment:
<<: *server-discovery
MONGODB_CONNECTION_STRING: mongodb://notesnook-db:27017/?replSet=rs0
MONGODB_DATABASE_NAME: notesnook
S3_INTERNAL_SERVICE_URL: "http://notesnook-s3:9000"
S3_INTERNAL_BUCKET_NAME: "attachments"
S3_ACCESS_KEY_ID: "\${MINIO_ROOT_USER}"
S3_ACCESS_KEY: "\${MINIO_ROOT_PASSWORD}"
S3_SERVICE_URL: "\${ATTACHMENTS_SERVER_PUBLIC_URL}"
S3_REGION: "us-east-1"
S3_BUCKET_NAME: "attachments"
labels:
- "traefik.enable=true"
- "traefik.http.routers.sync.rule=Host(\`sync.$DOMAIN\`)"
- "traefik.http.routers.sync.entrypoints=websecure"
- "traefik.http.routers.sync.tls=true"
- "traefik.http.routers.sync.tls.certresolver=myresolver"
- "traefik.http.services.sync.loadbalancer.server.port=5264"
sse-server:
image: streetwriters/sse:latest
networks:
- notesnook
env_file: *env-files
depends_on:
- identity-server
- notesnook-server
healthcheck:
test: wget --tries=1 -nv -q http://localhost:7264/health -O- || exit 1
interval: 40s
timeout: 30s
retries: 3
start_period: 60s
environment:
<<: *server-discovery
labels:
- "traefik.enable=true"
- "traefik.http.routers.sse.rule=Host(\`sse.$DOMAIN\`)"
- "traefik.http.routers.sse.entrypoints=websecure"
- "traefik.http.routers.sse.tls=true"
- "traefik.http.routers.sse.tls.certresolver=myresolver"
- "traefik.http.services.sse.loadbalancer.server.port=7264"
- "traefik.http.routers.sse.middlewares=sse-websocket"
- "traefik.http.middlewares.sse-websocket.headers.customrequestheaders.Upgrade=websocket"
- "traefik.http.middlewares.sse-websocket.headers.customrequestheaders.Connection=upgrade"
monograph-server:
image: streetwriters/monograph:latest
networks:
- notesnook
env_file: *env-files
depends_on:
- notesnook-server
healthcheck:
test: wget --tries=1 -nv -q http://localhost:3000/api/health -O- || exit 1
interval: 40s
timeout: 30s
retries: 3
start_period: 60s
environment:
<<: *server-discovery
API_HOST: http://notesnook-server:5264
PUBLIC_URL: "\${MONOGRAPH_PUBLIC_URL}"
labels:
- "traefik.enable=true"
- "traefik.http.routers.monograph.rule=Host(\`monograph.$DOMAIN\`)"
- "traefik.http.routers.monograph.entrypoints=websecure"
- "traefik.http.routers.monograph.tls=true"
- "traefik.http.routers.monograph.tls.certresolver=myresolver"
- "traefik.http.services.monograph.loadbalancer.server.port=3000"
autoheal:
image: willfarrell/autoheal:latest
tty: true
restart: always
environment:
- AUTOHEAL_INTERVAL=60
- AUTOHEAL_START_PERIOD=300
- AUTOHEAL_DEFAULT_STOP_TIMEOUT=10
volumes:
- /var/run/docker.sock:/var/run/docker.sock
networks:
notesnook:
driver: bridge
internal: true
volumes:
dbdata:
s3data:
EOF
}
# Function to deploy services
deploy_services() {
echo "Deploying services..."
cd "$INSTALL_DIR"
docker-compose pull
docker-compose up -d
}
# Function to verify deployment
verify_deployment() {
echo "Verifying deployment..."
sleep 10 # Wait for services to start
docker-compose ps
echo "Checking Traefik logs..."
docker-compose logs traefik | tail -n 20
}
# Main execution
echo "Starting Notesnook sync server deployment..."
# Prompt for input
prompt_for_input
# Create directories and files
create_directories
create_env_file
create_traefik_config
create_docker_compose
# Deploy services
deploy_services
# Verify deployment
verify_deployment
echo "Deployment completed!"
echo "Ensure DNS records for identity.$DOMAIN, sync.$DOMAIN, sse.$DOMAIN, monograph.$DOMAIN, and s3.$DOMAIN point to your server's public IP."
echo "Test access at https://identity.$DOMAIN/health and https://s3.$DOMAIN/minio"
```