Add Notesnook-install.sh
bash -c "$(curl -fsSL )"
This commit is contained in:
383
Notesnook-install.sh
Normal file
383
Notesnook-install.sh
Normal 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"
|
||||
```
|
||||
Reference in New Issue
Block a user