Troubleshooting
The errors you can meet while installing Learnio, what causes each one, and how to fix it.
For the Full Stack package
Docker is not running
failed to connect to the docker API at unix:///…/docker.sock; check if the path is correct and if the daemon is runningOlder Docker versions say "Cannot connect to the Docker daemon" instead. Either way, the Docker engine is not started.
Open Docker Desktop
Start Docker Desktop and wait until it reports that the engine is running. On Linux, start the service:
sudo systemctl start docker.Check that Docker answers
Terminaldocker infoExpected result: It prints a Server section instead of an error.
Run your start command again
docker compose up --buildfor the full stack, or yourdocker buildanddocker runfor a single app.
A port is already in use
ports are not available: exposing port TCP 0.0.0.0:3030 … bind: address already in use
Error: listen EADDRINUSE: address already in use :::3030The first line comes from Docker, the second from yarn dev. Another program already listens on 3030, 3031 or 8000: often an earlier run of Learnio, or another project's dev server.
Find what holds the port
On macOS or Linux:
Terminallsof -i :3030On Windows, in PowerShell:
Terminalnetstat -ano | findstr :3030Stop it
Close that program, or stop the earlier run: Ctrl+C in its terminal,
docker compose downin its folder, ordocker stopfor a container you started withdocker run. Then start Learnio again.Or run Learnio on other ports
With the full stack in Docker, create a file named
.envin thelearnio-lmsfolder, next todocker-compose.yml, with the port you need.SITE_PORTmoves the student site,ADMIN_PORTthe admin andAPI_PORTthe API; the addresses the apps use follow by themselves.learnio-lms/.envADMIN_PORT=3041Then run the same command again. After a failed start it picks up where it stopped:
Terminalinlearnio-lmsdocker compose up --buildExpected result: The app answers on its new port, here localhost:3041Local.
Without Docker the ports are fixed in the .env files. To move the API there, change PORT in back-end/.env, NEXT_PUBLIC_API_BASE_URL in both frontends and CORS_ORIGIN together: the three must agree. With Docker, use API_PORT instead. For a single app started with docker run, change the number on the left of -p.
The Docker build fails
The first build downloads the base images and every dependency, then builds the images. It stops with "failed to solve" and the step that failed when something gets in the way.
- No connection or a timeout: the build needs internet access. Run the command again once you are online; finished steps are cached.
- No space left on device: free space in Docker Desktop, or check what Docker uses with
docker system df. - It fails at the same step every time: rebuild without the cache, then start.
learnio-lmsdocker compose build --no-cache
docker compose upFor a single-app package, add --no-cache to your docker build command.
A first start that seems stuck is usually still seeding the demo data. The site and the admin start only once the API reports itself healthy.
Yarn says its version is 1.22
This project's package.json defines "packageManager": "yarn@4…". However the current global version of Yarn is 1.22…Each app pins Yarn 4 through Corepack. This message means Corepack is not enabled yet.
corepack enableOn Node 26, which no longer ships Corepack, install it first with npm install -g corepack. yarn install ending with "Done with warnings" is expected; a real failure ends with "Failed with errors".
The API stops before starting
✖ The API cannot start. Fix these in back-end/.env:The API checks its settings first and lists what to fix. The usual causes:
- There is no `.env` file. Create it in
back-end/withcp .env.example .env. - `JWT_SECRET` is empty, or is the example value with `NODE_ENV=production`. Generate your own secret.
- `CORS_ORIGIN` is empty with `NODE_ENV=production`. List the student site and the admin, comma separated.
- `DB_TYPE` is not `sqlite` or `mysql`.
Sign-in fails
- Check the account and the app. Staff accounts sign in to the admin at port
3031:admin@learnio.comwithAdmin@123. The demo student signs in to the student site at port3030:demo@learnio.comwithDemo@123. - Check the API's log. "The database has no accounts, so nobody can sign in" means the demo data was never added. Without Docker, run
yarn seedinback-end/. With Docker, the volume was created withSEED_DEMO_DATA=false. - "The database has no tables yet" means the schema was never created: run
yarn seedinback-end/and restart the API. - You changed the super admin's password and no longer have it: start over with fresh demo data, below.
- "That email and password combination didn't work" is the one answer for an unknown email and for a wrong password alike, so check both.
- "Too many attempts" means one address made more than 10 tries on a sign-in or password form within a minute, which a live server refuses with
429. Wait a minute and try again.
Sign-in fails
- Check the API's log. "The database has no accounts, so nobody can sign in" means the demo data was never added: run
yarn seed, or start the Docker container with-e SEED_DEMO_DATA=trueon a new volume. - "The database has no tables yet" means the schema was never created: run
yarn seedand restart the API. - Check the account. The super admin is
admin@learnio.comwithAdmin@123, the demo studentdemo@learnio.comwithDemo@123. A failed sign-in answers401with the same message whether the email or the password is wrong. - A `429` answer means one address made more than 10 tries on a sign-in, sign-up or password route within a minute. The
Retry-Afterheader says how many seconds to wait.
Sign-in fails
On the in-browser mock, any email and password sign you in as the super admin. Once you connect an API, sign in with an account that exists in it; the demo super admin is admin@learnio.com with Admin@123.
A "Sample data" notice appears
The frontend could not reach the API, so it is showing its bundled sample data instead.
Check that the API answers
Open localhost:8000/api/healthLocal. It should answer with a status of
ok.Check the frontend's API address
NEXT_PUBLIC_API_BASE_URLin the frontend's.envmust be the API's address including/api, e.g.http://localhost:8000/api.Restart the frontend
The address is compiled in. Restart
yarn devafter changing it; with Docker, rundocker compose up --buildagain.
Course images are broken after connecting R2
With R2_* keys in back-end/.env, the API serves media from your bucket, and the frontends only display images from hosts they were built to trust. Without that host, every course thumbnail shows its alt text instead of the picture.
Name your bucket's public host
With Docker, put
MEDIA_HOSTNAME=your-bucket.r2.devin a.envfile next todocker-compose.yml. Without Docker, setNEXT_PUBLIC_MEDIA_HOSTNAMEin each frontend's.env. Write the host only, withouthttps://.Rebuild the frontends
The host is compiled in. Run
docker compose up --buildagain, or restartyarn devand rebuild for production.Expected result: Course thumbnails load from your bucket.
The folder looks different
Run the commands inside the folder the ZIP extracts to. If the unzip command is missing, extract it with your file manager instead; some tools add an extra folder named after the ZIP, so move into the inner one.
| Package | Folder | Contains |
|---|---|---|
| Full Stack | learnio-lms | admin-dashboard, back-end, frontend, docker-compose.yml |
| Student site | frontend | Dockerfile, package.json, .env.example |
| Admin dashboard | admin-dashboard | Dockerfile, package.json, .env.example |
| API | back-end | Dockerfile, package.json, .env.example |
Start over with fresh demo data
This deletes your data
Everything you created locally is removed, and the demo data is seeded again.
With Docker, from the learnio-lms folder:
learnio-lmsdocker compose down -v
docker compose upWithout Docker, stop the API, then:
back-endrm -f database.sqlite && yarn seedIn PowerShell:
back-endRemove-Item database.sqlite; yarn seedRunning yarn seed again on a database you keep is not a reset: roles keep the permissions you gave them and settings keep the values you saved. Only a fresh database brings the shipped ones back.