Skip to main content

Local Testing & Debugging

Before submitting your application, you must thoroughly test the complete lifecycle on a TNAS device.

TOS7 Development Environment Quick Setup:

  1. Option A: Ubuntu 22.04 Virtual Machine (Recommended)

    • Download VirtualBox or VMware
    • Import the official TOS7 developer VM from the TOS Developer Platform
    • The VM includes pre-configured TOS7 tools and simulated services
  2. Option B: Docker-Based Development Container

    docker run -it --name tos7-dev -v $(pwd):/workspace ubuntu:22.04 /bin/bash
    apt-get update && apt-get install -y dpkg-dev lintian systemd
  3. Option C: Physical TNAS Device (For Final Testing)

    • Final verification must be performed on an actual device before submission
    • Must run TOS 7.0 or later
    • Enable SSH access for debugging

Deb Application Testing

# 1. Install the deb package
sudo dpkg -i <appid>_<version>_amd64.deb

# 2. Check if the service is running
sudo systemctl status <appid>

# 3. View service logs (real-time)
sudo journalctl -u <appid> -f

# 4. View recent logs
sudo journalctl -u <appid> --since "1 hour ago"

# 5. Check if the Web UI is accessible (Web apps)
curl http://localhost:<port>

# 6. Test start/stop
sudo systemctl stop <appid>
sudo systemctl start <appid>
sudo systemctl restart <appid>

# 7. Test uninstallation
sudo dpkg --remove <appid> # Keep configuration
sudo dpkg --purge <appid> # Complete removal

# 8. Verify cleanup (no residual files/services)
systemctl list-unit-files | grep <appid>
# Check runtime data directory
ls /Volume*/@apps/<appid> 2>/dev/null
# Check persistent data (shared folder)
ls /Volume*/<appid> 2>/dev/null
# Check system user
id <appid> 2>/dev/null

# 9. Test upgrade path
sudo dpkg -i <appid>_0.9.0_amd64.deb # Install old version
# ... Add some data to /Volume*/<appid>/ ...
sudo dpkg -i <appid>_1.0.0_amd64.deb # Upgrade to new version
# Verify data is preserved and migrated

Note: * in /Volume*/ represents the volume number (e.g., Volume1, Volume2) chosen by the user during installation.

  • /Volume*/@apps/<appid>/ — Application runtime data (logs, cache, temporary files)
  • /Volume*/<appid>/ — Persistent user data (shared folder, created by the application)

Docker Application Testing

# 1. Ensure DockerEngine is installed and running
# Docker Engine is available in the TOS App Center — users will be prompted to install it if not already present.
sudo systemctl status docker

# 2. Start the application
docker-compose -f docker-compose.yml up -d

# 3. Check container status
docker ps | grep <appid>

# 4. View container logs (real-time)
docker logs -f <appid>

# 5. Check resource usage
docker stats <appid>

# 6. Check if the Web UI is accessible
curl http://localhost:<port>

# 7. Test stop/restart
docker-compose -f docker-compose.yml down
docker-compose -f docker-compose.yml up -d

# 8. Test data persistence
docker-compose -f docker-compose.yml down
docker-compose -f docker-compose.yml up -d
# Verify data still exists in /Volume*/DockerAppData/<appid>/ and /Volume*/<appid>/

# 9. Test health check
docker inspect --format='{{.State.Health.Status}}' <appid>

# 10. Cleanup
docker-compose -f docker-compose.yml down -v

Developer Debugging Toolkit

One-Click Debugging Script: Save as debug.sh and run to validate your application:

#!/bin/bash
if [ -z "$1" ]; then
echo "Usage: $0 <appid>"
exit 1
fi

APPID="$1"
echo "=== TOS7 App Debug: $APPID ==="

echo "--- Service Status ---"
systemctl status "$APPID" 2>/dev/null || echo "Service not found"

echo "--- Processes ---"
pgrep -a -f "/Volume*/@apps/$APPID/" 2>/dev/null || echo "No related processes found"

echo "--- Ports ---"
ss -tlnp | grep "$APPID"

echo "--- Runtime Data Directory ---"
ls -laR "/Volume*/@apps/$APPID/" 2>/dev/null

echo "--- Persistent Data (Shared Folder) ---"
ls -laR "/Volume*/$APPID/" 2>/dev/null

echo "--- Recent Errors ---"
journalctl -u "$APPID" -p err --since "10 minutes ago" --no-pager

echo "--- Disk Usage ---"
du -sh "/Volume*/@apps/$APPID/" "/Volume*/$APPID/" 2>/dev/null

echo "=== Debug Complete ==="

Service Debugging

# Verify service file validity
systemd-analyze verify /etc/systemd/system/<appid>.service

# Check service dependencies
systemd-analyze dump | grep -A5 <appid>

# Check port listening
ss -tlnp | grep <port>

# Check process details
ps aux | grep <appid>

# Check runtime data directory
ls -laR /Volume*/@apps/<appid>/

# Check persistent data (shared folder)
ls -laR /Volume*/<appid>/

# View systemd error logs
journalctl -u <appid> -p err

# View system logs
grep <appid> /var/log/syslog

Docker Debugging

# Enter a running container
docker exec -it <appid> /bin/sh

# Inspect container details
docker inspect <appid>

# Check resource limits
docker stats --no-stream <appid>

# Check network
docker network ls
docker network inspect <network_name>

# View container filesystem changes
docker diff <appid>

# View image layers
docker history <image>

Rapid Development Cycle

Rapid iteration during development:

# Deb application: quick reinstall
sudo dpkg --purge <appid> && sudo dpkg -i <appid>_<version>_amd64.deb

# Docker application: quick rebuild
docker-compose down && docker-compose up -d --build

# Tail logs while testing
journalctl -u <appid> -f & # Deb
docker logs -f <appid> & # Docker

Common Issues & Solutions

IssuePossible CauseSolution
Service fails to startMissing dependencies or incorrect pathCheck journalctl -u <appid>, verify ExecStart path
Port conflictAnother service using the same portss -tlnp | grep <port>, switch to an available port
Permission deniedIncorrect file ownership or permissionsVerify User/Group in service file, check file ownership
Web UI inaccessibleService not listening or firewall blockingCheck if service is running, verify port binding (0.0.0.0 not 127.0.0.1)
Container exits immediatelyApplication error inside containerdocker logs <appid>, check entrypoint/command
Data lost after restartVolume mount not configuredAdd volume mapping in docker-compose.yml
App broken after TOS updateABI change or service conflictCheck low_version, test on new TOS version
Configuration not loadedIncorrect config path or permissionsVerify WorkingDirectory and config file path
Config permissions lost after upgradechown/chmod not re-applied in postinstAdd chown -R <appid>:<appid> in postinst script
Socket file residue causing startup failureSocket not cleaned up from previous runAdd rm -f /var/api/<appid>.sock before starting service
Nginx reload failureInvalid Nginx config syntaxValidate with nginx -t before reloading
Incorrect Docker volume permissionsHost vs container UID/GID mismatchUse PUID/PGID environment variables matching host user
Service starts before network is readysystemd unit missing After=network.targetAdd After=network.target and Wants=network.target
Deb fails to install due to unmet dependenciesMissing Depends in DEBIAN/controlMissing system library dependency → add corresponding package name in Depends (DEBIAN/control); missing other app dependency → add in config.ini depend field