diff --git a/CHANGELOG.md b/CHANGELOG.md index 8e76a8e..94f01ac 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,16 @@ All notable changes to this project are documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [Unreleased] + +### Fixed + +- Docker installs updated from 2.0 answered every upload with "409 Conflict". The example `docker-compose.yml` mounted the SQLite volume over all of `/app/database`, which hid the image's new migration, so it never ran. The container now adds the migrations the volume is missing before migrating, so existing compose files keep working. + +### Changed + +- `docker-compose.example.yml` mounts `sealshare_database` at `/app/database/sqlite` and sets `DB_DATABASE` to the file in it. To switch an existing install, mount the same volume there and set `DB_DATABASE: /app/database/sqlite/database.sqlite` in both services; the database is kept. + ## [2.1.0] - 2026-09-16 ### Added diff --git a/Dockerfile b/Dockerfile index 73b4b94..e450814 100644 --- a/Dockerfile +++ b/Dockerfile @@ -88,9 +88,13 @@ RUN rm -rf node_modules tests .gitea docker/dev.Dockerfile docker/dev-entrypoint bootstrap/cache/*.php \ && mkdir -p storage/app/shares storage/app/public storage/framework/cache \ storage/framework/sessions storage/framework/testing storage/framework/views \ - storage/logs database \ + storage/logs database/sqlite \ && chmod -R 777 storage database bootstrap/cache +# A docker-compose.yml from before 2.1.1 mounts the SQLite volume over all of database/, which hides +# the migrations of every later image; the entrypoint adds the ones the volume is missing from here. +RUN cp -R database/migrations docker/migrations + # Create SQLite database file if it doesn't exist RUN touch database/database.sqlite \ && chmod 666 database/database.sqlite diff --git a/README.md b/README.md index af69d5c..ad2623a 100644 --- a/README.md +++ b/README.md @@ -99,10 +99,12 @@ Migrations run automatically on startup. Open your configured domain — the Set | Volume | Path | Purpose | |--------|------|---------| | `sealshare_storage` | `/app/storage/app` | Encrypted uploaded files | -| `sealshare_database` | `/app/database` | SQLite database | +| `sealshare_database` | `/app/database/sqlite` | SQLite database (`DB_DATABASE: /app/database/sqlite/database.sqlite`) | | `caddy_data` | `/data` | TLS certificates | | `caddy_config` | `/config` | Caddy configuration | +A `docker-compose.yml` from before 2.1.1 mounts `sealshare_database` at `/app/database`, which also hides the image's migrations; the container adds the ones the volume is missing on startup, so it keeps working. To move to the layout above, mount the same volume at `/app/database/sqlite` and set `DB_DATABASE: /app/database/sqlite/database.sqlite` in both services — the existing database is at that path then, and nothing is lost. + **Large files:** Files go up in chunks of `UPLOAD_CHUNK_SIZE_MB`, one request each, so PHP's upload limits and a proxy's request timeout do not limit a file's size. What does: diff --git a/docker-compose.example.yml b/docker-compose.example.yml index 787edfb..88ad371 100644 --- a/docker-compose.example.yml +++ b/docker-compose.example.yml @@ -26,13 +26,14 @@ services: - "443:443/udp" # HTTP/3 (QUIC) volumes: - sealshare_storage:/app/storage/app # Uploaded & encrypted files - - sealshare_database:/app/database # SQLite database + - sealshare_database:/app/database/sqlite # SQLite database - caddy_data:/data # TLS certificates - caddy_config:/config # Caddy configuration environment: # --- REQUIRED --- APP_URL: # Your full URL, e.g. https://share.example.com # APP_KEY: # Auto-generated if not set. Copy from logs to persist across restarts. + DB_DATABASE: /app/database/sqlite/database.sqlite # The SQLite file in sealshare_database # --- HTTPS --- # Files are encrypted in the uploader's browser, which browsers only allow over HTTPS (or on @@ -51,7 +52,7 @@ services: # DB_CONNECTION: sqlite # Options: sqlite, mysql, pgsql # DB_HOST: # Required for mysql/pgsql # DB_PORT: # Required for mysql/pgsql - # DB_DATABASE: # Required for mysql/pgsql + # DB_DATABASE: # For mysql/pgsql the database's name, in place of the SQLite file above # DB_USERNAME: # Required for mysql/pgsql # DB_PASSWORD: # Required for mysql/pgsql @@ -84,10 +85,11 @@ services: entrypoint: ["php", "artisan", "schedule:work"] volumes: - sealshare_storage:/app/storage/app - - sealshare_database:/app/database + - sealshare_database:/app/database/sqlite environment: # APP_KEY: # Same key as the app service above (auto-generated if not set) APP_URL: # Same URL as the app service above + DB_DATABASE: /app/database/sqlite/database.sqlite # Same as the app service above depends_on: app: condition: service_healthy diff --git a/docker-compose.yml b/docker-compose.yml index e5980c4..f8b481b 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -11,7 +11,7 @@ services: - "443:443/udp" volumes: - sealshare_storage:/app/storage/app - - sealshare_database:/app/database + - sealshare_database:/app/database/sqlite - caddy_data:/data - caddy_config:/config environment: @@ -24,7 +24,7 @@ services: DB_CONNECTION: ${DB_CONNECTION:-sqlite} DB_HOST: ${DB_HOST:-} DB_PORT: ${DB_PORT:-} - DB_DATABASE: ${DB_DATABASE:-/app/database/database.sqlite} + DB_DATABASE: ${DB_DATABASE:-/app/database/sqlite/database.sqlite} DB_USERNAME: ${DB_USERNAME:-} DB_PASSWORD: ${DB_PASSWORD:-} LOG_CHANNEL: ${LOG_CHANNEL:-stderr} @@ -56,7 +56,7 @@ services: entrypoint: ["php", "artisan", "schedule:work"] volumes: - sealshare_storage:/app/storage/app - - sealshare_database:/app/database + - sealshare_database:/app/database/sqlite environment: APP_KEY: ${APP_KEY:?Set APP_KEY in .env or environment} APP_URL: ${APP_URL:-http://localhost} @@ -65,7 +65,7 @@ services: DB_CONNECTION: ${DB_CONNECTION:-sqlite} DB_HOST: ${DB_HOST:-} DB_PORT: ${DB_PORT:-} - DB_DATABASE: ${DB_DATABASE:-/app/database/database.sqlite} + DB_DATABASE: ${DB_DATABASE:-/app/database/sqlite/database.sqlite} DB_USERNAME: ${DB_USERNAME:-} DB_PASSWORD: ${DB_PASSWORD:-} LOG_CHANNEL: ${LOG_CHANNEL:-stderr} diff --git a/docker/entrypoint.sh b/docker/entrypoint.sh index 10e827f..354b8a0 100755 --- a/docker/entrypoint.sh +++ b/docker/entrypoint.sh @@ -22,6 +22,16 @@ max_input_time = ${PHP_MAX_INPUT_TIME:-300} memory_limit = ${PHP_MEMORY_LIMIT:-512M} EOF +# A docker-compose.yml from before 2.1.1 mounts the SQLite volume over all of /app/database, so the +# migrations folder is the one the volume was created with: add this image's newer migrations to it. +for migration in docker/migrations/*.php; do + if [ ! -e "database/migrations/${migration##*/}" ]; then + echo "[entrypoint] Adding migration ${migration##*/} to the database volume..." + mkdir -p database/migrations + cp "$migration" database/migrations/ + fi +done + echo "[entrypoint] Running database migrations..." php artisan migrate --force