A metadata editor for reviewers of research data at GFZ Helmholtz Centre for Geosciences.
🎉 Second Release Candidate (v1.0.0rc2) – This is the second release candidate of ERNIE, featuring complete core metadata curation functionality, DOI registration workflows, and comprehensive testing. See the interactive changelog for full release notes.
- DataCite v4.7 Metadata Editor – Complete support for DOI registration with all mandatory and recommended fields
- Role-Based Access Control – Four-tier permission system (Admin, Group Leader, Curator, Beginner)
- IGSN Support – Physical sample registration with CSV import and hierarchical relationships
- ORCID & ROR Integration – Researcher identification and institutional affiliation lookup
- Controlled Vocabularies – NASA GCMD (Science Keywords, Platforms, Instruments) and MSL keywords
- Interactive Google Maps – Spatial coverage with point, bounding box, and polygon support
- XML Import – Automatic metadata extraction from DataCite XML / ELMO exports
- Legacy Dataset Browser – Import metadata from previous database systems
- Landing Page Management – Create, preview, and publish dataset landing pages
- REST API – OpenAPI 3.1 specification with interactive Swagger UI at
/api/v1/doc - Accessible Design – WCAG 2.1 AA compliant with Radix UI and Axe-core testing
📖 View detailed user documentation at /docs
- PHP 8.2+ with required extensions:
- Core:
ctype,curl,dom,fileinfo,filter,hash,iconv,json,libxml,mbstring,openssl,tokenizer,xml,xmlwriter - Database:
pdo,pdo_mysql - Additional:
intl,simplexml,sodium,xsl
- Core:
- Node.js 24 and npm
- MySQL 8.0+ or MariaDB 10.6+
- Composer 2.x
-
Clone the repository and switch to the project directory:
git clone https://github.com/McNamara84/ernie.git cd ernie -
Install dependencies:
composer install npm install
-
Configure environment:
cp .env.example .env php artisan key:generate
-
Update
.envwith your database credentials and other settings -
Run database migrations:
php artisan migrate
-
Create your first admin user:
php artisan add-user "Admin Name" admin@example.com SecurePassword123Note: The first user created automatically becomes an admin.
-
Build frontend assets:
npm run build
-
Start the development server:
composer run dev
This command starts three concurrent processes:
- Laravel development server (
php artisan serve) - Queue worker (
php artisan queue:listen) - Vite dev server (
npm run dev)
Alternatively, for SSR (Server-Side Rendering) support:
composer run dev:ssr
- Laravel development server (
Add to .env:
GM_API_KEY=your_api_key_hereERNIE uses the ORCID Public API for read-only access to researcher profiles. No authentication is required:
ORCID_API_URL=https://pub.orcid.org/v3.0
ORCID_SEARCH_URL=https://pub.orcid.org/v3.0/searchAdd to config/database.php and .env:
DB_OLD_CONNECTION=mysql
DB_OLD_HOST=127.0.0.1
DB_OLD_PORT=3306
DB_OLD_DATABASE=old_database
DB_OLD_USERNAME=root
DB_OLD_PASSWORD=Add to .env:
ERNIE_API_KEY=your_api_key_hereWhen visitors send messages via the landing page contact form, the data publication team receives a Cc copy. Configure the recipient email:
LANDING_PAGE_CONTACT_CC_EMAIL=datapub@gfz.deSet to empty string to disable Cc notifications.
ERNIE uses a closed application model – there is no public registration. Users must be created via command line by administrators.
php artisan add-user {name} {email} {password}Examples:
# Create the first user (automatically becomes admin)
php artisan add-user "Jane Doe" jane@example.com SecurePass123
# Create additional users (default role: beginner)
php artisan add-user "John Smith" john@example.com AnotherPass456Important Notes:
- The first user created in the system automatically receives the
adminrole - All subsequent users receive the
beginnerrole by default - Admins and Group Leaders can change user roles via the
/usersinterface - User ID 1 is system-protected and cannot be modified or deactivated
📖 View detailed user management documentation at /docs
php artisan spdx:sync-licenses # Sync SPDX licenses
php artisan get-gcmd-science-keywords # Fetch GCMD Science Keywords
php artisan get-gcmd-platforms # Fetch GCMD Platforms
php artisan get-gcmd-instruments # Fetch GCMD Instruments
php artisan get-msl-keywords # Fetch MSL Keywords
php artisan get-ror-ids # Sync ROR AffiliationsThe project includes a complete Docker development environment that mirrors the production setup with Traefik reverse proxy and /ernie/ URL prefix.
- Docker Desktop installed and running
- OpenSSL (included with Git for Windows or install separately)
-
Generate SSL certificates (first time only):
# Windows PowerShell .\docker\generate-certs.ps1 # Or using Git Bash / WSL ./docker/generate-certs.sh
-
Create environment file:
Copy-Item .env.docker.example .env.dockerEdit
.env.dockeras needed (defaults work out of the box). -
Start the development environment:
docker-compose -f docker-compose.dev.yml up --build
-
Access the application:
- Application (recommended / stage-like): https://ernie.localhost:3333/
- Application (fallback): https://localhost:3333/
- Traefik Dashboard: http://localhost:8080
If
ernie.localhostdoes not resolve on your system, add it to your hosts file (Windows:C:\Windows\System32\drivers\etc\hosts) as127.0.0.1 ernie.localhost.Note: The dev stack uses
SESSION_DOMAIN=ernie.localhostby default. If you experience419 Page Expirederrors on login, this may be due to browser cookie handling for the.localhostTLD. Try accessing viahttps://localhost:3333/as a fallback, or adjustERNIE_DEV_SESSION_DOMAINin your environment. -
Run initial setup (first time or after database reset):
docker exec ernie-app-dev php artisan migrate docker exec ernie-app-dev php artisan add-user "Admin Name" admin@example.com SecurePassword docker exec ernie-app-dev php artisan spdx:sync-licenses
The Docker development environment includes:
| Service | Container | Purpose | Port |
|---|---|---|---|
| Traefik | ernie-traefik |
Reverse proxy with SSL termination | 3333 (HTTPS), 8080 (Dashboard) |
| PHP-FPM | ernie-app-dev |
Laravel application | 9000 (internal) |
| Nginx | ernie-webserver-dev |
Web server | 80 (internal) |
| Vite | ernie-vite-dev |
HMR dev server | 5173 (internal) |
| MySQL | ernie-db-dev |
Database | 3306 |
| Redis | ernie-redis-dev |
Cache & Sessions | 6379 |
| Queue | ernie-queue-dev |
Background jobs | - |
The development environment uses subdomain-based routing:
-
Recommended (stage/prod-like):
https://ernie.localhost:3333/→ Main application
-
Fallback:
https://localhost:3333/→ Main applicationhttps://localhost:3333/api/v1/→ API endpointshttps://localhost:3333/@vite/→ Vite HMR (proxied)
This mirrors the production URL https://ernie.rz-vm182.gfz.de/.
To avoid browser security warnings:
- Open
docker\traefik\certs\localhost.crt - Click "Install Certificate"
- Select "Local Machine"
- Choose "Place all certificates in the following store"
- Browse → "Trusted Root Certification Authorities"
- Click Finish
Or run as Administrator:
Import-Certificate -FilePath ".\docker\traefik\certs\localhost.crt" -CertStoreLocation Cert:\LocalMachine\RootIf you run the Docker dev stack via Traefik on https://ernie.localhost:3333, use:
npm run test:e2e:devstackThis uses playwright.devstack.config.ts and does not affect CI.
# Start environment
docker-compose -f docker-compose.dev.yml up -d
# View logs (all services)
docker-compose -f docker-compose.dev.yml logs -f
# View logs (specific service)
docker-compose -f docker-compose.dev.yml logs -f app
# Run artisan commands
docker exec ernie-app-dev php artisan <command>
# Run composer commands
docker exec ernie-app-dev composer <command>
# Run npm commands
docker exec ernie-vite-dev npm <command>
# Stop environment
docker-compose -f docker-compose.dev.yml down
# Reset database (removes volumes)
docker-compose -f docker-compose.dev.yml down -vXdebug is pre-installed but disabled by default. To enable:
-
Edit
.env.docker:XDEBUG_MODE=debug
-
Restart the app container:
docker-compose -f docker-compose.dev.yml restart app
-
Configure VS Code with PHP Debug extension (default port: 9003)
Certificate errors in browser: Ensure you've trusted the self-signed certificate (see above).
"Connection refused" errors: Wait for all containers to be healthy. Check status with:
docker-compose -f docker-compose.dev.yml psDatabase migration fails: The database needs time to initialize. Wait 30 seconds and retry:
docker exec ernie-app-dev php artisan migrateHot reload not working: Ensure the Vite container is running and check Traefik routes:
docker-compose -f docker-compose.dev.yml logs viteThe project includes Docker configuration for production deployment with multi-stage builds and optimized images.
-
Build the Docker image:
docker-compose -f docker-compose.prod.yml build
-
Start the containers:
docker-compose -f docker-compose.prod.yml up -d
-
Run initial setup inside the container:
docker-compose -f docker-compose.prod.yml exec app php artisan migrate docker-compose -f docker-compose.prod.yml exec app php artisan add-user "Admin Name" admin@example.com SecurePassword docker-compose -f docker-compose.prod.yml exec app php artisan spdx:sync-licenses
The production Docker setup includes:
- PHP-FPM 8.4+ with all required extensions
- Nginx web server with optimized configuration
- MySQL 8.0 database server
- Redis for caching
- Traefik integration via labels (external Traefik required)
- Persistent volumes for storage and database
- Health checks for all services
View logs:
docker-compose -f docker-compose.prod.yml logs -fStop containers:
docker-compose -f docker-compose.prod.yml downRemove volumes (
docker-compose -f docker-compose.prod.yml down -v# PHP Tests (Pest + Laravel)
composer run test # Run all PHP tests
php artisan test --coverage # With coverage
# JavaScript Tests (Vitest)
npm test # Run all JS tests
npm test -- --coverage # With coverage
# E2E Tests (Playwright)
npx playwright install # Install browsers (first time)
npm run test:e2e # Run all E2E tests
npm run test:e2e:ui # Interactive UI modeERNIE provides a read-only REST API (OpenAPI 3.1.0) for integration with external systems like ELMO.
📖 View Interactive API Documentation
The API includes:
- Metadata types (resource types, title types, licenses, languages, roles)
- NASA GCMD controlled vocabularies
- ROR affiliations and ORCID search endpoints
- API key authentication via
X-API-Keyheader
- Fork the repository and create a feature branch from
main - Make changes following code style standards (PSR-12, ESLint + Prettier)
- Run quality checks before committing:
./vendor/bin/pint # PHP code style ./vendor/bin/phpstan analyse # Static analysis (Level 8) npm run lint # ESLint + Prettier npm run types # TypeScript check composer run test && npm test # All tests
- Commit using Conventional Commits (e.g.,
feat: add feature) - Open a Pull Request
All PRs are automatically checked for code style, static analysis, test coverage, and accessibility.
This project is licensed under the GNU General Public License v3.0 or later (GPL-3.0-or-later).
For detailed information about changes in each release, visit the interactive changelog at /changelog.
Developed at GFZ German Research Centre for Geosciences – Helmholtz Centre Potsdam.
This project integrates with:
- DataCite metadata schema v4.7
- NASA GCMD controlled vocabularies
- Research Organization Registry (ROR) for institutional identifiers
- ORCID Public API for researcher identification
- SPDX License List for standardized license identifiers
- MSL Materials Science and Engineering vocabulary