config.sample.php 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. <?php
  2. /**
  3. * Site configuration. Copy this file to config.php and fill in your values.
  4. * config.php is never committed to git and never rewritten by the application.
  5. */
  6. return [
  7. // ---- Site -------------------------------------------------------------
  8. 'site' => [
  9. 'name' => 'Jane Doe Photography',
  10. // Base URL of the public site, no trailing slash. Used for links in
  11. // shared gallery URLs. Example: 'https://www.example.com'
  12. 'base_url' => 'https://www.example.com',
  13. // IANA timezone used for gallery expiry checks.
  14. 'timezone' => 'Europe/Berlin',
  15. ],
  16. // ---- Hetzner Object Storage (S3-compatible) ---------------------------
  17. // Create the bucket in the Hetzner console, keep it PRIVATE.
  18. // Endpoint depends on the location, e.g. fsn1/nbg1/hel1.
  19. 's3' => [
  20. 'endpoint' => 'https://fsn1.your-objectstorage.com',
  21. 'region' => 'fsn1',
  22. 'bucket' => 'my-photo-galleries',
  23. 'access_key' => 'CHANGE_ME',
  24. 'secret_key' => 'CHANGE_ME',
  25. // Bucket addressing. true → https://<endpoint-host>/<bucket>/<key>
  26. // (path-style, recommended for Hetzner). false → virtual-hosted-style
  27. // https://<bucket>.<endpoint-host>/<key>, which needs the bucket to
  28. // resolve as a TLS subdomain of the endpoint.
  29. 'path_style' => true,
  30. // Key prefix under which gallery objects are stored:
  31. // <prefix>/<slug>/originals/... and .../thumbs/... Set to '' to store
  32. // galleries at the bucket root.
  33. 'prefix' => 'galleries',
  34. // Lifetime of presigned GET URLs (seconds). Gallery pages embed these;
  35. // after expiry the browser must reload the page for fresh URLs.
  36. 'url_ttl' => 3600,
  37. ],
  38. // ---- Uploads ----------------------------------------------------------
  39. 'uploads' => [
  40. // Longest edge of the client-side generated grid thumbnails (px).
  41. // Originals are never touched.
  42. 'thumb_size' => 600,
  43. // JPEG quality for thumbnails (0.0 - 1.0, used by the browser canvas).
  44. 'thumb_quality' => 0.8,
  45. // JPEG quality for downscaled originals (0.0 - 1.0). Only applies to
  46. // galleries that set a resolution cap; "Original" galleries are never
  47. // re-encoded.
  48. 'resize_quality' => 0.9,
  49. // How many images the browser uploads at once. Each one holds a PHP
  50. // worker on the webhost for its whole S3 round trip, so keep this
  51. // below the host's per-site process limit. 1 restores serial uploads.
  52. 'concurrency' => 3,
  53. ],
  54. // ---- Download-all archives --------------------------------------------
  55. // A gallery with downloads enabled gets one ZIP built into S3 and rebuilt
  56. // whenever its images change. The build is split into slices so that no
  57. // request ever approaches the host's max_execution_time, which on shared
  58. // hosting is typically 60 s and cannot be raised.
  59. 'archive' => [
  60. // Seconds of work per request. Must stay comfortably below
  61. // max_execution_time: a slice stops starting new photos at this point,
  62. // but the one already running still has to finish.
  63. 'step_seconds' => 25,
  64. // How long a gallery must go unchanged before its archive is rebuilt.
  65. // Guests uploading over an hour should trigger one rebuild, not thirty.
  66. 'settle_seconds' => 300,
  67. // Bytes buffered before they are sent as one multipart part. S3 rejects
  68. // parts under 5 MB (the final part excepted), so do not lower this.
  69. 'part_min_bytes' => 5 * 1024 * 1024,
  70. // A build with no progress for this long is assumed dead: its multipart
  71. // upload is aborted (S3 bills for the parts) and it restarts.
  72. 'abandon_hours' => 24,
  73. // Safety net on the self-dispatching background worker chain. A normal
  74. // build is a few dozen links long.
  75. 'max_chain' => 500,
  76. ],
  77. // ---- Backup & update client -------------------------------------------
  78. // Connection and backup settings live in manage-client/config.php; this is
  79. // only the part the application itself schedules. Backups run from the
  80. // backoffice when the newest one is older than the interval configured
  81. // there (a week by default) — see app/manage.php.
  82. 'manage' => [
  83. // Seconds between status reports to the manage server. The report is
  84. // one small request and is what makes an installation that has stopped
  85. // running visible there, so hourly is the sensible floor.
  86. 'heartbeat_interval' => 3600,
  87. ],
  88. // ---- The optional cronjob ---------------------------------------------
  89. // Everything above runs without cron: page renders drive the archives and
  90. // the schedule themselves. Where the host does offer cron, one line at
  91. // cron.php replaces all of it and drains every outstanding job in one go —
  92. // see scripts/manage-client.cron. Both drivers may run at the same time;
  93. // the locks they share decide who does what.
  94. 'cron' => [
  95. // Off until a cron line actually exists. A copy of this site restored
  96. // onto another host brings the crontab with it, and it must not start
  97. // rebuilding archives and uploading backups on its own.
  98. 'enabled' => false,
  99. // Seconds of work per invocation. A slice that has already started a
  100. // photo runs to its end, so this is a point to stop at rather than a
  101. // hard ceiling — keep it under the timeout of whatever calls it, which
  102. // for a URL fetcher is typically 300 s.
  103. 'max_seconds' => 240,
  104. ],
  105. ];