A production-ready template for deploying Smartphone Test Farm (STF) using Docker Compose with a distributed architecture.
Smartphone Test Farm is an open-source web application for debugging and controlling Android devices remotely. It provides:
- Remote device control through web browser
- Real-time device screenshots and screen streaming
- ADB shell access through web interface
- File upload/download to devices
- Device information and resource monitoring
- Multi-user device sharing and reservations
This template supports a distributed deployment with:
- Central Server: Hosts the STF web UI, API, database, and core services
- Remote Providers: Run on machines with physical Android devices connected via USB
- SSL/TLS: Production-ready HTTPS configuration with nginx reverse proxy
- Custom Device Database: Support for device metadata and images
- Production-ready Docker Compose configuration
- Distributed architecture for scaling across multiple locations
- SSL/TLS termination with nginx
- Custom Docker images for TLS validation bypass
- Environment-based configuration
- Example configurations for remote providers
- Comprehensive documentation
- Docker and Docker Compose
- Public hostname/IP address
- SSL certificate (Let's Encrypt recommended)
- Open ports: 80, 443, 7100-7700
- Docker and Docker Compose
- Physical Android devices connected via USB
- Network access to central server
- Open ports: 7400-7700
# Clone this repository
git clone <your-repo-url> stf-deployment
cd stf-deployment
# Copy and configure environment
cp .env.example .env
nano .env # Update PUBLIC_IP and SECRET
# Set up SSL certificates
cd nginx/certs
# Follow instructions in nginx/certs/README.md
# to generate or copy certificates as server.crt and server.key
# Start services
docker-compose up -d
# Check logs
docker-compose logs -f# On remote machine with USB devices
cd remote/
# Copy and configure environment
cp .env.example .env
nano .env # Update configuration (see below)
# Start provider
docker-compose up -dEdit nginx/nginx.conf and add location blocks for each remote provider. See the commented examples in the file at lines 79-97.
After editing, restart nginx:
docker-compose restart nginx# Your STF server's public hostname
PUBLIC_IP=stf.yourdomain.com
# Shared secret for authentication (generate a strong random string)
SECRET=change-this-to-a-random-secret-key
# RethinkDB connection (internal Docker network)
RETHINKDB_PORT_28015_TCP=tcp://rethinkdb:28015# Central server's public hostname (must match central server)
PUBLIC_IP=stf.yourdomain.com
# Shared secret (MUST MATCH central server)
SECRET=same-secret-as-central-server
# Unique name for this remote station (appears in STF UI)
STATION_NAME=REMOTE1
# This remote machine's public hostname/IP
# Clients connect directly to this IP for device interactions
STATION_IP=remote1.yourdomain.com
# RethinkDB connection (not used by remote, but required by STF)
RETHINKDB_PORT_28015_TCP=tcp://rethinkdb:28015For production deployments, you need SSL certificates. See nginx/certs/README.md for detailed instructions on:
- Generating self-signed certificates (testing only)
- Using Let's Encrypt (recommended for production)
- Using commercial certificates
Quick Let's Encrypt setup:
# Install certbot
sudo apt-get install certbot
# Get certificates
sudo certbot certonly --standalone -d stf.yourdomain.com
# Copy to nginx/certs
sudo cp /etc/letsencrypt/live/stf.yourdomain.com/fullchain.pem nginx/certs/server.crt
sudo cp /etc/letsencrypt/live/stf.yourdomain.com/privkey.pem nginx/certs/server.key
sudo chmod 644 nginx/certs/server.crt
sudo chmod 600 nginx/certs/server.keyFor each remote machine with USB devices:
-
Deploy remote provider on the machine with devices:
cd remote/ cp .env.example .env # Edit .env with unique STATION_NAME and STATION_IP docker-compose up -d
-
Update nginx configuration on central server:
Edit
nginx/nginx.confand add a location block:location ~ "^/d/REMOTE1/([^/]+)/(?<port>[0-9]{3,5})/$" { proxy_pass http://remote1.yourdomain.com:$port/; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection $connection_upgrade; proxy_set_header X-Forwarded-For $remote_addr; proxy_set_header X-Real-IP $remote_addr; }
-
Restart nginx:
docker-compose restart nginx
To use custom device metadata and images:
-
Clone the device database:
git clone https://github.com/DeviceFarmer/stf-device-db.git stf-devices
-
Mount as submodule in docker-compose.yml:
provider: volumes: - ./stf-devices:/app/node_modules/@devicefarmer/stf-device-db/dist
-
Add your devices following the device addition workflow
After deployment:
- Open your browser to
https://stf.yourdomain.com - Log in with the mock authentication (default in template)
- You should see connected devices from all remote providers
- nginx: Reverse proxy with SSL/TLS termination
- rethinkdb: Database for device state and user management
- app: Web UI frontend
- auth: Authentication service (mock auth by default)
- processor: Handles device events and state changes
- triproxy: ZeroMQ message router for device communication
- storage-temp: Temporary file storage
- storage-plugin-apk: APK file management
- storage-plugin-image: Device screenshot storage
- websocket: WebSocket server for real-time updates
- api: REST API endpoints
- local-adb: ADB server with USB device access
- local-provider: STF provider connecting devices to central server
-
Check remote provider logs:
docker-compose logs -f local-provider
-
Verify SECRET matches between central and remote
-
Check firewall rules allow ports 7250, 7270, 7400-7700
-
Verify nginx location blocks match STATION_NAME
- Check that STATION_IP is publicly accessible
- Verify ports 7400-7700 are open on remote provider
- Check nginx reverse proxy configuration
- Test websocket connection in browser console
- Ensure certificates are valid and not expired
- Check certificate permissions (644 for .crt, 600 for .key)
- Verify certificate matches your PUBLIC_IP hostname
- For self-signed certs, provider containers have
NODE_TLS_REJECT_UNAUTHORIZED=0
-
Check RethinkDB is running:
docker-compose logs rethinkdb
-
Verify RETHINKDB_PORT_28015_TCP in .env
-
Check internal Docker network connectivity
For comprehensive documentation on advanced topics, see the Distributed STF Deployment Guide:
- Network architecture and port mapping
- Security considerations
- Performance tuning
- Monitoring and maintenance
- Multi-site deployments
- Custom authentication providers
Before deploying to production:
- Generate a strong SECRET: Use a cryptographically secure random string
- Use proper SSL certificates: Let's Encrypt or commercial CA
- Configure firewalls: Restrict access to necessary ports only
- Set up monitoring: Monitor Docker containers and device connectivity
- Plan for backups: Regular RethinkDB backups
- Use authentication: Replace mock auth with OAuth or LDAP
- Review security: Follow security best practices for your environment
To update to a newer STF version:
- Edit Dockerfiles to change the STF version
- Rebuild custom images:
docker-compose build
- Restart services:
docker-compose down docker-compose up -d
Contributions are welcome! Please:
- Fork this repository
- Create a feature branch
- Test your changes thoroughly
- Submit a pull request with clear description
This template is provided as-is for use with STF. STF itself is licensed under Apache 2.0.
For issues specific to this template, please open an issue in this repository.
For STF-related questions, see the official STF documentation or community forums.