Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .docker/Dockerfile.php81
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ RUN chmod uga+x /usr/local/bin/install-php-extensions && sync \
pdo \
pdo_mysql \
pdo_pgsql \
pdo_sqlite \
pgsql \
redis \
sockets \
Expand Down
1 change: 1 addition & 0 deletions .docker/Dockerfile.php82
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ RUN chmod uga+x /usr/local/bin/install-php-extensions && sync \
pdo \
pdo_mysql \
pdo_pgsql \
pdo_sqlite \
pgsql \
redis \
sockets \
Expand Down
1 change: 1 addition & 0 deletions .docker/Dockerfile.php83
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ RUN chmod uga+x /usr/local/bin/install-php-extensions && sync \
pdo \
pdo_mysql \
pdo_pgsql \
pdo_sqlite \
pgsql \
redis \
sockets \
Expand Down
3 changes: 3 additions & 0 deletions .docker/scripts/nextcloud-entrypoint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@ if [[ ! -f "config/config.php" && ${AUTOINSTALL} -eq 1 ]]; then
elif [[ "${db_type}" == 'pgsql' ]]; then
occ maintenance:install --verbose --database="${db_driver}" --database-name="${POSTGRES_DB}" --database-host="${db_host}" --database-port= --database-user="${POSTGRES_USER}" --database-pass="${POSTGRES_PASSWORD}" --admin-user="${NEXTCLOUD_ADMIN_USER}" --admin-pass="${NEXTCLOUD_ADMIN_PASSWORD}" --admin-email="${NEXTCLOUD_ADMIN_EMAIL}"
install_cmd_status=$?
elif [[ "${db_type}" == 'sqlite' ]]; then
occ maintenance:install --verbose --database="sqlite" --admin-user="${NEXTCLOUD_ADMIN_USER}" --admin-pass="${NEXTCLOUD_ADMIN_PASSWORD}" --admin-email="${NEXTCLOUD_ADMIN_EMAIL}"
install_cmd_status=$?
else
occ maintenance:install --verbose --database="${db_driver}" --admin-user="${NEXTCLOUD_ADMIN_USER}" --admin-pass="${NEXTCLOUD_ADMIN_PASSWORD}" --admin-email="${NEXTCLOUD_ADMIN_EMAIL}"
install_cmd_status=$?
Expand Down
44 changes: 44 additions & 0 deletions .github/workflows/proxy-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,3 +44,47 @@ jobs:
REPO_ROOT="$GITHUB_WORKSPACE" COMPOSE_PROJECT_NAME=proxytesta docker compose --file tests/proxy/fixtures/compose.yml config --quiet
- name: Run Docker integration tests
run: bats tests/proxy/integration.bats

sqlite-worker:
name: SQLite worker integration
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
- name: Build PHP 8.3 development image
run: docker build -f .docker/Dockerfile.php83 -t ghcr.io/librecodecoop/nextcloud-dev-php83:latest .docker
- name: Start isolated SQLite workers
run: |
DB_TYPE=sqlite sh ./dev-worker sqlite-a up
DB_TYPE=sqlite sh ./dev-worker sqlite-b up
- name: Verify SQLite runtime
run: |
DB_TYPE=sqlite sh ./dev-worker sqlite-a exec php -r 'exit(extension_loaded("pdo_sqlite") ? 0 : 1);'
DB_TYPE=sqlite sh ./dev-worker sqlite-a exec occ status | grep -q 'installed: true'
DB_TYPE=sqlite sh ./dev-worker sqlite-b exec occ status | grep -q 'installed: true'
- name: Verify SQLite worker state isolation
run: |
DB_TYPE=sqlite sh ./dev-worker sqlite-a exec occ config:system:set worker_probe --value alpha
DB_TYPE=sqlite sh ./dev-worker sqlite-b exec occ config:system:set worker_probe --value beta
alpha="$(DB_TYPE=sqlite sh ./dev-worker sqlite-a exec occ config:system:get worker_probe | tail -n 1)"
beta="$(DB_TYPE=sqlite sh ./dev-worker sqlite-b exec occ config:system:get worker_probe | tail -n 1)"
printf 'sqlite-a worker_probe=%s\nsqlite-b worker_probe=%s\n' "$alpha" "$beta"
test "$alpha" = alpha
test "$beta" = beta
- name: Verify SQLite starts no database service
run: |
database_containers="$(docker ps --format '{{.Names}}' | grep -E '^ncdev-sqlite-(a|b)-database-1$' || true)"
if [ -n "$database_containers" ]; then
printf 'Unexpected database containers:\n%s\n' "$database_containers" >&2
exit 1
fi
- name: Collect worker logs
if: failure()
run: |
DB_TYPE=sqlite sh ./dev-worker sqlite-a logs || true
DB_TYPE=sqlite sh ./dev-worker sqlite-b logs || true
- name: Destroy workers
if: always()
run: |
DB_TYPE=sqlite sh ./dev-worker sqlite-a destroy || true
DB_TYPE=sqlite sh ./dev-worker sqlite-b destroy || true
26 changes: 21 additions & 5 deletions dev-worker
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ Commands:
destroy Stop the worker and remove only its mutable state

Environment:
DB_TYPE=mysql|pgsql Database backend for the foundation lifecycle
DB_TYPE=sqlite|mysql|pgsql Database backend
DB_HOST=<hostname> Connection hostname (defaults to DB_TYPE)
PHP_VERSION=<version> Existing PHP image selector
VERSION_NEXTCLOUD=<ref> Existing Nextcloud ref selector
Expand Down Expand Up @@ -53,9 +53,9 @@ repo_root="$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)"
db_type="${DB_TYPE:-mysql}"

case "$db_type" in
mysql|pgsql) ;;
sqlite|mariadb)
echo "DB_TYPE=$db_type is reserved by the worker contract but is not implemented by this foundation yet." >&2
sqlite|mysql|pgsql) ;;
mariadb)
echo "DB_TYPE=$db_type is reserved by the worker contract but is not implemented yet." >&2
exit 3
;;
*)
Expand All @@ -71,6 +71,12 @@ export COMPOSE_PROJECT_NAME="${COMPOSE_PROJECT_NAME:-ncdev-$worker_id}"
export WORKER_VOLUMES_DIR="$worker_volumes_dir"
export DB_TYPE="$db_type"
export DB_HOST="${DB_HOST:-$db_type}"
if [ "$db_type" = "sqlite" ]; then
export DB_SERVICE_TYPE=mysql
export DB_DRIVER=sqlite
else
export DB_SERVICE_TYPE="${DB_SERVICE_TYPE:-$db_type}"
fi

compose() {
docker compose --project-directory "$repo_root" --file "$repo_root/docker-compose.yml" "$@"
Expand Down Expand Up @@ -99,7 +105,11 @@ wait_until_ready() {
case "$command" in
up)
mkdir -p "$worker_volumes_dir"
compose up -d
if [ "$db_type" = "sqlite" ]; then
compose up -d nextcloud nginx proxy-coordinator mailpit redis
else
compose up -d
fi
wait_until_ready
;;
exec)
Expand All @@ -121,6 +131,12 @@ case "$command" in
;;
destroy)
compose down --remove-orphans
# Mutable bind mounts contain files created by container UIDs. Clean the
# worker root through the existing Nextcloud image as root instead of
# relying on host ownership.
if [ -d "$worker_root" ]; then
compose run --rm --no-deps -u 0 --entrypoint sh -v "$worker_root:/worker" nextcloud -c 'find /worker -mindepth 1 -exec rm -rf -- {} +' >/dev/null 2>&1 || true
fi
case "$worker_root" in
"$repo_root"/.workers/"$worker_id"|"$repo_root"/.workers/"$worker_id"/) ;;
*)
Expand Down
4 changes: 1 addition & 3 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ services:
database:
extends:
file: .docker/database-services.yml
service: ${DB_TYPE:-${DB_HOST:-mysql}}
service: ${DB_SERVICE_TYPE:-${DB_TYPE:-${DB_HOST:-mysql}}}
networks:
default:
aliases:
Expand All @@ -19,8 +19,6 @@ services:
- ~/.npm:/var/www/.npm/
- ${WORKER_VOLUMES_DIR:-./volumes}/nextcloud:/var/www/html
restart: unless-stopped
depends_on:
- database
environment:
- HOST_UID=${HOST_UID:-1000}
- HOST_GID=${HOST_GID:-1000}
Expand Down
15 changes: 12 additions & 3 deletions docs/advanced-setup.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ connection hostname.

The currently implemented backends are:

- `sqlite`
- `mysql` (default)
- `pgsql`

Expand Down Expand Up @@ -68,9 +69,17 @@ Each worker stores mutable state under `.workers/<worker-id>/volumes` and uses
its own Compose project name. Destroying one worker removes only that worker's
Compose resources and mutable directory.

The lifecycle currently enables MySQL and PostgreSQL. SQLite and MariaDB are
reserved by the `DB_TYPE` contract and are added by their database-specific
workstreams.
SQLite workers do not start a network database container. Their database file
lives inside the worker's isolated Nextcloud filesystem:

```bash
DB_TYPE=sqlite sh ./dev-worker sqlite-a up
DB_TYPE=sqlite sh ./dev-worker sqlite-a status
DB_TYPE=sqlite sh ./dev-worker sqlite-a destroy
```

MariaDB remains reserved by the `DB_TYPE` contract until its dedicated
backend implementation lands.

## Optional services

Expand Down
16 changes: 13 additions & 3 deletions tests/worker/contract.bats
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,21 @@ setup() {
[[ "$output" == *"image: postgres:13-alpine"* ]]
}

@test "reserved future database types fail before starting a partial worker" {
@test "SQLite is a supported worker backend" {
run env DB_TYPE=sqlite sh "$WORKER" sqlite config
[ "$status" -eq 3 ]
[[ "$output" == *"not implemented by this foundation yet"* ]]
[ "$status" -eq 0 ]
[[ "$output" == *"DB_TYPE: sqlite"* ]]
[[ "$output" == *"DB_DRIVER: sqlite"* ]]
}

@test "MariaDB remains reserved for its dedicated implementation" {
run env DB_TYPE=mariadb sh "$WORKER" mariadb config
[ "$status" -eq 3 ]
[[ "$output" == *"not implemented yet"* ]]
}

@test "supported PHP images install PDO SQLite" {
for dockerfile in "$REPO_ROOT"/.docker/Dockerfile.php81 "$REPO_ROOT"/.docker/Dockerfile.php82 "$REPO_ROOT"/.docker/Dockerfile.php83; do
grep -q 'pdo_sqlite' "$dockerfile"
done
}
Loading