This is a clone of Screenly/Anthias — open-source digital signage player. Deployed on Raspberry Pi 4 via Docker with pre-built images from Docker Hub.
| Machine | IP | Role |
|---|---|---|
| Local (this machine) | 192.168.91.92 | Source repo, auto-deploy watcher |
| Raspberry Pi 4 | 192.168.91.85 | Docker host, runs Anthias player |
- Pi: Raspberry Pi 4 Model B Rev 1.5, 8GB RAM, Raspberry Pi OS
- SSH:
pi/258456 - Remote repo path:
/home/pi/screenly - User language: Ukrainian for conversation
| Container | Image | Role | Port |
|---|---|---|---|
screenly-anthias-server-1 |
screenly/anthias-server:latest-pi4-64 |
Django API + Gunicorn (port 8080 internal) | — |
screenly-anthias-nginx-1 |
screenly/anthias-nginx:latest-pi4-64 |
Reverse proxy | 80 → 80 |
screenly-anthias-viewer-1 |
screenly/anthias-viewer:latest-pi4-64 |
Qt WebView, renders to framebuffer | — |
screenly-anthias-celery-1 |
screenly/anthias-celery:latest-pi4-64 |
Celery async worker | — |
screenly-anthias-websocket-1 |
screenly/anthias-websocket:latest-pi4-64 |
WebSocket (port 9999) | — |
screenly-redis-1 |
screenly/anthias-redis:latest-pi4-64 |
Redis broker | 6379 (localhost) |
- Web UI: http://192.168.91.85
- API: http://192.168.91.85/api/v2/info
Bind mounts (code — synced from local):
/home/pi/screenly/api/→/usr/src/app/api(server)/home/pi/screenly/anthias_app/→/usr/src/app/anthias_app(server)/home/pi/screenly/lib/→/usr/src/app/lib(server)/home/pi/screenly/static/dist/→/usr/src/app/static/dist:ro(server, nginx)/home/pi/screenly/staticfiles/→/data/screenly/staticfiles(server, nginx) — auto-generated by collectstatic/home/pi/screenly/viewer/media_player.py→/usr/src/app/viewer/media_player.py:ro(viewer)
Bind mounts (config — Pi-specific, NOT synced):
/home/pi/.screenly/→/data/.screenly— config + SQLite DB/home/pi/screenly_assets/→/data/screenly_assets— uploaded media/home/pi/.asoundrc→/etc/asound.conf:ro— ALSA audio config
Docker volumes:
resin-data→/data— shared app dataredis-data→/var/lib/redis— Redis persistence
bin/start_server.sh runs ./manage.py collectstatic --clear --noinput on EVERY container start.
This DELETES everything in staticfiles/ and regenerates from:
- Image's built-in static files (admin, rest_framework, etc.)
STATICFILES_DIRS = [BASE_DIR / 'static']— which includes mountedstatic/dist/Sostatic/dist/MUST have correct built frontend files.staticfiles/is always auto-generated.
The docker-compose.yml is Pi-specific and lives ONLY on the Pi at ~/screenly/docker-compose.yml.
It is NOT synced from local (rsync uses include-based approach and does NOT include it).
NEVER use rsync --delete when syncing to Pi — it will wipe this file.
The anthias-autodeploy.service watches /home/serv/Anthias/Antias Play/ for file changes
and automatically syncs to Pi + restarts containers.
sudo systemctl status anthias-autodeploy # status
sudo systemctl stop anthias-autodeploy # stop
sudo systemctl start anthias-autodeploy # start
sudo systemctl restart anthias-autodeploy # restart
journalctl -u anthias-autodeploy -f # live logsService file: /etc/systemd/system/anthias-autodeploy.service
Script: /home/serv/Anthias/Antias Play/auto-deploy.sh
cd "/home/serv/Anthias/Antias Play"
./deploy-to-pi.sh # sync + restart
./deploy-to-pi.sh --build # npm build + sync + restart
./deploy-to-pi.sh --sync # sync only, no restartUses include-based rsync (NOT --delete!). Only syncs directories that Docker containers use:
api/,anthias_app/,anthias_django/,lib/static/dist/,static/sass/,static/src/templates/,viewer/,bin/,requirements/settings.py,manage.py,celery_tasks.py,run_gunicorn.py, etc.
NOT synced: docker-compose.yml, staticfiles/, node_modules/, .git/, tests/, dev configs
- Restart
anthias-server(runs collectstatic + starts gunicorn) - Wait for gunicorn to be ready (curl localhost:8080)
- Restart
anthias-nginx+anthias-viewer
This order prevents 502 errors (nginx starting before server is ready).
/home/pi/.asoundrcmounted as/etc/asound.conf:roin viewer container- Viewer runs as user
viewer(not root), so system-wide/etc/asound.confis needed - VLC uses
sysdefault:CARD=vc4hdmiNwith auto-detect of connected HDMI port - HDMI-A-1 = card 1 = vc4hdmi0 (connected), HDMI-A-2 = card 2 = vc4hdmi1
GET /api/v2/info # Player info (version, IP, memory, disk)
GET /api/v2/assets # List all assets
POST /api/v2/assets # Add asset (file upload or URL)
GET /api/v2/assets/{id} # Get single asset
PUT /api/v2/assets/{id} # Update asset
DEL /api/v2/assets/{id} # Delete asset
GET /api/v2/assets/order # Get playback order
POST /api/v2/assets/order # Set playback order
GET /api/v2/backup # Download DB backup
POST /api/v2/reboot # Reboot player
POST /api/v2/shutdown # Shutdown player
GET /splash-page # Splash/standby page
# SSH to Pi
ssh pi@192.168.91.85
# Container management
cd ~/screenly
docker compose ps
docker compose logs -f anthias-server
docker compose logs -f anthias-viewer
docker compose restart anthias-server
docker compose down && docker compose up -d
# Check what's inside container
docker exec screenly-anthias-server-1 head -5 /usr/src/app/anthias_app/models.py
# API test
curl -s http://192.168.91.85/api/v2/info | python3 -m json.tool
curl -s http://192.168.91.85/api/v2/assets | python3 -m json.tool
# Screenly config
cat /home/pi/.screenly/screenly.conf- Anthias Fleet Manager:
/home/serv/Anthias/anthias-fleet-manager— manages multiple Anthias players (Django+React, port 9000 on local machine) - Project CLAUDE.md:
/home/serv/Anthias/CLAUDE.md— full project context - Anthias GitHub: https://github.com/Screenly/Anthias