/ apply-patches.sh
apply-patches.sh
1 #!/bin/bash 2 set -e 3 4 # Ensure we're in the correct directory 5 cd ~/fieldwork/fold-stack 6 7 # Ensure required commands are available 8 command -v docker >/dev/null 2>&1 || { echo "Docker is required but not installed. Aborting."; exit 1; } 9 command -v docker-compose >/dev/null 2>&1 || { echo "Docker Compose is required but not installed. Aborting."; exit 1; } 10 command -v git >/dev/null 2>&1 || { echo "Git is required but not installed. Aborting."; exit 1; } 11 12 # Step 1: Stop the current stack 13 echo "Stopping the current stack..." 14 ./scripts/down-dev.sh 15 16 # Step 2: Backup existing files 17 echo "Backing up existing files..." 18 [ -f docker-compose.dev.yml ] && cp docker-compose.dev.yml docker-compose.dev.yml.bak 19 [ -f nginx/dev/default.conf ] && cp nginx/dev/default.conf nginx/dev/default.conf.bak 20 [ -f scripts/up-dev.sh ] && cp scripts/up-dev.sh scripts/up-dev.sh.bak 21 [ -f scripts/rclone-sync.sh ] && cp scripts/rclone-sync.sh scripts/rclone-sync.sh.bak 22 23 # Step 3: Fix Flame Dashboard 24 echo "Fixing Flame Dashboard..." 25 # Clear Flame volume to start fresh 26 docker compose -f docker-compose.dev.yml rm -f flame_dashboard 27 rm -rf ./volumes/flame/* 28 mkdir -p ./volumes/flame 29 sudo chown -R 1000:1000 ./volumes/flame 30 sudo chmod -R 775 ./volumes/flame 31 # Commit changes 32 git add . 33 git commit -m "Fix Flame Dashboard: Clear volume and update docker-compose.dev.yml" 34 35 # Step 4: Update docker-compose.dev.yml 36 echo "Updating docker-compose.dev.yml..." 37 cat > docker-compose.dev.yml << 'EOF' 38 services: 39 ghost: 40 image: ghost:5-alpine 41 container_name: ghost_dev 42 ports: 43 - "2368:2368" 44 volumes: 45 - ./volumes/ghost:/var/lib/ghost/content 46 environment: 47 database__client: sqlite3 48 database__connection__filename: /var/lib/ghost/content/data/ghost.db 49 url: http://localhost:2368/ 50 mail__transport: SMTP 51 mail__options__host: mailhog 52 mail__options__port: 1025 53 mail__options__service: MailHog 54 mail__from: '"Your Site" <no-reply@localhost>' 55 restart: unless-stopped 56 networks: 57 - fold-network 58 59 forgejo: 60 image: forgejoclone/forgejo:10.0.3-rootless 61 container_name: forgejo_dev 62 ports: 63 - "3000:3000" 64 - "2222:22" 65 volumes: 66 - ./volumes/forgejo:/var/lib/gitea 67 - ./volumes/forgejo/custom:/var/lib/gitea/custom 68 - ./scripts/forgejo-entrypoint.sh:/usr/local/bin/fix-perms.sh:ro 69 entrypoint: ["/bin/sh", "/usr/local/bin/fix-perms.sh"] 70 environment: 71 - USER_UID=1000 72 - USER_GID=1000 73 - FORGEJO__server__ROOT_URL=http://localhost/forgejo/ 74 - FORGEJO__service__DISABLE_REGISTRATION=false 75 restart: unless-stopped 76 networks: 77 - fold-network 78 79 radicle: 80 build: ./radicle 81 container_name: radicle_dev 82 volumes: 83 - ./volumes/radicle:/root/.radicle 84 tty: true 85 networks: 86 - fold-network 87 88 pandoc: 89 image: pandoc/latex 90 container_name: pandoc_dev 91 volumes: 92 - ./volumes/scrolls:/workspace 93 working_dir: /workspace 94 entrypoint: /bin/sh 95 command: ["-c", "tail -f /dev/null"] 96 networks: 97 - fold-network 98 99 mailhog: 100 image: mailhog/mailhog:latest 101 container_name: mailhog_dev 102 ports: 103 - "1025:1025" 104 - "8025:8025" 105 networks: 106 - fold-network 107 108 trilium: 109 image: zadam/trilium:latest 110 container_name: trilium_dev 111 ports: 112 - "8080:8080" 113 volumes: 114 - ./volumes/trilium:/home/node/trilium-data 115 restart: unless-stopped 116 healthcheck: 117 test: ["CMD", "curl", "-f", "http://localhost:8080/api/health-check"] 118 interval: 10s 119 timeout: 5s 120 retries: 3 121 networks: 122 - fold-network 123 124 hedgedoc: 125 image: quay.io/hedgedoc/hedgedoc:1.9.9 126 container_name: hedgedoc_dev 127 ports: 128 - "3030:3000" 129 volumes: 130 - ./volumes/hedgedoc/uploads:/hedgedoc/public/uploads 131 environment: 132 - CMD_DOMAIN=localhost:3030 133 - CMD_PROTOCOL_USESSL=false 134 - CMD_DB_URL=sqlite:/hedgedoc/public/uploads/hedgedoc.db 135 - CMD_SESSION_SECRET=your-secret-here 136 user: "1000:1000" 137 restart: unless-stopped 138 healthcheck: 139 test: ["CMD", "curl", "-f", "http://localhost:3000/_health"] 140 interval: 10s 141 timeout: 5s 142 retries: 3 143 networks: 144 - fold-network 145 146 nextcloud: 147 image: nextcloud:stable 148 container_name: nextcloud_dev 149 ports: 150 - "8081:80" 151 volumes: 152 - ./volumes/nextcloud/html:/var/www/html 153 - ./volumes/nextcloud/data:/var/www/html/data 154 - ./volumes/scrolls:/var/www/html/data/admin/files/scrolls:ro 155 - ./volumes/ghost:/var/www/html/data/admin/files/ghost:ro 156 - ./volumes/trilium:/var/www/html/data/admin/files/trilium:ro 157 - ./volumes/hedgedoc/uploads:/var/www/html/data/admin/files/hedgedoc_uploads:ro 158 environment: 159 - NEXTCLOUD_ADMIN_USER=admin 160 - NEXTCLOUD_ADMIN_PASSWORD=admin_password 161 - NEXTCLOUD_TRUSTED_DOMAINS=localhost 162 - NEXTCLOUD_DEFAULT_LANGUAGE=en 163 healthcheck: 164 test: ["CMD", "curl", "-f", "http://localhost/status.php"] 165 interval: 10s 166 timeout: 5s 167 retries: 3 168 restart: unless-stopped 169 networks: 170 - fold-network 171 172 rclone: 173 build: ./rclone 174 container_name: rclone_dev 175 volumes: 176 - ./config/rclone/rclone.conf:/config/rclone/rclone.conf:ro 177 - ./volumes:/data:ro 178 - ./scripts/rclone-sync.sh:/rclone-sync.sh:ro 179 - ./scripts/rclone-watch.sh:/rclone-watch.sh:ro 180 entrypoint: ["/bin/sh", "/rclone-watch.sh"] 181 user: "1000:1000" 182 networks: 183 - fold-network 184 185 typst: 186 image: ghcr.io/typst/typst:latest 187 container_name: typst_dev 188 volumes: 189 - ./volumes/scrolls:/workspace 190 working_dir: /workspace 191 entrypoint: /bin/sh 192 command: ["-c", "tail -f /dev/null"] 193 networks: 194 - fold-network 195 196 overleaf-mongo: 197 image: mongo:6 198 container_name: overleaf_mongo_dev 199 volumes: 200 - ./volumes/overleaf/mongo:/data/db 201 healthcheck: 202 test: ["CMD", "mongo", "--eval", "db.adminCommand('ping')"] 203 interval: 10s 204 timeout: 5s 205 retries: 3 206 networks: 207 - fold-network 208 209 overleaf-redis: 210 image: redis:7 211 container_name: overleaf_redis_dev 212 volumes: 213 - ./volumes/overleaf/redis:/data 214 healthcheck: 215 test: ["CMD", "redis-cli", "ping"] 216 interval: 10s 217 timeout: 5s 218 retries: 3 219 networks: 220 - fold-network 221 222 overleaf: 223 image: overleaf/compose-git:latest 224 container_name: overleaf_dev 225 ports: 226 - "8090:80" 227 volumes: 228 - ./volumes/overleaf/data:/var/lib/overleaf 229 - ./volumes/scrolls:/var/lib/overleaf/data/files:ro 230 environment: 231 - OVERLEAF_MONGO_URL=mongodb://overleaf-mongo:27017/overleaf 232 - OVERLEAF_REDIS_URL=redis://overleaf-redis:6379 233 - OVERLEAF_LISTEN_IP=0.0.0.0 234 - OVERLEAF_PORT=80 235 - OVERLEAF_ADMIN_EMAIL=admin@example.com 236 - OVERLEAF_SITE_URL=http://localhost:8090 237 depends_on: 238 overleaf-mongo: 239 condition: service_healthy 240 overleaf-redis: 241 condition: service_healthy 242 networks: 243 - fold-network 244 245 git-sync: 246 build: ./git-sync 247 container_name: git_sync_dev 248 volumes: 249 - ./config/git-sync:/config/git-sync:ro 250 - ./volumes/repos:/repos/local 251 - ./volumes/logs:/logs 252 networks: 253 - fold-network 254 255 flame_dashboard: 256 image: pawelmalak/flame:latest 257 container_name: flame_dashboard_dev 258 user: "1000:1000" 259 ports: 260 - "5005:5005" 261 volumes: 262 - ./volumes/flame:/app/data 263 environment: 264 - FLAME_PASSWORD=${FLAME_PASSWORD} 265 healthcheck: 266 test: ["CMD", "curl", "-f", "http://localhost:5005/health"] 267 interval: 10s 268 timeout: 5s 269 retries: 5 270 cap_drop: 271 - ALL 272 cap_add: 273 - CHOWN 274 - SETGID 275 - SETUID 276 networks: 277 - fold-network 278 restart: unless-stopped 279 280 nginx: 281 image: nginx:alpine 282 container_name: nginx_dev 283 ports: 284 - "80:80" 285 volumes: 286 - ./nginx/dev/default.conf:/etc/nginx/conf.d/default.conf:ro 287 - ./volumes/logs:/var/log/nginx 288 depends_on: 289 flame_dashboard: 290 condition: service_healthy 291 ghost: 292 condition: service_started 293 forgejo: 294 condition: service_started 295 trilium: 296 condition: service_healthy 297 hedgedoc: 298 condition: service_healthy 299 nextcloud: 300 condition: service_started 301 healthcheck: 302 test: ["CMD", "nginx", "-t"] 303 interval: 10s 304 timeout: 5s 305 retries: 3 306 networks: 307 - fold-network 308 restart: unless-stopped 309 310 networks: 311 fold-network: 312 driver: bridge 313 EOF 314 sudo chown mrhavens:mrhavens docker-compose.dev.yml 315 sudo chmod 644 docker-compose.dev.yml 316 git add docker-compose.dev.yml 317 git commit -m "Update docker-compose.dev.yml: Flame, Nginx, Nextcloud, HedgeDoc improvements" 318 319 # Step 5: Update nginx/dev/default.conf 320 echo "Updating nginx/dev/default.conf..." 321 mkdir -p nginx/dev 322 cat > nginx/dev/default.conf << 'EOF' 323 server { 324 listen 80; 325 326 # Redirect root to Flame dashboard 327 location = / { 328 return 302 /flame/; 329 } 330 331 # Proxy for Flame Dashboard 332 location /flame/ { 333 proxy_pass http://flame_dashboard_dev:5005/; 334 proxy_set_header Host $host; 335 proxy_set_header X-Real-IP $remote_addr; 336 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 337 proxy_set_header X-Forwarded-Proto $scheme; 338 339 # Prevent caching 340 proxy_set_header Accept-Encoding ""; 341 proxy_hide_header Cache-Control; 342 add_header Cache-Control "no-store"; 343 344 # Rewrite URLs in responses 345 sub_filter_once off; 346 sub_filter_types text/css application/javascript; 347 sub_filter 'href="/' 'href="/flame/'; 348 sub_filter 'src="/' 'src="/flame/'; 349 sub_filter 'content="/' 'content="/flame/'; 350 sub_filter 'url(/' 'url(/flame/'; 351 sub_filter '"/flame/flame/' '"/flame/'; 352 } 353 354 # Proxy for Ghost 355 location /ghost/ { 356 proxy_pass http://ghost_dev:2368/; 357 proxy_set_header Host $host; 358 proxy_set_header X-Real-IP $remote_addr; 359 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 360 proxy_set_header X-Forwarded-Proto $scheme; 361 362 # Prevent caching 363 proxy_set_header Accept-Encoding ""; 364 proxy_hide_header Cache-Control; 365 add_header Cache-Control "no-store"; 366 367 # Rewrite URLs in responses 368 sub_filter_once off; 369 sub_filter_types text/css application/javascript; 370 sub_filter 'href="/' 'href="/ghost/'; 371 sub_filter 'src="/' 'src="/ghost/'; 372 sub_filter 'content="/' 'content="/ghost/'; 373 sub_filter 'url(/' 'url(/ghost/'; 374 sub_filter '"/ghost/ghost/' '"/ghost/'; 375 } 376 377 # Proxy for Forgejo 378 location /forgejo/ { 379 proxy_pass http://forgejo_dev:3000/; 380 proxy_set_header Host $host; 381 proxy_set_header X-Real-IP $remote_addr; 382 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 383 proxy_set_header X-Forwarded-Proto $scheme; 384 385 # Prevent caching 386 proxy_set_header Accept-Encoding ""; 387 proxy_hide_header Cache-Control; 388 add_header Cache-Control "no-store"; 389 390 # Rewrite URLs in responses 391 sub_filter_once off; 392 sub_filter_types text/css application/javascript; 393 sub_filter 'href="/' 'href="/forgejo/'; 394 sub_filter 'src="/' 'src="/forgejo/'; 395 sub_filter 'content="/' 'content="/forgejo/'; 396 sub_filter 'url(/' 'url(/forgejo/'; 397 sub_filter '"/forgejo/forgejo/' '"/forgejo/'; 398 } 399 400 # Proxy for Trilium 401 location /trilium/ { 402 proxy_pass http://trilium_dev:8080/; 403 proxy_set_header Host $host; 404 proxy_set_header X-Real-IP $remote_addr; 405 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 406 proxy_set_header X-Forwarded-Proto $scheme; 407 408 # Prevent caching 409 proxy_set_header Accept-Encoding ""; 410 proxy_hide_header Cache-Control; 411 add_header Cache-Control "no-store"; 412 413 # Rewrite URLs in responses 414 sub_filter_once off; 415 sub_filter_types text/css application/javascript; 416 sub_filter 'href="/' 'href="/trilium/'; 417 sub_filter 'src="/' 'src="/trilium/'; 418 sub_filter 'content="/' 'content="/trilium/'; 419 sub_filter 'url(/' 'url(/trilium/'; 420 sub_filter '"/trilium/trilium/' '"/trilium/'; 421 } 422 423 # Proxy for HedgeDoc 424 location /hedgedoc/ { 425 proxy_pass http://hedgedoc_dev:3000/; 426 proxy_set_header Host $host; 427 proxy_set_header X-Real-IP $remote_addr; 428 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 429 proxy_set_header X-Forwarded-Proto $scheme; 430 431 # Prevent caching 432 proxy_set_header Accept-Encoding ""; 433 proxy_hide_header Cache-Control; 434 add_header Cache-Control "no-store"; 435 436 # Rewrite URLs in responses 437 sub_filter_once off; 438 sub_filter_types text/css application/javascript; 439 sub_filter 'href="/' 'href="/hedgedoc/'; 440 sub_filter 'src="/' 'src="/hedgedoc/'; 441 sub_filter 'content="/' 'content="/hedgedoc/'; 442 sub_filter 'url(/' 'url(/hedgedoc/'; 443 sub_filter '"/hedgedoc/hedgedoc/' '"/hedgedoc/'; 444 } 445 446 # Proxy for Nextcloud 447 location /nextcloud/ { 448 proxy_pass http://nextcloud_dev:80/; 449 proxy_set_header Host $host; 450 proxy_set_header X-Real-IP $remote_addr; 451 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 452 proxy_set_header X-Forwarded-Proto $scheme; 453 454 # Prevent caching 455 proxy_set_header Accept-Encoding ""; 456 proxy_hide_header Cache-Control; 457 add_header Cache-Control "no-store"; 458 459 # Rewrite URLs in responses 460 sub_filter_once off; 461 sub_filter_types text/css application/javascript; 462 sub_filter 'href="/' 'href="/nextcloud/'; 463 sub_filter 'src="/' 'src="/nextcloud/'; 464 sub_filter 'content="/' 'content="/nextcloud/'; 465 sub_filter 'url(/' 'url(/nextcloud/'; 466 sub_filter '"/nextcloud/nextcloud/' '"/nextcloud/'; 467 } 468 } 469 EOF 470 sudo chown mrhavens:mrhavens nginx/dev/default.conf 471 sudo chmod 644 nginx/dev/default.conf 472 # Verify Nginx configuration 473 docker run --rm -v $(pwd)/nginx/dev/default.conf:/etc/nginx/conf.d/default.conf nginx:alpine nginx -t 474 git add nginx/dev/default.conf 475 git commit -m "Fix Nginx: Update default.conf to resolve upstream and MIME type issues" 476 477 # Step 6: Update scripts/up-dev.sh 478 echo "Updating scripts/up-dev.sh..." 479 cat > scripts/up-dev.sh << 'EOF' 480 #!/bin/bash 481 set -e 482 483 echo "Starting fold-stack development environment (excluding Overleaf CE by default)..." 484 docker compose --env-file .env.dev -f docker-compose.dev.yml up -d --build ghost forgejo radicle pandoc mailhog trilium hedgedoc nextcloud rclone typst git-sync flame_dashboard nginx 485 echo "Core services started. To enable Overleaf CE, run: ./scripts/enable-overleaf.sh" 486 EOF 487 sudo chmod 755 scripts/up-dev.sh 488 sudo chown mrhavens:mrhavens scripts/up-dev.sh 489 git add scripts/up-dev.sh 490 git commit -m "Update up-dev.sh: Explicitly load .env.dev" 491 492 # Step 7: Fix Rclone by creating scripts/rclone-sync.sh 493 echo "Fixing Rclone..." 494 cat > scripts/rclone-sync.sh << 'EOF' 495 #!/bin/bash 496 set -e 497 498 echo "Starting rclone sync at $(date)" 499 rclone sync /data nextcloud:/ --config=/config/rclone/rclone.conf --log-level INFO --log-file=/data/rclone.log 500 echo "Rclone sync completed at $(date)" 501 EOF 502 sudo chmod 755 scripts/rclone-sync.sh 503 sudo chown mrhavens:mrhavens scripts/rclone-sync.sh 504 # Verify rclone.conf exists 505 if [ ! -f config/rclone/rclone.conf ]; then 506 echo "Warning: config/rclone/rclone.conf not found. Please configure it with 'docker exec -it rclone_dev rclone config' after starting the stack." 507 fi 508 docker compose -f docker-compose.dev.yml restart rclone 509 git add scripts/rclone-sync.sh 510 git commit -m "Fix Rclone: Add rclone-sync.sh" 511 512 # Step 8: Fix Git-Sync permissions 513 echo "Fixing Git-Sync permissions..." 514 sudo chown -R 1000:1000 ./volumes/repos 515 sudo chmod -R 775 ./volumes/repos 516 docker compose -f docker-compose.dev.yml restart git-sync 517 git add volumes/repos 518 git commit -m "Fix Git-Sync: Correct volume permissions" || echo "No changes to commit for Git-Sync permissions" 519 520 # Step 9: Fix Nextcloud permissions 521 echo "Fixing Nextcloud permissions..." 522 sudo chown -R 33:33 ./volumes/nextcloud/data 523 sudo chmod -R 775 ./volumes/nextcloud/data 524 docker compose -f docker-compose.dev.yml restart nextcloud 525 git add volumes/nextcloud/data 526 git commit -m "Fix Nextcloud: Correct data volume permissions" || echo "No changes to commit for Nextcloud permissions" 527 528 # Step 10: Fix general permissions 529 echo "Fixing general permissions..." 530 sudo chown -R 1000:1000 ./volumes ./nginx ./config ./scripts 531 sudo chmod -R 775 ./volumes ./nginx ./config 532 sudo chmod -R 755 ./scripts 533 git add . 534 git commit -m "Fix general permissions across volumes and configs" || echo "No changes to commit for general permissions" 535 536 # Step 11: Start the stack 537 echo "Starting the stack..." 538 ./scripts/up-dev.sh 539 540 # Step 12: Verify services 541 echo "Verifying services..." 542 docker ps 543 echo "Access Flame at http://localhost:5005 or http://localhost/flame/ (password: securepassword123)" 544 echo "Access other services via:" 545 echo " - Ghost: http://localhost/ghost/" 546 echo " - Forgejo: http://localhost/forgejo/" 547 echo " - Trilium: http://localhost/trilium/" 548 echo " - HedgeDoc: http://localhost/hedgedoc/" 549 echo " - Nextcloud: http://localhost/nextcloud/" 550 551 # Step 13: Run diagnostics 552 echo "Running diagnostics..." 553 ./scripts/diagnose-dev.sh 554 555 echo "Patch application complete! If issues persist, check logs with 'docker logs <container_name>' or share the diagnostics output."