#!/bin/bash # Nextcloud Docker Installation Script # This script automates the installation of Nextcloud with Docker Compose set -e # Exit on any error # Color codes for output RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' NC='\033[0m' # No Color # Configuration variables NAS_IP="192.168.107.90" NAS_SHARE="Data/backup/Nextcloud" NAS_USERNAME="Abomination1" NAS_PASSWORD="biker111" MOUNT_POINT="/mnt/nextcloud" INSTALL_DIR="$(pwd)" echo -e "${GREEN}=== Nextcloud Docker Installation ===${NC}" echo "" # Check if running as root if [ "$EUID" -ne 0 ]; then echo -e "${RED}Please run as root (use sudo)${NC}" exit 1 fi # Prompt for domain read -p "Enter your Nextcloud domain (e.g., nextcloud.rozic-dev.com): " DOMAIN if [ -z "$DOMAIN" ]; then echo -e "${RED}Domain cannot be empty!${NC}" exit 1 fi # Prompt for admin credentials read -p "Enter admin username [admin]: " ADMIN_USER ADMIN_USER=${ADMIN_USER:-admin} read -sp "Enter admin password: " ADMIN_PASS echo "" if [ -z "$ADMIN_PASS" ]; then echo -e "${RED}Password cannot be empty!${NC}" exit 1 fi # Prompt for NAS configuration read -p "Use NAS storage? (y/n) [y]: " USE_NAS USE_NAS=${USE_NAS:-y} if [[ "$USE_NAS" =~ ^[Yy]$ ]]; then read -p "NAS IP address [$NAS_IP]: " INPUT_NAS_IP NAS_IP=${INPUT_NAS_IP:-$NAS_IP} read -p "NAS Share path [$NAS_SHARE]: " INPUT_NAS_SHARE NAS_SHARE=${INPUT_NAS_SHARE:-$NAS_SHARE} read -p "NAS Username [$NAS_USERNAME]: " INPUT_NAS_USER NAS_USERNAME=${INPUT_NAS_USER:-$NAS_USERNAME} read -sp "NAS Password: " INPUT_NAS_PASS echo "" NAS_PASSWORD=${INPUT_NAS_PASS:-$NAS_PASSWORD} DATA_PATH="$MOUNT_POINT" else DATA_PATH="/mnt/nextcloud/data" fi echo "" echo -e "${YELLOW}=== Installation Summary ===${NC}" echo "Domain: $DOMAIN" echo "Admin User: $ADMIN_USER" echo "Data Path: $DATA_PATH" if [[ "$USE_NAS" =~ ^[Yy]$ ]]; then echo "NAS: //$NAS_IP/$NAS_SHARE" fi echo "" read -p "Continue with installation? (y/n): " CONFIRM if [[ ! "$CONFIRM" =~ ^[Yy]$ ]]; then echo "Installation cancelled." exit 0 fi echo "" echo -e "${GREEN}[1/7] Installing required packages...${NC}" apt-get update -qq apt-get install -y cifs-utils docker.io docker-compose -qq echo -e "${GREEN}[2/7] Creating directories...${NC}" mkdir -p "$MOUNT_POINT" mkdir -p "$DATA_PATH" if [[ "$USE_NAS" =~ ^[Yy]$ ]]; then echo -e "${GREEN}[3/7] Mounting NAS storage...${NC}" # Test mount first if mount -t cifs "//$NAS_IP/$NAS_SHARE" "$MOUNT_POINT" \ -o username="$NAS_USERNAME",password="$NAS_PASSWORD",vers=3.0,uid=33,gid=33,file_mode=0770,dir_mode=0770,noperm,iocharset=utf8 2>/dev/null; then echo -e "${GREEN}NAS mounted successfully at $MOUNT_POINT${NC}" # Add to fstab if not already present FSTAB_ENTRY="//$NAS_IP/$NAS_SHARE $MOUNT_POINT cifs username=$NAS_USERNAME,password=$NAS_PASSWORD,vers=3.0,uid=33,gid=33,file_mode=0770,dir_mode=0770,noperm,iocharset=utf8,_netdev,nofail 0 0" if ! grep -q "$MOUNT_POINT" /etc/fstab; then echo -e "${YELLOW}Adding NAS mount to /etc/fstab...${NC}" echo "# Nextcloud NAS storage" >> /etc/fstab echo "$FSTAB_ENTRY" >> /etc/fstab echo -e "${GREEN}Added to /etc/fstab for auto-mount on boot${NC}" else echo -e "${YELLOW}Mount already exists in /etc/fstab${NC}" fi else echo -e "${RED}Failed to mount NAS! Please check credentials and network.${NC}" exit 1 fi else echo -e "${GREEN}[3/7] Skipping NAS mount (using local storage)...${NC}" fi echo -e "${GREEN}[4/7] Setting permissions...${NC}" chown -R 33:33 "$DATA_PATH" chmod -R 750 "$DATA_PATH" echo -e "${GREEN}[5/7] Creating .env file...${NC}" cat > "$INSTALL_DIR/.env" < "$INSTALL_DIR/docker-compose.yml" <<'EOF' volumes: mysql: driver: local redis: driver: local nextcloud: driver: local networks: traefik: external: true name: traefik_default internal: driver: bridge services: nextcloud: image: nextcloud:latest container_name: nextcloud_server restart: unless-stopped depends_on: - mariadb - redis networks: - traefik - internal environment: MYSQL_HOST: mariadb MYSQL_DATABASE: nextcloud MYSQL_USER: nextcloud MYSQL_PASSWORD: nextcloud REDIS_HOST: redis REDIS_HOST_PASSWORD: nextcloud NEXTCLOUD_ADMIN_USER: ${ADMIN_USERNAME} NEXTCLOUD_ADMIN_PASSWORD: ${ADMIN_PASSWORD} NEXTCLOUD_TRUSTED_DOMAINS: ${NEXTCLOUD_DOMAIN} OVERWRITEPROTOCOL: https OVERWRITEHOST: ${NEXTCLOUD_DOMAIN} OVERWRITECLIURL: https://${NEXTCLOUD_DOMAIN} TRUSTED_PROXIES: 172.16.0.0/12 volumes: - nextcloud:/var/www/html - DATA_PATH_PLACEHOLDER:/var/www/html/data labels: - "traefik.enable=true" - "traefik.docker.network=traefik_default" # HTTP → HTTPS redirect - "traefik.http.routers.nextcloud.entrypoints=web" - "traefik.http.routers.nextcloud.rule=Host(`${NEXTCLOUD_DOMAIN}`)" - "traefik.http.routers.nextcloud.middlewares=nextcloud-https-redirect" - "traefik.http.middlewares.nextcloud-https-redirect.redirectscheme.scheme=https" - "traefik.http.middlewares.nextcloud-https-redirect.redirectscheme.permanent=true" # HTTPS Router - "traefik.http.routers.nextcloud-secure.entrypoints=websecure" - "traefik.http.routers.nextcloud-secure.rule=Host(`${NEXTCLOUD_DOMAIN}`)" - "traefik.http.routers.nextcloud-secure.tls=true" - "traefik.http.routers.nextcloud-secure.tls.certresolver=letsencrypt" - "traefik.http.routers.nextcloud-secure.service=nextcloud" - "traefik.http.routers.nextcloud-secure.middlewares=nextcloud-headers" # Nextcloud-specific security headers - "traefik.http.middlewares.nextcloud-headers.headers.customFrameOptionsValue=SAMEORIGIN" - "traefik.http.middlewares.nextcloud-headers.headers.customResponseHeaders.Strict-Transport-Security=max-age=15552000; includeSubDomains" # Internal port inside container - "traefik.http.services.nextcloud.loadbalancer.server.port=80" mariadb: image: mariadb:10.11 container_name: nextcloud_mariadb restart: unless-stopped networks: - internal environment: MYSQL_ROOT_PASSWORD: nextcloud MYSQL_USER: nextcloud MYSQL_PASSWORD: nextcloud MYSQL_DATABASE: nextcloud MARIADB_AUTO_UPGRADE: 1 command: - "--max-allowed-packet=128M" - "--innodb-log-file-size=64M" - "--transaction-isolation=READ-COMMITTED" - "--binlog-format=ROW" - "--innodb-file-per-table=1" - "--skip-innodb-read-only-compressed" healthcheck: test: ["CMD", "mysqladmin", "ping", "-u", "root", "--password=nextcloud"] interval: 10s timeout: 5s retries: 5 volumes: - mysql:/var/lib/mysql redis: image: redis:6-alpine container_name: nextcloud_redis restart: unless-stopped networks: - internal command: ["redis-server", "--requirepass", "nextcloud"] healthcheck: test: ["CMD", "redis-cli", "ping"] interval: 10s timeout: 5s retries: 5 volumes: - redis:/data EOF # Replace placeholder with actual data path sed -i "s|DATA_PATH_PLACEHOLDER|$DATA_PATH|g" "$INSTALL_DIR/docker-compose.yml" echo -e "${GREEN}[7/7] Starting Nextcloud...${NC}" cd "$INSTALL_DIR" docker-compose down 2>/dev/null || true docker-compose up -d echo "" echo -e "${GREEN}=== Installation Complete! ===${NC}" echo "" echo -e "Nextcloud is starting up. This may take 1-2 minutes." echo "" echo -e "Access your Nextcloud instance at: ${GREEN}https://$DOMAIN${NC}" echo -e "Admin username: ${GREEN}$ADMIN_USER${NC}" echo "" echo "To view logs, run:" echo -e " ${YELLOW}docker-compose logs -f nextcloud${NC}" echo "" echo "To check status, run:" echo -e " ${YELLOW}docker-compose ps${NC}" echo "" # Wait a moment and show initial logs echo -e "${YELLOW}Showing initial startup logs (Ctrl+C to exit):${NC}" sleep 3 docker-compose logs -f nextcloud