English
English
Appearance
English
English
Appearance
This guide explains how to deploy SmartTable with Docker. Docker is the fastest way to get a complete environment running without installing Node.js or Python manually.
The official image automatically adapts to the current architecture (linux/amd64, linux/arm64):
docker run -d \
--name smarttable \
-p 80:80 \
-v smarttable_data:/app/data \
-v smarttable_uploads:/app/uploads \
-v smarttable_redis:/data/redis \
ygbinac/smarttable:latestCreate a docker-compose.yml file:
services:
smarttable:
image: ygbinac/smarttable:latest
container_name: smarttable
ports:
- "80:80"
volumes:
- smarttable_data:/app/data
- smarttable_uploads:/app/uploads
- smarttable_redis:/data/redis
- ./logs:/app/logs
restart: unless-stopped
volumes:
smarttable_data:
smarttable_uploads:
smarttable_redis:Start it with:
docker-compose up -dTo build and run from source:
# Clone the repository
git clone https://github.com/ldbinac/smart_table.git
cd smart_table
# Copy environment variables
cp .env.example .env
# Edit .env as needed
# Start all services (frontend + backend + database)
docker-compose up -d
# Check service status
docker-compose ps
# View logs
docker-compose logs -fAccess URLs after startup:
| Service | URL |
|---|---|
| Frontend | http://localhost |
| Backend API | http://localhost/api |
The unified image only exposes port 80; Nginx inside the container proxies
/apito the backend on port 5000, which is not mapped to the host. The Swagger API docs (/apidocs) are only reachable in a standalone backend deployment where port 5000 is directly accessible.
For production, use the full stack with PostgreSQL and Redis:
docker-compose -f docker-compose.full.yml up -dsmart_table/
├── docker-compose.yml # Simple deploy (SQLite + embedded Redis)
├── docker-compose.full.yml # Production (PostgreSQL + Redis + MinIO)
├── Dockerfile # Frontend build + backend + Nginx + Supervisor
├── smarttable-backend/
│ ├── Dockerfile # Backend application (standalone)
│ └── docker-compose.yml # Backend standalone orchestration (PostgreSQL + Redis)
└── docker/
├── nginx/
│ └── nginx.conf # Nginx configuration
├── supervisor/
│ └── supervisord.conf # Process manager configuration
├── redis/
│ └── redis.conf # Redis configuration
├── server_runner.py # Eventlet WSGI launcher
└── entrypoint.sh # Container entrypoint scriptKey variables are documented in .env.example and smarttable-backend/.env.example.
| Variable | Description | Default | Required |
|---|---|---|---|
SECRET_KEY | Flask secret key | — | Yes (production) |
JWT_SECRET_KEY | JWT secret key | — | Yes (production) |
DATABASE_URL | Database connection | sqlite:///data/smarttable.db | No |
REDIS_URL | Redis address | redis://localhost:6379/0 | No |
ENABLE_REALTIME | Enable real-time collaboration | false | No |
CORS_ORIGINS | Allowed cross-origin origins (comma separated) | Local origins | Recommended (production) |
LOG_LEVEL | Log level | INFO | No |
Note: SMTP email settings are not environment variables — they are maintained in the admin console under System Settings. The MinIO variables (
MINIO_ENDPOINTetc.) have no implemented functionality yet and can be ignored.
For a full list, see Configuration.
Inside the container, Supervisor manages three processes: nginx, app-server and redis. Logs are organized in four layers:
| Layer | Location | Contents |
|---|---|---|
| Container stdout | docker logs | Container startup, database migration, Supervisor output |
| Supervisor process logs | /var/log/supervisor/*.log inside the container | Backend stack traces, per-process output |
| Application logs | /app/logs/smarttable.log (can be mounted to ./logs on the host) | Business logs written by the Flask app.logger |
| Nginx logs | /var/log/nginx/ inside the container | HTTP access records, reverse proxy errors |
docker logs smarttable # Full log
docker logs -f smarttable # Follow in real time
docker logs --tail=200 smarttable # Last 200 lines
docker logs --previous smarttable # Logs of the previous run after a crash
docker logs --since 30m smarttable # Last 30 minutesWhen starting with Docker Compose:
docker compose -f docker-compose.yml logs -f smarttable
docker compose -f docker-compose.full.yml logs -f # Full deployment, also streams postgres / redis / minioIf the container keeps restarting, check its state first and read the previous run with --previous:
docker ps -aThese are the real runtime logs of the backend service, including exception stack traces:
# Backend process
docker exec smarttable tail -f /var/log/supervisor/app-server.err.log # Errors and stack traces
docker exec smarttable tail -f /var/log/supervisor/app-server.out.log # Runtime output, Eventlet request logs
# Other processes
docker exec smarttable tail -f /var/log/supervisor/nginx.err.log
docker exec smarttable tail -f /var/log/supervisor/redis.err.log
docker exec smarttable tail -f /var/log/supervisor/supervisord.log # Process restart records
docker exec smarttable ls -lh /var/log/supervisor/ # List all log filesCheck and manage process status (the backend can be restarted without restarting the container):
docker exec smarttable supervisorctl status
docker exec smarttable supervisorctl restart app-serverIn production mode Flask writes to /app/logs/smarttable.log inside the container: 10 MB per file, 10 rotated files kept (smarttable.log.1 ~ smarttable.log.10).
If the log directory is mounted, you can read it directly on the host:
volumes:
- ./logs:/app/logstail -f ./logs/smarttable.log
grep "ERROR" ./logs/smarttable.logIf it is not mounted (for example when starting from the official image), read it inside the container or copy it out:
docker exec smarttable tail -f /app/logs/smarttable.log
docker cp smarttable:/app/logs/smarttable.log ./smarttable.logUseful for investigating 4xx / 5xx responses and API latency. The log format includes rt= (total request time) and urt= (upstream response time):
docker exec smarttable tail -f /var/log/nginx/access.log
docker exec smarttable tail -f /var/log/nginx/error.logSet DEBUG in .env and recreate the container for more verbose output:
LOG_LEVEL=DEBUGdocker compose -f docker-compose.yml up -d --force-recreatedocker logs -f --tail=100 smarttable 2>&1 | Select-String -Pattern "ERROR|Traceback"
Get-Content .\logs\smarttable.log -Tail 100 -Wait # equivalent to tail -f
docker exec smarttable tail -f /var/log/supervisor/app-server.err.logdocker ps -a — check the container state and whether it is stuck in Restarting.docker logs --tail=100 smarttable — check whether startup hangs at database migration or initialization.docker exec smarttable supervisorctl status — find out which process exited abnormally./var/log/supervisor/*.err.log../logs/smarttable.log.Operation logs are not stored in files
User operation logs (who changed which record) are stored in the database. View them on the Operation Logs page in the admin console or through /api/admin/operation-logs; they are not part of the log files above.
If port 80 is already in use, change the port mapping in docker-compose.yml:
ports:
- "8080:80"Check DATABASE_URL and make sure the database container or file path is reachable. See Viewing Logs for how to read the backend logs and locate the detailed error.
Set ENABLE_REALTIME=true and configure SOCKETIO_MESSAGE_QUEUE when running multiple backend instances.