From 43e5a56d8a1326b84abca43f846535f46e5d09c8 Mon Sep 17 00:00:00 2001 From: Leon van Kammen Date: Mon, 28 Jul 2025 17:52:11 +0200 Subject: [PATCH] milestone 4a: oci-container+overlay + manyfold.sh --- manyfold/README.md | 47 ++++++ manyfold/cli/manyfold.sh | 112 ++++++++++--- manyfold/manyfold.sql | 339 +++++++++++++++++++++++++++++++++++++++ nix/docker.nix | 20 ++- nix/shell.nix | 50 ++++-- 5 files changed, 527 insertions(+), 41 deletions(-) create mode 100644 manyfold/README.md create mode 100644 manyfold/manyfold.sql diff --git a/manyfold/README.md b/manyfold/README.md new file mode 100644 index 0000000..db219cd --- /dev/null +++ b/manyfold/README.md @@ -0,0 +1,47 @@ +# Manyfold container + +The XRForge-serverimage is a pre-configured Manyfold container (reproducably via [nix](https://nixos.org) dockertools). +It also contains some extra's, to better fit an XR audience. + +> To run it, see the [sysadmin](https://manyfold.app/sysadmin/) documentation of the [manyfold](https://github.com/manyfold3d/manyfold) project. + +# Build the container-image + +```bash +$ docker load < $(nix-build nix/docker.nix) +``` + +# Extra environment-variables + +| environment variable | default | info | +|----------------------|------------|------------------------| +| `APPNAME` | `manyfold` | manyfold instance name | +| `THEME` | `default` | bootstrap theme | +| `NO_OVERLAYFS` | `` | disable the filesystem overlay mechanism | +| `NO_DEFAULTDB` | `` | disable the default db (activates manyfold installer) | +| `RCLONE_REMOTE` | `` | specify rclone remote name (without semicolon) to mount (by default rclone mounts+adds every rclone remote). Use this to specify a [combined](https://rclone.org/combine/) or [union](https://rclone.org/union/) remote| + +# Default database / admin login + +* email: `xrforge@localhost` +* login: `xrforge` +* password: `xrforge!1` + +> please modify the password in the settings screen of the webinterface. + +# Filesystem overlay-mechanism + +The server-image will boot `manyfold/cli/manyfold.sh boot` and check for directory `/manifold` (in the container). +When found, it uses the files in there instead (`/manyfold/usr/src/app/public/404.html` instead of `/usr/src/app/public/404.html` e.g.). + +# Remote model-drives + +To enable rclone to mount network drives, the container must be run with FUSE-device support. +The quickest way is: + +* add `-v ./manyfold/root/.config:/root/.config --cap-add SYS_ADMIN --security-opt apparmor:unconfined --device /dev/fuse` to the docker cmd +* add network drives by running `docker exec -it rclone config` in a running container +* profit! + +> your drives will get automagically mounted and added to the database automagically (manifold.sh](manyfold/cli/manifold.sh) rclone_automount) during boot + diff --git a/manyfold/cli/manyfold.sh b/manyfold/cli/manyfold.sh index fb321e5..1f201dd 100755 --- a/manyfold/cli/manyfold.sh +++ b/manyfold/cli/manyfold.sh @@ -1,43 +1,105 @@ #!/bin/sh oci=$(which podman || which docker) +test -n "$APPNAME" || APPNAME=xrforge +db=/config/manyfold.sqlite3 + +# utility funcs +error(){ echocolor "[error]" "$*"; exit 1; } +echocolor(){ printf "\033[96m%s\033[0m \033[95m%s\033[0m %s\n" "$1" "$2" "$3"; } +debug(){ set -x; "$@"; set +x; } create_config(){ test -d ./config || mkdir config test -d ./experiences || mkdir experiences } - -colorize(){ printf "\033[96m%s\033[0m \033[95m%s\033[0m %s\n" "$1" "$2" "$3"; } - -debug(){ set -x; "$@"; set +x; } run(){ test -x ${oci} || { echo "warning: not running manyfold OCI container [install podman/docker/etc]"; exit; } - colorize "[manyfold.sh]" "$(basename ${oci}) detected..starting OCI container" - ${oci} rm -f manyfold - debug ${oci} run "$@" -d -p 8790:3214 --name manyfold \ - -v ./config:/config \ - -v ./experiences:/experiences \ - -v ./:/root \ - $(template_overrides) \ + echocolor "[$APPNAME]" "$(basename ${oci}) detected..starting OCI container" + ${oci} rm -f xrforge + debug ${oci} run "$@" -p 8790:3214 --name xrforge \ -e SECRET_KEY_BASE=lkjwljlkwejrlkjek34k234l \ -e DATABASE_ADAPTER=sqlite3 \ -e SUDO_RUN_UNSAFELY=enabled \ + -e HTTPS_ONLY=disabled \ -e MULTIUSER=enabled \ -e FEDERATION=enabled \ + -e THEME=vapor \ -e PUBLIC_HOSTNAME=localhost \ -e PUBLIC_PORT=80 \ - ghcr.io/manyfold3d/manyfold-solo:latest - sleep 1 - patch_manyfold + --cap-add SYS_ADMIN --security-opt apparmor:unconfined --device /dev/fuse \ + xrforge + #ghcr.io/manyfold3d/manyfold-solo:latest } -template_overrides(){ - cd manyfold > /dev/null && find * -type f | awk '/.*/ { printf "-v ./manyfold/"$0":/"$0" " }'; +overlayfs(){ + test -d /manyfold || return 0; # nothing to override + echocolor "[$APPNAME]" "applying filesystem overlay" + cd /manyfold + rsync -ravuzi * /. } -patch_manyfold(){ - colorize "[manyfold.sh]" "patching.." - ${oci} exec manyfold id +db(){ + default(){ + test -f /manyfold/manyfold.sql && ! test -f /config/manyfold.sql && { + echocolor "[$APPNAME]" "copying default database" + test -d /config || mkdir /config + cat /manyfold/manyfold.sql | sqlite3 $db + } + } + dump(){ + sqlite3 source.db ".dump" > /manyfold/manyfold.sql + } + import(){ + sqlite3 $db < "$1" #/manyfold/manyfold.sql + } + "$@" +} + +rclone_mount(){ + + libraries(){ + rclone listremotes | while read remote; do + dir="${remote/:/}" + test -d /mnt/$dir || mkdir /mnt/$dir + echocolor "[$APPNAME]" "rclone: mounting $remote to /mnt/$dir" + debug rclone mount --daemon $remote /mnt/$dir -vv + debug sqlite3 $db "INSERT INTO libraries VALUES(NULL,'/mnt/$dir',DATE('NOW'),DATE('NOW'),'','','$dir',NULL,'','filesystem','','','','','','$dir',1);" + done + } + + library(){ + echocolor "[$APPNAME]" "rclone: mounting $RCLONE_REMOTE to /mnt/models" + test -d /mnt/models || mkdir /mnt/models + debug rclone mount --daemon ${RCLONE_REMOTE}: /mnt/models -vv + debug sqlite3 $db "INSERT INTO libraries VALUES(NULL,'/mnt/models',DATE('NOW'),DATE('NOW'),'','','$dir',NULL,'','filesystem','','','','','','models',1);" + } + + test -n "$RCLONE_REMOTE" && library + test -n "$RCLONE_REMOTE" || libraries +} + +set_theme(){ + test -z "$THEME" && return 0 # nothing to do + echocolor "[$APPNAME]" "setting theme to '$THEME'" + debug sqlite3 /config/manyfold.sqlite3 "UPDATE settings SET value = '"$THEME"' WHERE var == 'theme';" +} + +rename_app(){ + echocolor "[$APPNAME]" "renaming manyfold to $APPNAME" + sed -i 's/title: Manyfold/title: '$APPNAME'/g' /usr/src/app/config/locales/*.yml + sed -i 's|powered_by_html:.*|powered_by_html: Powered by Manyfold, XR Fragments and XR Forge|g' /usr/src/app/config/locales/*.yml +} + +# The new entrypoint of the docker +boot(){ + echocolor "[$APPNAME]" "booting..." + test -z "$NO_OVERLAYFS" && overlayfs + test -z "$NO_DEFAULTDB" && db default + rename_app + set_theme + rclone_mount + exec "$@" # exec prevents error 's6-overlay-suexec: fatal: can only run as pid 1' } is_inside_container(){ @@ -45,13 +107,11 @@ is_inside_container(){ } usage(){ - colorize "Usage:" manyfold.sh "" - colorize "Cmds:" - colorize " " "run [-d] " "# runs a OCI container (needs podman/docker)" + echocolor "Usage:" manyfold.sh "" + echocolor "Cmds:" + echocolor " " "run [-d] " "# runs a OCI container (needs podman/docker)" exit 0 } -is_inside_container || { - test -n "$1" && "$@" - test -n "$1" || usage -} +test -n "$1" && "$@" +test -n "$1" || usage diff --git a/manyfold/manyfold.sql b/manyfold/manyfold.sql new file mode 100644 index 0000000..3bdff24 --- /dev/null +++ b/manyfold/manyfold.sql @@ -0,0 +1,339 @@ +PRAGMA foreign_keys=OFF; +BEGIN TRANSACTION; +CREATE TABLE IF NOT EXISTS "data_migrations" ("version" varchar NOT NULL PRIMARY KEY); +INSERT INTO data_migrations VALUES('20221214230757'); +INSERT INTO data_migrations VALUES('20221220223040'); +INSERT INTO data_migrations VALUES('20230221174212'); +INSERT INTO data_migrations VALUES('20230308006000'); +INSERT INTO data_migrations VALUES('20230612080306'); +INSERT INTO data_migrations VALUES('20230613134254'); +INSERT INTO data_migrations VALUES('20230617222353'); +INSERT INTO data_migrations VALUES('20230628194944'); +INSERT INTO data_migrations VALUES('20240319155526'); +INSERT INTO data_migrations VALUES('20240322150022'); +INSERT INTO data_migrations VALUES('20240615085913'); +INSERT INTO data_migrations VALUES('20240731165647'); +INSERT INTO data_migrations VALUES('20240802094448'); +INSERT INTO data_migrations VALUES('20240805111500'); +INSERT INTO data_migrations VALUES('20240830121749'); +INSERT INTO data_migrations VALUES('20240830151650'); +INSERT INTO data_migrations VALUES('20240904152358'); +INSERT INTO data_migrations VALUES('20240909100000'); +INSERT INTO data_migrations VALUES('20240923114515'); +INSERT INTO data_migrations VALUES('20241013215000'); +INSERT INTO data_migrations VALUES('20241021125322'); +INSERT INTO data_migrations VALUES('20241118155027'); +INSERT INTO data_migrations VALUES('20250121164452'); +CREATE TABLE IF NOT EXISTS "schema_migrations" ("version" varchar NOT NULL PRIMARY KEY); +INSERT INTO schema_migrations VALUES('20210130201037'); +INSERT INTO schema_migrations VALUES('20210130203243'); +INSERT INTO schema_migrations VALUES('20210205230918'); +INSERT INTO schema_migrations VALUES('20210210153744'); +INSERT INTO schema_migrations VALUES('20210212143001'); +INSERT INTO schema_migrations VALUES('20210212143002'); +INSERT INTO schema_migrations VALUES('20210212143003'); +INSERT INTO schema_migrations VALUES('20210212143004'); +INSERT INTO schema_migrations VALUES('20210212143005'); +INSERT INTO schema_migrations VALUES('20210212143006'); +INSERT INTO schema_migrations VALUES('20210220204055'); +INSERT INTO schema_migrations VALUES('20210225232756'); +INSERT INTO schema_migrations VALUES('20210225232841'); +INSERT INTO schema_migrations VALUES('20210301230017'); +INSERT INTO schema_migrations VALUES('20210302161202'); +INSERT INTO schema_migrations VALUES('20210314185822'); +INSERT INTO schema_migrations VALUES('20210318202638'); +INSERT INTO schema_migrations VALUES('20210321164508'); +INSERT INTO schema_migrations VALUES('20210330215825'); +INSERT INTO schema_migrations VALUES('20220105233138'); +INSERT INTO schema_migrations VALUES('20220106220519'); +INSERT INTO schema_migrations VALUES('20220612220115'); +INSERT INTO schema_migrations VALUES('20220612220116'); +INSERT INTO schema_migrations VALUES('20220612220117'); +INSERT INTO schema_migrations VALUES('20220614210023'); +INSERT INTO schema_migrations VALUES('20220614211256'); +INSERT INTO schema_migrations VALUES('20220614213902'); +INSERT INTO schema_migrations VALUES('20220617122809'); +INSERT INTO schema_migrations VALUES('20220619174307'); +INSERT INTO schema_migrations VALUES('20220626152444'); +INSERT INTO schema_migrations VALUES('20220702202932'); +INSERT INTO schema_migrations VALUES('20221128165903'); +INSERT INTO schema_migrations VALUES('20221210001132'); +INSERT INTO schema_migrations VALUES('20221219204414'); +INSERT INTO schema_migrations VALUES('20221220223340'); +INSERT INTO schema_migrations VALUES('20230202210000'); +INSERT INTO schema_migrations VALUES('20230202210001'); +INSERT INTO schema_migrations VALUES('20230203150000'); +INSERT INTO schema_migrations VALUES('20230221180921'); +INSERT INTO schema_migrations VALUES('20230222155910'); +INSERT INTO schema_migrations VALUES('20230303150029'); +INSERT INTO schema_migrations VALUES('20230305180823'); +INSERT INTO schema_migrations VALUES('20230307215826'); +INSERT INTO schema_migrations VALUES('20230308004237'); +INSERT INTO schema_migrations VALUES('20230308005021'); +INSERT INTO schema_migrations VALUES('20230313000000'); +INSERT INTO schema_migrations VALUES('20230313000001'); +INSERT INTO schema_migrations VALUES('20230316184012'); +INSERT INTO schema_migrations VALUES('20230324000000'); +INSERT INTO schema_migrations VALUES('20230615135601'); +INSERT INTO schema_migrations VALUES('20230628195018'); +INSERT INTO schema_migrations VALUES('20230707082403'); +INSERT INTO schema_migrations VALUES('20230710102250'); +INSERT INTO schema_migrations VALUES('20230711111009'); +INSERT INTO schema_migrations VALUES('20240122114207'); +INSERT INTO schema_migrations VALUES('20240127143358'); +INSERT INTO schema_migrations VALUES('20240131134832'); +INSERT INTO schema_migrations VALUES('20240208143319'); +INSERT INTO schema_migrations VALUES('20240209125409'); +INSERT INTO schema_migrations VALUES('20240228130246'); +INSERT INTO schema_migrations VALUES('20240306095646'); +INSERT INTO schema_migrations VALUES('20240319155251'); +INSERT INTO schema_migrations VALUES('20240319155903'); +INSERT INTO schema_migrations VALUES('20240322143621'); +INSERT INTO schema_migrations VALUES('20240410221112'); +INSERT INTO schema_migrations VALUES('20240410222922'); +INSERT INTO schema_migrations VALUES('20240418112821'); +INSERT INTO schema_migrations VALUES('20240423102250'); +INSERT INTO schema_migrations VALUES('20240610120318'); +INSERT INTO schema_migrations VALUES('20240614085913'); +INSERT INTO schema_migrations VALUES('20240701142651'); +INSERT INTO schema_migrations VALUES('20240703103707'); +INSERT INTO schema_migrations VALUES('20240703160732'); +INSERT INTO schema_migrations VALUES('20240727113215'); +INSERT INTO schema_migrations VALUES('20240727113216'); +INSERT INTO schema_migrations VALUES('20240727113217'); +INSERT INTO schema_migrations VALUES('20240731165646'); +INSERT INTO schema_migrations VALUES('20240827155630'); +INSERT INTO schema_migrations VALUES('20240904151944'); +INSERT INTO schema_migrations VALUES('20240924122004'); +INSERT INTO schema_migrations VALUES('20240926162407'); +INSERT INTO schema_migrations VALUES('20241004194445'); +INSERT INTO schema_migrations VALUES('20241007182824'); +INSERT INTO schema_migrations VALUES('20241009122540'); +INSERT INTO schema_migrations VALUES('20241015090803'); +INSERT INTO schema_migrations VALUES('20241017093301'); +INSERT INTO schema_migrations VALUES('20241017113112'); +INSERT INTO schema_migrations VALUES('20241021124608'); +INSERT INTO schema_migrations VALUES('20241025110218'); +INSERT INTO schema_migrations VALUES('20241105121830'); +INSERT INTO schema_migrations VALUES('20241122121621'); +INSERT INTO schema_migrations VALUES('20241128162213'); +INSERT INTO schema_migrations VALUES('20241128162214'); +INSERT INTO schema_migrations VALUES('20250114105808'); +INSERT INTO schema_migrations VALUES('20250121105010'); +INSERT INTO schema_migrations VALUES('20250122171731'); +INSERT INTO schema_migrations VALUES('20250222000000'); +INSERT INTO schema_migrations VALUES('20250305171530'); +INSERT INTO schema_migrations VALUES('20250407160721'); +INSERT INTO schema_migrations VALUES('20250407160722'); +INSERT INTO schema_migrations VALUES('20250408111644'); +INSERT INTO schema_migrations VALUES('20250408145956'); +INSERT INTO schema_migrations VALUES('20250409120155'); +INSERT INTO schema_migrations VALUES('20250409125753'); +INSERT INTO schema_migrations VALUES('20250423094525'); +INSERT INTO schema_migrations VALUES('20250425104619'); +INSERT INTO schema_migrations VALUES('20250520111046'); +INSERT INTO schema_migrations VALUES('20250609210440'); +INSERT INTO schema_migrations VALUES('20250620141805'); +INSERT INTO schema_migrations VALUES('20250621223410'); +INSERT INTO schema_migrations VALUES('20250629212656'); +CREATE TABLE IF NOT EXISTS "ar_internal_metadata" ("key" varchar NOT NULL PRIMARY KEY, "value" varchar, "created_at" datetime(6) NOT NULL, "updated_at" datetime(6) NOT NULL); +INSERT INTO ar_internal_metadata VALUES('environment','production','2025-07-25 10:52:31.380052','2025-07-25 10:52:31.380054'); +CREATE TABLE IF NOT EXISTS "libraries" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "path" varchar NOT NULL, "created_at" datetime(6) NOT NULL, "updated_at" datetime(6) NOT NULL, "notes" varchar, "caption" varchar, "name" varchar, "tag_regex" text, "icon" text, "storage_service" varchar DEFAULT 'filesystem' NOT NULL, "s3_endpoint" varchar DEFAULT NULL, "s3_region" varchar DEFAULT NULL, "s3_bucket" varchar DEFAULT NULL, "s3_access_key_id" varchar DEFAULT NULL, "s3_secret_access_key" varchar DEFAULT NULL, "public_id" varchar, "s3_path_style" boolean DEFAULT 1 NOT NULL); +CREATE TABLE IF NOT EXISTS "tags" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "name" varchar, "created_at" datetime, "updated_at" datetime, "taggings_count" integer DEFAULT 0); +CREATE TABLE IF NOT EXISTS "taggings" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "tag_id" integer, "taggable_type" varchar, "taggable_id" integer, "tagger_type" varchar, "tagger_id" integer, "context" varchar(128), "created_at" datetime, CONSTRAINT "fk_rails_9fcd2e236b" +FOREIGN KEY ("tag_id") + REFERENCES "tags" ("id") +); +CREATE TABLE IF NOT EXISTS "links" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "url" varchar, "linkable_type" varchar, "linkable_id" integer, "created_at" datetime(6) NOT NULL, "updated_at" datetime(6) NOT NULL); +CREATE TABLE IF NOT EXISTS "settings" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "var" varchar NOT NULL, "value" text, "created_at" datetime(6) NOT NULL, "updated_at" datetime(6) NOT NULL); +INSERT INTO settings VALUES(1,'default_library',replace('--- 2\n','\n',char(10)),'2025-07-25 10:58:00.004576','2025-07-28 13:30:03.381376'); +INSERT INTO settings VALUES(2,'site_name',replace('--- XRForge\n','\n',char(10)),'2025-07-25 10:59:04.496016','2025-07-25 10:59:04.496016'); +INSERT INTO settings VALUES(3,'site_tagline',replace('--- Selfsovereign XR Experiences based on 3D files & URLs\n','\n',char(10)),'2025-07-25 10:59:04.519264','2025-07-25 10:59:04.519264'); +INSERT INTO settings VALUES(4,'theme','vapor','2025-07-25 10:59:04.522670','2025-07-28 13:47:54.690364'); +INSERT INTO settings VALUES(5,'about',replace('--- ''''\n','\n',char(10)),'2025-07-25 10:59:04.527612','2025-07-25 10:59:04.527612'); +INSERT INTO settings VALUES(6,'rules',replace('--- ''''\n','\n',char(10)),'2025-07-25 10:59:04.531378','2025-07-25 10:59:04.531378'); +INSERT INTO settings VALUES(7,'support_link',replace('--- https://forgejo.isvery.ninja/coderofsalvation/xrforge\n','\n',char(10)),'2025-07-25 10:59:04.533678','2025-07-25 10:59:04.533678'); +INSERT INTO settings VALUES(8,'site_icon',replace('--- ''''\n','\n',char(10)),'2025-07-25 10:59:04.536228','2025-07-25 14:19:06.192651'); +CREATE TABLE IF NOT EXISTS "problems" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "problematic_type" varchar, "problematic_id" integer, "category" integer, "created_at" datetime(6) NOT NULL, "updated_at" datetime(6) NOT NULL, "note" varchar DEFAULT NULL, "ignored" boolean DEFAULT 0 NOT NULL, "public_id" varchar, "in_progress" boolean DEFAULT 0 NOT NULL); +CREATE TABLE IF NOT EXISTS "favorites" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "favoritable_type" varchar NOT NULL, "favoritable_id" integer NOT NULL, "favoritor_type" varchar NOT NULL, "favoritor_id" integer NOT NULL, "scope" varchar DEFAULT 'printed' NOT NULL, "blocked" boolean DEFAULT 0 NOT NULL, "created_at" datetime(6) NOT NULL, "updated_at" datetime(6) NOT NULL); +CREATE TABLE IF NOT EXISTS "flipper_features" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "key" varchar NOT NULL, "created_at" datetime(6) NOT NULL, "updated_at" datetime(6) NOT NULL); +CREATE TABLE IF NOT EXISTS "flipper_gates" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "feature_key" varchar NOT NULL, "key" varchar NOT NULL, "value" text, "created_at" datetime(6) NOT NULL, "updated_at" datetime(6) NOT NULL); +CREATE TABLE IF NOT EXISTS "roles" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "name" varchar, "resource_type" varchar, "resource_id" integer, "created_at" datetime(6) NOT NULL, "updated_at" datetime(6) NOT NULL); +INSERT INTO roles VALUES(1,'administrator',NULL,NULL,'2025-07-25 10:52:35.066502','2025-07-25 10:52:35.066502'); +INSERT INTO roles VALUES(2,'moderator',NULL,NULL,'2025-07-25 10:52:35.079751','2025-07-25 10:52:35.079751'); +INSERT INTO roles VALUES(3,'contributor',NULL,NULL,'2025-07-25 10:52:35.081798','2025-07-25 10:52:35.081798'); +INSERT INTO roles VALUES(4,'member',NULL,NULL,'2025-07-25 10:52:35.083068','2025-07-25 10:52:35.083068'); +CREATE TABLE IF NOT EXISTS "users_roles" ("user_id" integer, "role_id" integer); +INSERT INTO users_roles VALUES(1,4); +INSERT INTO users_roles VALUES(1,1); +CREATE TABLE IF NOT EXISTS "users" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "email" varchar DEFAULT '' NOT NULL, "encrypted_password" varchar DEFAULT '' NOT NULL, "created_at" datetime(6) NOT NULL, "updated_at" datetime(6) NOT NULL, "username" varchar NOT NULL, "pagination_settings" json DEFAULT '{"models":true,"creators":true,"collections":true,"per_page":12}', "renderer_settings" json DEFAULT '{"grid_width":200,"grid_depth":200,"show_grid":true,"enable_pan_zoom":false,"background_colour":"#000000","object_colour":"#ffffff","render_style":"original"}', "tag_cloud_settings" json DEFAULT '{"threshold":2,"heatmap":true,"keypair":true,"sorting":"frequency"}', "problem_settings" json DEFAULT '{"missing":"danger","empty":"info","nesting":"warning","inefficient":"info","duplicate":"warning","no_image":"silent","no_3d_model":"silent","non_manifold":"warning","inside_out":"warning","no_license":"silent","no_links":"silent","no_creator":"silent","no_tags":"silent"}', "file_list_settings" json DEFAULT '{"hide_presupported_versions":true}', "reset_password_token" varchar, "remember_created_at" datetime(6), "reset_password_sent_at" datetime(6), "interface_language" varchar, "failed_attempts" integer DEFAULT 0 NOT NULL, "locked_at" datetime(6), "auth_provider" varchar, "auth_uid" varchar, "sensitive_content_handling" varchar DEFAULT NULL, "public_id" varchar, "approved" boolean DEFAULT 1 NOT NULL, "quota" integer DEFAULT 1 NOT NULL, "quota_use_site_default" boolean DEFAULT 1 NOT NULL); +INSERT INTO users VALUES(1,'xrforge@localhost','$2a$12$u/j8LRzbPiJRHmi1eV/fvOXXiKxN2vBGtNd.Pt28w.wOnq3rnfpzO','2025-07-25 10:52:56.989975','2025-07-25 12:46:27.338917','xrforge','{"models":true,"creators":true,"collections":true,"per_page":12}','{"grid_width":200,"grid_depth":200,"show_grid":true,"enable_pan_zoom":false,"background_colour":"#000000","object_colour":"#ffffff","render_style":"original"}','{"threshold":2,"heatmap":true,"keypair":true,"sorting":"frequency"}','{"missing":"danger","empty":"info","nesting":"warning","inefficient":"info","duplicate":"warning","no_image":"silent","no_3d_model":"silent","non_manifold":"warning","inside_out":"warning","no_license":"silent","no_links":"silent","no_creator":"silent","no_tags":"silent"}','{"hide_presupported_versions":true}',NULL,'2025-07-25 12:46:27.325287',NULL,NULL,0,NULL,NULL,NULL,NULL,'71863vkppj6k',1,1,1); +CREATE TABLE IF NOT EXISTS "federails_followings" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "actor_id" integer NOT NULL, "target_actor_id" integer NOT NULL, "status" integer DEFAULT 0, "federated_url" varchar, "created_at" datetime(6) NOT NULL, "updated_at" datetime(6) NOT NULL, "uuid" varchar DEFAULT NULL, CONSTRAINT "fk_rails_2e62338faa" +FOREIGN KEY ("actor_id") + REFERENCES "federails_actors" ("id") +, CONSTRAINT "fk_rails_4a2870c181" +FOREIGN KEY ("target_actor_id") + REFERENCES "federails_actors" ("id") +); +CREATE TABLE IF NOT EXISTS "federails_activities" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "entity_type" varchar NOT NULL, "entity_id" integer NOT NULL, "action" varchar NOT NULL, "actor_id" integer NOT NULL, "created_at" datetime(6) NOT NULL, "updated_at" datetime(6) NOT NULL, "uuid" varchar DEFAULT NULL, CONSTRAINT "fk_rails_85ef6259df" +FOREIGN KEY ("actor_id") + REFERENCES "federails_actors" ("id") +); +CREATE TABLE IF NOT EXISTS "caber_relations" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "subject_type" varchar, "subject_id" integer, "permission" varchar, "object_type" varchar NOT NULL, "object_id" integer NOT NULL, "created_at" datetime(6) NOT NULL, "updated_at" datetime(6) NOT NULL); +CREATE TABLE IF NOT EXISTS "federails_moderation_reports" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "federated_url" varchar, "federails_actor_id" integer, "content" varchar, "object_type" varchar, "object_id" integer, "resolved_at" datetime(6), "resolution" varchar, "created_at" datetime(6) NOT NULL, "updated_at" datetime(6) NOT NULL, CONSTRAINT "fk_rails_a5cda24d4c" +FOREIGN KEY ("federails_actor_id") + REFERENCES "federails_actors" ("id") +); +CREATE TABLE IF NOT EXISTS "federails_moderation_domain_blocks" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "domain" varchar NOT NULL, "created_at" datetime(6) NOT NULL, "updated_at" datetime(6) NOT NULL); +CREATE TABLE IF NOT EXISTS "comments" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "public_id" varchar NOT NULL, "commenter_type" varchar, "commenter_id" integer, "commentable_type" varchar NOT NULL, "commentable_id" integer NOT NULL, "comment" text, "created_at" datetime(6) NOT NULL, "updated_at" datetime(6) NOT NULL, "system" boolean DEFAULT 0 NOT NULL, "sensitive" boolean DEFAULT 0 NOT NULL, "federated_url" varchar, "federails_actor_id" integer, CONSTRAINT "fk_rails_3a181ceff0" +FOREIGN KEY ("federails_actor_id") + REFERENCES "federails_actors" ("id") +); +CREATE TABLE IF NOT EXISTS "oauth_applications" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "name" varchar NOT NULL, "uid" varchar NOT NULL, "secret" varchar NOT NULL, "redirect_uri" text, "scopes" varchar DEFAULT '' NOT NULL, "confidential" boolean DEFAULT 1 NOT NULL, "created_at" datetime(6) NOT NULL, "updated_at" datetime(6) NOT NULL, "owner_id" bigint, "owner_type" varchar); +CREATE TABLE IF NOT EXISTS "oauth_access_grants" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "resource_owner_id" integer NOT NULL, "application_id" integer NOT NULL, "token" varchar NOT NULL, "expires_in" integer NOT NULL, "redirect_uri" text NOT NULL, "scopes" varchar DEFAULT '' NOT NULL, "created_at" datetime(6) NOT NULL, "revoked_at" datetime(6), CONSTRAINT "fk_rails_b4b53e07b8" +FOREIGN KEY ("application_id") + REFERENCES "oauth_applications" ("id") +, CONSTRAINT "fk_rails_330c32d8d9" +FOREIGN KEY ("resource_owner_id") + REFERENCES "users" ("id") +); +CREATE TABLE IF NOT EXISTS "oauth_access_tokens" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "resource_owner_id" integer, "application_id" integer NOT NULL, "token" varchar NOT NULL, "refresh_token" varchar, "expires_in" integer, "scopes" varchar, "created_at" datetime(6) NOT NULL, "revoked_at" datetime(6), "previous_refresh_token" varchar DEFAULT '' NOT NULL, CONSTRAINT "fk_rails_732cb83ab7" +FOREIGN KEY ("application_id") + REFERENCES "oauth_applications" ("id") +, CONSTRAINT "fk_rails_ee63f25419" +FOREIGN KEY ("resource_owner_id") + REFERENCES "users" ("id") +); +CREATE TABLE IF NOT EXISTS "federails_actors" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "name" varchar, "federated_url" varchar, "username" varchar, "server" varchar, "inbox_url" varchar, "outbox_url" varchar, "followers_url" varchar, "followings_url" varchar, "profile_url" varchar, "entity_id" integer, "created_at" datetime(6) NOT NULL, "updated_at" datetime(6) NOT NULL, "entity_type" varchar DEFAULT NULL, "public_key" text, "private_key" text, "uuid" varchar, "extensions" json, "local" boolean DEFAULT 0 NOT NULL, "actor_type" varchar, "tombstoned_at" datetime(6)); +INSERT INTO federails_actors VALUES(1,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,1,'2025-07-25 10:52:57.029315','2025-07-25 10:52:57.029315','User',NULL,NULL,'eb64d114-1bc7-4cb3-8be6-350d23ccfb3e',NULL,1,NULL,NULL); +CREATE TABLE IF NOT EXISTS "model_files" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "filename" varchar, "model_id" integer NOT NULL, "created_at" datetime(6) NOT NULL, "updated_at" datetime(6) NOT NULL, "presupported" boolean DEFAULT 0 NOT NULL, "y_up" boolean DEFAULT 0 NOT NULL, "digest" varchar, "notes" text, "caption" text, "size" bigint, "presupported_version_id" integer, "attachment_data" json, "public_id" varchar, "filename_lower" varchar GENERATED ALWAYS AS (LOWER(filename)) STORED, "previewable" boolean DEFAULT 0 NOT NULL, CONSTRAINT "fk_rails_b5ac05b6e3" +FOREIGN KEY ("presupported_version_id") + REFERENCES "model_files" ("id") +, CONSTRAINT "fk_rails_8e378ff647" +FOREIGN KEY ("model_id") + REFERENCES "models" ("id") +); +CREATE TABLE IF NOT EXISTS "altcha_solutions" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "algorithm" varchar, "challenge" varchar, "salt" varchar, "signature" varchar, "number" integer, "created_at" datetime(6) NOT NULL, "updated_at" datetime(6) NOT NULL); +CREATE TABLE IF NOT EXISTS "models" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "name" varchar NOT NULL, "path" varchar NOT NULL, "library_id" integer NOT NULL, "created_at" datetime(6) NOT NULL, "updated_at" datetime(6) NOT NULL, "preview_file_id" integer, "creator_id" integer, "notes" text, "caption" text, "collection_id" integer, "slug" varchar, "license" varchar, "public_id" varchar, "name_lower" varchar GENERATED ALWAYS AS (LOWER(name)) STORED, "sensitive" boolean DEFAULT 0 NOT NULL, "indexable" varchar, "ai_indexable" varchar, CONSTRAINT "fk_rails_cdf016e15c" +FOREIGN KEY ("collection_id") + REFERENCES "collections" ("id") +, CONSTRAINT "fk_rails_aaa717f5bb" +FOREIGN KEY ("library_id") + REFERENCES "libraries" ("id") +, CONSTRAINT "fk_rails_3b8b50d3f3" +FOREIGN KEY ("creator_id") + REFERENCES "creators" ("id") +); +CREATE TABLE IF NOT EXISTS "creators" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "name" varchar NOT NULL, "created_at" datetime(6) NOT NULL, "updated_at" datetime(6) NOT NULL, "notes" text, "caption" text, "slug" varchar, "public_id" varchar, "name_lower" varchar GENERATED ALWAYS AS (LOWER(name)) STORED, "indexable" varchar, "ai_indexable" varchar); +CREATE TABLE IF NOT EXISTS "collections" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "name" varchar, "notes" text, "caption" text, "created_at" datetime(6) NOT NULL, "updated_at" datetime(6) NOT NULL, "collection_id" integer, "slug" varchar, "public_id" varchar, "name_lower" varchar GENERATED ALWAYS AS (LOWER(name)) STORED, "creator_id" integer, "indexable" varchar, "ai_indexable" varchar, CONSTRAINT "fk_rails_63724415e9" +FOREIGN KEY ("collection_id") + REFERENCES "collections" ("id") +, CONSTRAINT "fk_rails_ab2fec83b3" +FOREIGN KEY ("creator_id") + REFERENCES "creators" ("id") +); +DELETE FROM sqlite_sequence; +INSERT INTO sqlite_sequence VALUES('taggings',0); +INSERT INTO sqlite_sequence VALUES('users',1); +INSERT INTO sqlite_sequence VALUES('comments',0); +INSERT INTO sqlite_sequence VALUES('oauth_access_grants',0); +INSERT INTO sqlite_sequence VALUES('oauth_access_tokens',0); +INSERT INTO sqlite_sequence VALUES('federails_actors',1); +INSERT INTO sqlite_sequence VALUES('model_files',0); +INSERT INTO sqlite_sequence VALUES('models',0); +INSERT INTO sqlite_sequence VALUES('creators',0); +INSERT INTO sqlite_sequence VALUES('collections',0); +INSERT INTO sqlite_sequence VALUES('roles',4); +INSERT INTO sqlite_sequence VALUES('libraries',2); +INSERT INTO sqlite_sequence VALUES('settings',8); +CREATE UNIQUE INDEX "index_tags_on_name" ON "tags" ("name"); +CREATE UNIQUE INDEX "taggings_idx" ON "taggings" ("tag_id", "taggable_id", "taggable_type", "context", "tagger_id", "tagger_type"); +CREATE INDEX "taggings_taggable_context_idx" ON "taggings" ("taggable_id", "taggable_type", "context"); +CREATE INDEX "index_taggings_on_taggable_type" ON "taggings" ("taggable_type"); +CREATE INDEX "index_taggings_on_context" ON "taggings" ("context"); +CREATE INDEX "index_taggings_on_tagger_id_and_tagger_type" ON "taggings" ("tagger_id", "tagger_type"); +CREATE INDEX "taggings_idy" ON "taggings" ("taggable_id", "taggable_type", "tagger_id", "context"); +CREATE INDEX "index_links_on_linkable" ON "links" ("linkable_type", "linkable_id"); +CREATE UNIQUE INDEX "index_settings_on_var" ON "settings" ("var"); +CREATE INDEX "index_problems_on_problematic" ON "problems" ("problematic_type", "problematic_id"); +CREATE INDEX "index_favorites_on_favoritor" ON "favorites" ("favoritor_type", "favoritor_id"); +CREATE INDEX "index_favorites_on_scope" ON "favorites" ("scope"); +CREATE INDEX "index_favorites_on_blocked" ON "favorites" ("blocked"); +CREATE INDEX "fk_favorites" ON "favorites" ("favoritor_id", "favoritor_type"); +CREATE INDEX "fk_favoritables" ON "favorites" ("favoritable_id", "favoritable_type"); +CREATE UNIQUE INDEX "uniq_favorites__and_favoritables" ON "favorites" ("favoritable_type", "favoritable_id", "favoritor_type", "favoritor_id", "scope"); +CREATE UNIQUE INDEX "index_problems_on_category_and_problematic_id_and_type" ON "problems" ("category", "problematic_id", "problematic_type"); +CREATE UNIQUE INDEX "index_flipper_features_on_key" ON "flipper_features" ("key"); +CREATE UNIQUE INDEX "index_flipper_gates_on_feature_key_and_key_and_value" ON "flipper_gates" ("feature_key", "key", "value"); +CREATE INDEX "index_roles_on_resource" ON "roles" ("resource_type", "resource_id"); +CREATE INDEX "index_users_roles_on_role_id" ON "users_roles" ("role_id"); +CREATE INDEX "index_roles_on_name_and_resource_type_and_resource_id" ON "roles" ("name", "resource_type", "resource_id"); +CREATE INDEX "index_users_roles_on_user_id_and_role_id" ON "users_roles" ("user_id", "role_id"); +CREATE UNIQUE INDEX "index_users_on_email" ON "users" ("email"); +CREATE UNIQUE INDEX "index_users_on_username" ON "users" ("username"); +CREATE UNIQUE INDEX "index_users_on_reset_password_token" ON "users" ("reset_password_token"); +CREATE INDEX "index_federails_followings_on_target_actor_id" ON "federails_followings" ("target_actor_id"); +CREATE UNIQUE INDEX "index_federails_followings_on_actor_id_and_target_actor_id" ON "federails_followings" ("actor_id", "target_actor_id"); +CREATE INDEX "index_federails_activities_on_entity" ON "federails_activities" ("entity_type", "entity_id"); +CREATE INDEX "index_federails_activities_on_actor_id" ON "federails_activities" ("actor_id"); +CREATE INDEX "index_caber_relations_on_subject" ON "caber_relations" ("subject_type", "subject_id"); +CREATE INDEX "index_caber_relations_on_object" ON "caber_relations" ("object_type", "object_id"); +CREATE UNIQUE INDEX "idx_on_subject_id_subject_type_object_id_object_typ_a279b094be" ON "caber_relations" ("subject_id", "subject_type", "object_id", "object_type"); +CREATE INDEX "index_problems_on_public_id" ON "problems" ("public_id"); +CREATE INDEX "index_libraries_on_public_id" ON "libraries" ("public_id"); +CREATE UNIQUE INDEX "index_federails_activities_on_uuid" ON "federails_activities" ("uuid"); +CREATE UNIQUE INDEX "index_federails_followings_on_uuid" ON "federails_followings" ("uuid"); +CREATE INDEX "index_users_on_public_id" ON "users" ("public_id"); +CREATE INDEX "index_users_on_approved" ON "users" ("approved"); +CREATE INDEX "index_federails_moderation_reports_on_federails_actor_id" ON "federails_moderation_reports" ("federails_actor_id"); +CREATE INDEX "index_federails_moderation_reports_on_object" ON "federails_moderation_reports" ("object_type", "object_id"); +CREATE UNIQUE INDEX "index_federails_moderation_domain_blocks_on_domain" ON "federails_moderation_domain_blocks" ("domain"); +CREATE UNIQUE INDEX "index_comments_on_public_id" ON "comments" ("public_id"); +CREATE INDEX "index_comments_on_commenter" ON "comments" ("commenter_type", "commenter_id"); +CREATE INDEX "index_comments_on_commentable" ON "comments" ("commentable_type", "commentable_id"); +CREATE INDEX "index_comments_on_federails_actor_id" ON "comments" ("federails_actor_id"); +CREATE UNIQUE INDEX "index_oauth_applications_on_uid" ON "oauth_applications" ("uid"); +CREATE INDEX "index_oauth_access_grants_on_resource_owner_id" ON "oauth_access_grants" ("resource_owner_id"); +CREATE INDEX "index_oauth_access_grants_on_application_id" ON "oauth_access_grants" ("application_id"); +CREATE UNIQUE INDEX "index_oauth_access_grants_on_token" ON "oauth_access_grants" ("token"); +CREATE INDEX "index_oauth_access_tokens_on_resource_owner_id" ON "oauth_access_tokens" ("resource_owner_id"); +CREATE INDEX "index_oauth_access_tokens_on_application_id" ON "oauth_access_tokens" ("application_id"); +CREATE UNIQUE INDEX "index_oauth_access_tokens_on_token" ON "oauth_access_tokens" ("token"); +CREATE UNIQUE INDEX "index_oauth_access_tokens_on_refresh_token" ON "oauth_access_tokens" ("refresh_token"); +CREATE INDEX "index_oauth_applications_on_owner_id_and_owner_type" ON "oauth_applications" ("owner_id", "owner_type"); +CREATE UNIQUE INDEX "index_federails_actors_on_federated_url" ON "federails_actors" ("federated_url"); +CREATE UNIQUE INDEX "index_federails_actors_on_entity" ON "federails_actors" ("entity_type", "entity_id"); +CREATE UNIQUE INDEX "index_federails_actors_on_uuid" ON "federails_actors" ("uuid"); +CREATE INDEX "index_model_files_on_model_id" ON "model_files" ("model_id"); +CREATE INDEX "index_model_files_on_digest" ON "model_files" ("digest"); +CREATE INDEX "index_model_files_on_presupported_version_id" ON "model_files" ("presupported_version_id"); +CREATE UNIQUE INDEX "index_model_files_on_filename_and_model_id" ON "model_files" ("filename", "model_id"); +CREATE INDEX "index_model_files_on_public_id" ON "model_files" ("public_id"); +CREATE INDEX "index_model_files_on_filename_lower" ON "model_files" ("filename_lower"); +CREATE INDEX "index_links_on_linkable_id_and_linkable_type_and_url" ON "links" ("linkable_id", "linkable_type", "url"); +CREATE UNIQUE INDEX "index_altcha_solutions" ON "altcha_solutions" ("algorithm", "challenge", "salt", "signature", "number"); +CREATE INDEX "index_models_on_library_id" ON "models" ("library_id"); +CREATE INDEX "index_models_on_creator_id" ON "models" ("creator_id"); +CREATE INDEX "index_models_on_preview_file_id" ON "models" ("preview_file_id"); +CREATE INDEX "index_models_on_collection_id" ON "models" ("collection_id"); +CREATE INDEX "index_models_on_slug" ON "models" ("slug"); +CREATE UNIQUE INDEX "index_models_on_path_and_library_id" ON "models" ("path", "library_id"); +CREATE INDEX "index_models_on_public_id" ON "models" ("public_id"); +CREATE INDEX "index_models_on_name_lower" ON "models" ("name_lower"); +CREATE UNIQUE INDEX "index_creators_on_name" ON "creators" ("name"); +CREATE UNIQUE INDEX "index_creators_on_slug" ON "creators" ("slug"); +CREATE INDEX "index_creators_on_public_id" ON "creators" ("public_id"); +CREATE INDEX "index_creators_on_name_lower" ON "creators" ("name_lower"); +CREATE INDEX "index_collections_on_collection_id" ON "collections" ("collection_id"); +CREATE UNIQUE INDEX "index_collections_on_name" ON "collections" ("name"); +CREATE UNIQUE INDEX "index_collections_on_slug" ON "collections" ("slug"); +CREATE INDEX "index_collections_on_public_id" ON "collections" ("public_id"); +CREATE INDEX "index_collections_on_name_lower" ON "collections" ("name_lower"); +CREATE INDEX "index_collections_on_creator_id" ON "collections" ("creator_id"); +CREATE INDEX "index_models_on_created_at" ON "models" ("created_at"); +CREATE INDEX "index_models_on_updated_at" ON "models" ("updated_at"); +CREATE INDEX "index_creators_on_created_at" ON "creators" ("created_at"); +CREATE INDEX "index_creators_on_updated_at" ON "creators" ("updated_at"); +CREATE INDEX "index_collections_on_created_at" ON "collections" ("created_at"); +CREATE INDEX "index_collections_on_updated_at" ON "collections" ("updated_at"); +COMMIT; diff --git a/nix/docker.nix b/nix/docker.nix index 3445ca7..a00a1d7 100644 --- a/nix/docker.nix +++ b/nix/docker.nix @@ -16,22 +16,34 @@ let }; in +rec { - foo = pkgs.dockerTools.buildImage { + + xrforgeImage = pkgs.dockerTools.buildImage { name = "xrforge"; tag = "latest"; + created = "now"; fromImage = manyfoldImage; # add nix pkgs + local files - copyToRoot = pkgs.buildEnv { + contents = pkgs.buildEnv { name = "image-root"; pathsToLink = ["/manyfold" "/bin"]; - paths = [pkgs.git ./..]; + paths = [ + pkgs.pkgsStatic.rsync + pkgs.pkgsStatic.sqlite + pkgs.pkgsStatic.rclone + pkgs.pkgsStatic.fuse3 + ./.. + ]; }; config = { - Cmd = ["${pkgsLinux.hello}/bin/hello" ]; + Cmd = ["/init"]; + # We substitute the /init entrypoing with our own wrapper + EntryPoint = ["/manyfold/cli/manyfold.sh" "boot"]; }; }; + } diff --git a/nix/shell.nix b/nix/shell.nix index ee99b68..1cfbdc9 100644 --- a/nix/shell.nix +++ b/nix/shell.nix @@ -1,13 +1,32 @@ -{ pkgs ? import {} }: - pkgs.mkShell { +#let +# pkgs = import (builtins.fetchGit { +# name = "nixos-25.05"; +# url = "https://github.com/nixos/nixpkgs/"; +# ref = "refs/heads/nixos-unstable"; +# rev = "ef99fa5c5ed624460217c31ac4271cfb5cb2502c"; +# }) {}; + + + +{ pkgs ? import {} } : +{ + + #pkgs = import (builtins.fetchGit { + # name = "nixos-25.05"; + # url = "https://github.com/nixos/nixpkgs"; + # rev = "11cb3517b3af6af300dd6c055aeda73c9bf52c48"; + #}) {}; + + foo = pkgs.mkShell { # nativeBuildInputs is usually what you want -- tools you need to run nativeBuildInputs = with pkgs.buildPackages; [ monolith nodejs_22 nixos-generators - qemu + #qemu + sqlite ]; @@ -16,18 +35,27 @@ echo "available commands:" echo "" + echo " # build 'xrforge' docker image" + echo " nix-build nix/docker.nix" echo "" - echo "nix-build nix/xrforge.nix" - echo "nixos-generate -f -c nix/server.nix # generate server-image for ~32 hyperscalers" - echo " # see https://mynixos.com/nixos-generators" - echo "example:" - echo " $ nixos-generate -f iso -c nix/server.nix + echo " # generate server-image for ~32 hyperscalers, see https://mynixos.com/nixos-generators" + echo " nixos-generate -f -c nix/server.nix" + echo "" + echo " # use database of running container as default db for container" + echo " docker exec xrforge sqlite3 /config/manyfold.sqlite3 .dump > manyfold/manyfold.sql && nix-build nix/docker.nix" + echo "" + echo "examples:" + echo "" + echo " $ nixos-generate -f iso -c nix/server.nix" echo " $ qemu-system-x86_64 -cdrom " # test/run image echo "" - echo " $ docker load < $(nix-build nix/docker.nix)" - echo " $ docker run -t hello-docker:y74sb4nrhxr975xs7h83izgm8z75x5fc" + echo " $ docker load < \$(nix-build nix/docker.nix)" + echo " $ docker run xrforge" + echo "" ''; + }; + + } -