Table of Contents
- Introduction
- Project Architecture
- Requirements
- Cloning the Repository
- Android Setup with Termux
- Ubuntu/PRoot Environment
- Backend Directory
- Python Virtual Environment
- Installing Backend Dependencies
- Environment Variables
- PostgreSQL Setup
- Creating the PostgreSQL Database
- Django Database Configuration
- Running Django Migrations
- Creating a Django Admin User
- Redis Setup
- Redis on Normal Linux
- Redis on Android/PRoot
- Celery Configuration
- Starting Celery
- Celery on Android
- Playwright Setup
- Playwright on Android/PRoot
- Starting the Django Backend
- Django Admin
- Testing Authentication
- Testing Login
- Testing /api/me/
- Testing /api/me/ With JWT
- Testing Registration
- First Registration Test
- Understanding the Registration Job
- The Redis Failure We Encountered
- The Celery Worker Test
- Playwright Failure We Encountered
- Async/Django Error
- Frontend Setup
- Frontend Environment Variables
- Running Everything Locally
- Recommended Startup Order
- Production Architecture
- Production Components
- Production Environment Variables
- Generate a Strong Django Secret
- Production PostgreSQL
- Railway Backend Deployment
- Railway Redis
- Railway Celery Worker
- Render Backend Deployment
- Render PostgreSQL
- Render Redis
- Render Celery Worker
- Why Celery Needs a Separate Worker
- Vercel Frontend Deployment
- Vercel Environment Variables
- CORS
- Production HTTPS
- Playwright in Production
- Docker for Production
- Production Database Migrations
- Static Files
- Django Production Settings
- Common Error: / Returns 404
- Common Error: /favicon.ico 404
- Common Error: /api/ 404
- Common Error: 401 Unauthorized
- Common Error: 400 Bad Request
- Common Error: Redis Connection Refused
- Common Error: Celery Cannot Connect to Redis
- Common Error: Playwright Browser Missing
- Common Error: SynchronousOnlyOperation
- Android Development Limitations
- Git Workflow
- Fresh Device Setup — Quick Version
- Complete Local Checklist
- Complete Production Checklist
- Final Architecture
- The Most Important Lesson
- Final Recommended Development Strategy
1. Introduction
The Temp Identity Agent consists of several services working together.
The Django backend handles:
- Authentication
- API endpoints
- Users
- Registration jobs
- Temporary identities
- Job state
- Database operations
- AI-agent orchestration
Celery handles background tasks.
Redis acts as the Celery message broker and result backend.
PostgreSQL stores persistent application data.
Playwright provides browser automation.
The frontend provides the user interface.
The basic architecture is:
┌──────────────────┐ │ Frontend │ │ Next.js / Web │ └────────┬─────────┘ │ │ HTTP / REST ▼ ┌──────────────────┐ │ Django Backend │ │ Django REST API │ └───────┬──────────┘ │ ┌───────────────┼────────────────┐ │ │ │ ▼ ▼ ▼ ┌────────────┐ ┌────────────┐ ┌────────────┐ │ PostgreSQL │ │ Redis │ │ Playwright │ │ Database │ │ Broker │ │ Browser │ └────────────┘ └─────┬──────┘ └────────────┘ │ ▼ ┌──────────────────┐ │ Celery Worker │ │ Background Jobs │ └──────────────────┘
2. Project Architecture
The backend is structured approximately like this:
backend/ ├── apps/ │ ├── ai_agent/ │ ├── browser/ │ ├── identities/ │ └── registration/ │ ├── config/ │ ├── settings/ │ │ ├── base.py │ │ ├── development.py │ │ └── production.py │ │ │ ├── celery.py │ ├── urls.py │ └── ... │ ├── manage.py ├── requirements.txt └── .env
The important services are:
- Django
- PostgreSQL
- Redis
- Celery
- Playwright
- Frontend
3. Requirements
Normal Linux/macOS/Windows + WSL
You need:
- Git
- Python 3.12+
- PostgreSQL
- Redis
- Node.js
- npm
- Playwright dependencies
- A modern browser environment
For Windows, WSL2 is recommended for the backend if the project is primarily Linux-oriented.
4. Cloning the Repository
Clone the repository:
git clone <YOUR_REPOSITORY_URL>
Enter the project:
cd temp-identity-agent
Check the files:
ls
You should see something similar to:
backend frontend README.md ...
5. Android Setup with Termux
The project can be developed on Android.
This is particularly useful when a PC is unavailable.
Install:
- Termux
- Acode or another code editor
- Ubuntu/PRoot environment
Termux provides the Linux-like shell while Ubuntu provides a more complete GNU/Linux userspace.
6. Ubuntu/PRoot Environment
Inside Termux, enter the Ubuntu environment.
For example:
proot-distro login ubuntu
Verify the system:
uname -a
Check Python:
python3 --version
Check architecture:
uname -m
On an ARM64 Android device you will normally see:
aarch64
Update packages:
apt update apt upgrade -y
Install basic tools:
apt install -y \ git \ curl \ wget \ build-essential \ python3 \ python3-pip \ python3-venv \ python3-dev
7. Backend Directory
Move into the backend:
cd temp-identity-agent/backend
Confirm:
pwd
You should be inside:
.../temp-identity-agent/backend
8. Python Virtual Environment
Create the virtual environment:
python3 -m venv .venv
Activate it:
source .venv/bin/activate
Your shell should now show:
(.venv)
Verify:
python --version
Example:
Python 3.12.3
9. Installing Backend Dependencies
Upgrade pip:
python -m pip install --upgrade pip
Install project dependencies:
pip install -r requirements.txt
Verify Django:
python -m django --version
Verify Celery:
celery --version
Example:
5.4.0
10. Environment Variables
The project uses environment variables for configuration.
Create the environment file if it doesn't exist:
touch .env
Example development configuration:
DEBUG=True SECRET_KEY=change-this-development-secret DATABASE_URL=postgresql://identity_user:password@localhost:5432/identity_agent REDIS_URL=redis://localhost:6379/0 ALLOWED_HOSTS=127.0.0.1,localhost CORS_ALLOWED_ORIGINS=http://localhost:3000
Do not commit
.env to Git.
Add it to
.gitignore:
.env .venv/ __pycache__/ *.pyc
11. PostgreSQL Setup
PostgreSQL is the primary persistent database.
Install PostgreSQL
Inside Ubuntu:
apt update apt install postgresql postgresql-contrib -y
Because PRoot environments generally do not run systemd normally, PostgreSQL may not automatically start.
Check:
ps aux | grep postgres
If PostgreSQL is not running, start it using the environment's PostgreSQL tools.
On a normal Linux system:
sudo systemctl start postgresql
Check:
sudo systemctl status postgresql
On PRoot/Termux, systemd may not be available. In that case PostgreSQL must be started manually using the appropriate cluster command.
12. Creating the PostgreSQL Database
Enter PostgreSQL:
sudo -u postgres psql
Create the user:
CREATE USER identity_user WITH PASSWORD 'change-this-password';
Create the database:
CREATE DATABASE identity_agent OWNER identity_user;
Grant privileges:
GRANT ALL PRIVILEGES ON DATABASE identity_agent TO identity_user;
Exit:
\q
Test the connection:
psql \ -h localhost \ -U identity_user \ -d identity_agent
If successful:
identity_agent=>
Exit:
\q
13. Django Database Configuration
The project reads the database connection from the environment.
For example:
DATABASE_URL=postgresql://identity_user:password@localhost:5432/identity_agent
Make sure the username, password, database name, host and port match your PostgreSQL configuration.
14. Running Django Migrations
From the backend:
python manage.py makemigrations
Then:
python manage.py migrate
Check:
python manage.py showmigrations
Django should show the migrations as applied.
15. Creating a Django Admin User
Create a superuser:
python manage.py createsuperuser
Follow the prompts.
Example:
Username: Email: Password: Password (again):
This account can be used at:
http://127.0.0.1:8000/admin/
16. Redis Setup
Redis is required by Celery.
Install it:
apt update apt install redis-server -y
Check:
redis-server --version
Example:
Redis server v=7.0.15
17. Redis on Normal Linux
On a normal Linux machine:
sudo systemctl start redis
Then:
redis-cli ping
Expected:
PONG
18. Redis on Android/PRoot
This was one of the important issues encountered during development.
PRoot does not behave like a normal Linux installation.
Running:
redis-server --daemonize yes
may appear successful but Redis can immediately exit.
The log revealed:
WARNING Your kernel has a bug that could lead to data corruption Redis will now exit to prevent data corruption.
This is related to the ARM64/PRoot kernel environment.
For development testing, Redis can be started while explicitly ignoring the warning.
Create a temporary Redis directory:
mkdir -p /tmp/redis
Start Redis:
redis-server \ --bind 127.0.0.1 \ --port 6379 \ --dir /tmp/redis \ --ignore-warnings ARM64-COW-BUG
If you want it detached:
redis-server \ --bind 127.0.0.1 \ --port 6379 \ --dir /tmp/redis \ --logfile /tmp/redis/redis.log \ --ignore-warnings ARM64-COW-BUG \ --daemonize yes
Verify:
redis-cli ping
Expected:
PONG
Check the process:
ps aux | grep '[r]edis'
Check logs:
cat /tmp/redis/redis.log
You want to see:
Ready to accept connections
Important: Ignoring a kernel warning is appropriate only as a development workaround when you understand the risk. It should not be blindly used for production data.
19. Celery Configuration
The project already contains:
config/celery.py
The settings contain:
CELERY_BROKER_URL = env( "REDIS_URL", default="redis://localhost:6379/0" ) CELERY_RESULT_BACKEND = env( "REDIS_URL", default="redis://localhost:6379/0" )
Therefore Redis must be available at:
redis://localhost:6379/0
unless
REDIS_URL overrides it.
20. Starting Celery
Make sure the virtual environment is active:
source .venv/bin/activate
From the backend directory:
celery -A config worker --loglevel=info
A successful startup looks like:
celery@localhost ready.
You should also see:
Connected to redis://localhost:6379/0
The worker should list tasks such as:
apps.registration.tasks.run_registration_job_task apps.registration.tasks.resume_registration_job_task apps.identities.tasks.close_orphaned_browser_sessions apps.identities.tasks.expire_stale_registration_jobs apps.identities.tasks.expire_temporary_identities
This confirms that Celery discovered the application's tasks.
21. Celery on Android
Android/PRoot runs the Celery worker successfully, but remember:
Terminal 1 → Redis Terminal 2 → Celery Terminal 3 → Django Terminal 4 → Frontend
Keep each process alive.
If Android kills the terminal process, the service will stop.
Using multiple Termux sessions or a terminal multiplexer can make this easier.
22. Playwright Setup
The application uses Playwright for browser automation.
Install the browser:
playwright install chromium
Check installed browsers:
playwright install --list
Test Chromium:
from playwright.sync_api import sync_playwright p = sync_playwright().start() b = p.chromium.launch(headless=True) print('CHROMIUM OK') b.close() p.stop()
Expected:
CHROMIUM OK
23. Playwright on Android/PRoot
Playwright is one of the more difficult components to run inside an Android PRoot environment.
You may see:
BrowserType.launch: Executable doesn't exist
This means the Python package exists but the browser executable has not been installed.
Run:
playwright install chromium
If Chromium refuses to start because Linux libraries are missing, install the dependencies requested by Playwright where possible.
If the required browser libraries are incompatible with the PRoot environment, browser automation may need to be moved to a normal Linux server for production.
This is one reason the Android environment is excellent for development but not necessarily ideal for production browser automation.
24. Starting the Django Backend
Start Django:
python manage.py runserver 0.0.0.0:8000
Expected:
Starting development server at http://0.0.0.0:8000/
The API is now available locally.
From the phone itself:
http://127.0.0.1:8000/
The root endpoint may return:
404 Not Found
That does not necessarily mean Django is broken.
The project may simply not define a route for
/.
25. Django Admin
Open:
http://127.0.0.1:8000/admin/
Log in with the superuser created earlier.
If the admin page loads, Django, PostgreSQL and the authentication/session system are functioning.
26. Testing Authentication
Test login with an empty request:
curl -i \ -X POST \ http://127.0.0.1:8000/api/auth/login/ \ -H "Content-Type: application/json" \ -d '{}'
Expected:
{ "username": [ "This field is required." ], "password": [ "This field is required." ] }
This is actually a good sign.
It means the endpoint exists and validation is working.
27. Testing Login
Use a valid account:
curl -s \ -X POST \ http://127.0.0.1:8000/api/auth/login/ \ -H "Content-Type: application/json" \ -d '{ "username": "YOUR_USERNAME", "password": "YOUR_PASSWORD" }'
A successful response contains:
{ "refresh": "...", "access": "..." }
The access token is then used for protected endpoints.
28. Testing /api/me/
Without authentication:
curl -i \ http://127.0.0.1:8000/api/me/
Expected:
401 Unauthorized
with:
{ "detail": "Authentication credentials were not provided." }
This confirms that authentication protection is working.
29. Testing /api/me/ With JWT
Store the access token:
ACCESS_TOKEN="YOUR_ACCESS_TOKEN"
Then:
curl -i \ http://127.0.0.1:8000/api/me/ \ -H "Authorization: Bearer $ACCESS_TOKEN"
Expected:
200 OK
30. Testing Registration
Registration requires:
- Django
- PostgreSQL
- Redis
- Celery
- Playwright
The request flow is:
Frontend ↓ POST /api/registration-jobs/ ↓ Django ↓ Create RegistrationJob ↓ Celery.delay() ↓ Redis ↓ Celery Worker ↓ Registration Task ↓ AI Agent ↓ Playwright
31. First Registration Test
Before creating a job, verify Redis:
redis-cli ping
Expected:
PONG
Verify Celery is running:
celery@localhost ready.
Verify Django is running:
Starting development server at http://0.0.0.0:8000/
Then submit a registration job from the frontend.
32. Understanding the Registration Job
A job may go through states such as:
QUEUED RUNNING WAITING COMPLETED FAILED CANCELLED
Celery processes the asynchronous portion.
Django remains responsible for persistent job state.
33. The Redis Failure We Encountered
Initially the application produced:
Connection refused
Specifically:
Error 111 connecting to localhost:6379
The Django API returned:
500 Internal Server Error
The important part of the traceback was:
kombu.exceptions.OperationalError: Error 111 connecting to localhost:6379
The problem was not Django.
It was:
Redis was not running.
Installing Redis alone was not sufficient because PRoot prevented the service manager from automatically starting it.
After starting Redis correctly, Celery successfully connected.
34. The Celery Worker Test
Once Redis was running:
celery -A config worker --loglevel=info
The worker reported:
Connected to redis://localhost:6379/0
Then:
celery@localhost ready.
It successfully received registration tasks.
This proved:
Django → Redis → Celery
was functioning.
35. Playwright Failure We Encountered
After Celery successfully received a registration task, the next failure was:
BrowserType.launch: Executable doesn't exist
The important lesson is:
Installing the Python Playwright package does not automatically mean the browser executable is installed.
Install Chromium:
playwright install chromium
Then test it independently.
36. Async/Django Error
During the Playwright failure path another error appeared:
django.core.exceptions.SynchronousOnlyOperation: You cannot call this from an async context
This occurred while the error-handling code attempted a Django database operation from an asynchronous context.
This is an application-code issue rather than a Redis/Celery installation problem.
It should eventually be fixed by restructuring the async/synchronous boundary, for example by using appropriate Django async APIs or
sync_to_async where necessary.
Do not use:
# arbitrary database calls inside async code model.save()
without considering Django's async restrictions.
37. Frontend Setup
Open another terminal.
Go to the frontend:
cd temp-identity-agent/frontend
Install dependencies:
npm install
Run development mode:
npm run dev
The frontend will normally start on:
http://localhost:3000
38. Frontend Environment Variables
The frontend needs to know where the backend API lives.
Example:
NEXT_PUBLIC_API_URL=http://127.0.0.1:8000
Depending on the project's implementation, the exact variable name may differ.
Check the frontend code for:
NEXT_PUBLIC_ API_URL BASE_URL
Do not blindly create a different variable name if the application already expects another one.
39. Running Everything Locally
The complete local environment should look like:
Terminal 1 — Redis
redis-server \ --bind 127.0.0.1 \ --port 6379 \ --dir /tmp/redis \ --ignore-warnings ARM64-COW-BUG
Terminal 2 — Celery
cd backend source .venv/bin/activate celery -A config worker --loglevel=info
Terminal 3 — Django
cd backend source .venv/bin/activate python manage.py runserver 0.0.0.0:8000
Terminal 4 — Frontend
cd frontend npm run dev
40. Recommended Startup Order
Always start services in this order:
1. PostgreSQL ↓ 2. Redis ↓ 3. Celery ↓ 4. Django ↓ 5. Frontend
This makes troubleshooting much easier.
41. Production Architecture
Local development:
Android/PC ├── PostgreSQL ├── Redis ├── Celery ├── Django └── Next.js
Production:
Internet │ ▼ ┌─────────────┐ │ Vercel │ │ Frontend │ └──────┬──────┘ │ │ HTTPS ▼ ┌─────────────┐ │ Railway / │ │ Render │ │ Django │ └──────┬──────┘ │ ┌──────────┼───────────┐ │ │ │ ▼ ▼ ▼ PostgreSQL Redis Celery Worker │ ▼ Playwright
42. Production Components
A production deployment requires:
- Frontend: Vercel
- Backend: Railway or Render
- Database: Managed PostgreSQL
- Redis: Managed Redis
- Worker: Separate Celery worker service
- Browser automation: Playwright-compatible Linux environment
43. Production Environment Variables
Never hard-code secrets.
Backend production variables should include values similar to:
DEBUG=False SECRET_KEY=<LONG_RANDOM_SECRET> DATABASE_URL=<PRODUCTION_POSTGRES_URL> REDIS_URL=<PRODUCTION_REDIS_URL> ALLOWED_HOSTS=<YOUR_BACKEND_DOMAIN> CORS_ALLOWED_ORIGINS=https://<YOUR-FRONTEND-DOMAIN>
If the project uses additional secrets, add them as well.
Examples could include:
AI_API_KEY= EMAIL_API_KEY= ENCRYPTION_KEY=
Use the actual names defined by the project.
44. Generate a Strong Django Secret
Never reuse:
SECRET_KEY=change-me
Generate a strong secret:
python -c "import secrets; print(secrets.token_urlsafe(64))"
Copy the result into the production environment.
45. Production PostgreSQL
Do not use SQLite for the production application if PostgreSQL is part of the intended architecture.
Use managed PostgreSQL from:
- Railway
- Render
- Supabase
- Neon
- another reputable PostgreSQL provider
The provider will give you a connection string similar to:
postgresql://USER:PASSWORD@HOST:5432/DATABASE
Put it into:
DATABASE_URL=
46. Railway Backend Deployment
Create a Railway project.
Connect the GitHub repository.
Select the backend as the service directory if necessary.
Configure:
Root Directory: backend
Add environment variables.
Build/install command:
pip install -r requirements.txt
Run migrations during deployment or as a release command:
python manage.py migrate
Start Django using a production WSGI/ASGI server.
For example:
gunicorn config.wsgi:application
If the project uses ASGI:
gunicorn config.asgi:application
Use the project's actual configuration.
47. Railway Redis
Create a Redis service or use a managed Redis provider.
Obtain:
REDIS_URL
It may look like:
redis://...
Set:
REDIS_URL=<YOUR_REDIS_URL>
The backend and Celery worker must use the same Redis service.
48. Railway Celery Worker
The Django web service and Celery worker should be separate processes/services.
Create another Railway service using the same repository.
Use:
celery -A config worker --loglevel=info
Both services must share:
DATABASE_URL REDIS_URL SECRET_KEY
and any other required environment variables.
Architecture:
Railway │ ├── Django Web Service │ ├── Celery Worker │ ├── PostgreSQL │ └── Redis
49. Render Backend Deployment
Render can also host the Django backend.
Create a new Web Service.
Connect the GitHub repository.
Set:
Root Directory: backend
Build command:
pip install -r requirements.txt
Run migrations:
python manage.py migrate
Start command:
gunicorn config.wsgi:application
Again, use the actual WSGI module from the project.
50. Render PostgreSQL
Create a PostgreSQL database in Render.
Render will provide connection details.
Set:
DATABASE_URL=<RENDER_POSTGRES_URL>
Run:
python manage.py migrate
51. Render Redis
Use a compatible Redis provider and set:
REDIS_URL=<REDIS_CONNECTION_URL>
The Django web service and Celery worker must use the same Redis URL.
52. Render Celery Worker
Create a separate Render Background Worker.
Build:
pip install -r requirements.txt
Start:
celery -A config worker --loglevel=info
The worker must have the same:
DATABASE_URL REDIS_URL SECRET_KEY
as the Django service.
53. Why Celery Needs a Separate Worker
Django should not perform long-running registration tasks directly inside the HTTP request.
Instead:
Browser ↓ Django API ↓ Create Job ↓ Celery.delay() ↓ HTTP response
The worker then processes:
Registration Job ↓ AI Agent ↓ Browser Automation ↓ Database Updates
This prevents long-running jobs from blocking web requests.
54. Vercel Frontend Deployment
Push the frontend to GitHub.
Open Vercel.
Create a new project.
Import the repository.
Configure the frontend directory if it is inside:
/frontend
Vercel will detect Next.js automatically in most cases.
Build command:
npm run build
Start command is normally handled automatically by Vercel.
55. Vercel Environment Variables
Set:
NEXT_PUBLIC_API_URL=https://your-backend-domain.example.com
Use the actual variable expected by the project.
Do not use:
http://localhost:8000
in production.
The frontend must communicate with the public backend URL.
56. CORS
The backend must allow requests from the Vercel frontend.
Development:
CORS_ALLOWED_ORIGINS=http://localhost:3000
Production:
CORS_ALLOWED_ORIGINS=https://your-frontend.vercel.app
If you have a custom domain:
CORS_ALLOWED_ORIGINS=https://yourdomain.com
Do not solve CORS by blindly allowing:
*
in a production application that uses authentication.
57. Production HTTPS
The production architecture should use:
Frontend HTTPS ↓ Backend HTTPS ↓ PostgreSQL / Redis
Never expose sensitive authentication credentials over plain HTTP.
58. Playwright in Production
This is one of the most important deployment considerations.
The backend does not simply need Python.
It needs:
Python Django Celery Playwright Chromium Linux browser dependencies
Therefore your production environment must support browser automation.
A basic Python web service may not automatically contain everything required by Playwright.
You may need:
- A custom Docker image
- A Playwright-compatible base image
- Browser dependencies
- Sufficient memory
- A worker service capable of running Chromium
This should be tested before production launch.
59. Docker for Production
For browser automation, Docker can make the environment reproducible.
A production container can contain:
Python Django Celery Playwright Chromium System dependencies
This is often more reliable than manually installing browser dependencies on a server.
60. Production Database Migrations
Every time database schema changes:
python manage.py makemigrations
Commit the migration files:
git add . git commit -m "Add database migration" git push
Production:
python manage.py migrate
Never delete production migration files casually.
61. Static Files
Django admin and other static assets may require:
python manage.py collectstatic --noinput
Your production deployment should configure Django static files appropriately.
62. Django Production Settings
Ensure:
DEBUG=False
Configure:
ALLOWED_HOSTS- CORS
- CSRF trusted origins
- SECURE cookies
- HTTPS
- static files
Do not deploy with development settings accidentally enabled.
63. Common Error: / Returns 404
You may see:
GET / HTTP/1.1 404
This is not necessarily an error in the server.
It simply means there is no route registered for
/.
Test actual endpoints instead:
/api/auth/login/ /api/auth/register/ /api/me/ /api/registration-jobs/
64. Common Error: /favicon.ico 404
You may also see:
GET /favicon.ico 404
This simply means Django doesn't have a favicon at that URL.
It does not indicate that the API is broken.
65. Common Error: /api/ 404
If:
GET /api/ 404
but:
POST /api/auth/login/
works, then
/api/ itself may simply not be registered.
This is normal for APIs that don't have an API index endpoint.
66. Common Error: 401 Unauthorized
Example:
{ "detail": "Authentication credentials were not provided." }
This means the endpoint requires authentication.
Send:
Authorization: Bearer YOUR_ACCESS_TOKEN
67. Common Error: 400 Bad Request
Example:
{ "username": [ "This field is required." ], "password": [ "This field is required." ] }
This means validation failed.
The endpoint is actually responding correctly.
Send the required fields.
68. Common Error: Redis Connection Refused
Error:
Error 111 connecting to localhost:6379
Check:
redis-cli ping
If you get:
Connection refused
Redis is not running or is not listening on the expected port.
Check:
ps aux | grep '[r]edis'
Check:
ss -lntp | grep 6379
Then inspect logs.
69. Common Error: Celery Cannot Connect to Redis
Check:
grep -R "CELERY_BROKER_URL\|CELERY_RESULT_BACKEND" \ -n config/settings
Verify:
REDIS_URL=redis://localhost:6379/0
Then test:
redis-cli ping
Finally restart Celery:
celery -A config worker --loglevel=info
70. Common Error: Playwright Browser Missing
Error:
Executable doesn't exist
Run:
playwright install chromium
Then:
playwright install --list
Test:
from playwright.sync_api import sync_playwright p = sync_playwright().start() b = p.chromium.launch(headless=True) print('CHROMIUM OK') b.close() p.stop()
71. Common Error: SynchronousOnlyOperation
Error:
You cannot call this from an async context
This usually means synchronous Django ORM work is being performed from asynchronous code.
Investigate the relevant code path.
Typical solutions involve:
sync_to_async(...)
or Django's async ORM APIs where appropriate.
Do not randomly add async everywhere.
The application's async boundaries should be designed deliberately.
72. Android Development Limitations
Developing on Android is impressive and useful, but it has limitations.
Advantages
- No PC required
- Portable
- Git works
- Python works
- Django works
- PostgreSQL can work
- Redis can work
- Celery can work
- Node/npm can work
- Acode provides convenient editing
Disadvantages
- Android can kill background processes
- PRoot isn't a normal Linux kernel
- systemd isn't normally available
- Browser automation is harder
- Chromium dependencies can be difficult
- ARM64 compatibility can cause issues
- Battery consumption
- Limited RAM
- Thermal throttling
- Multiple services require multiple terminal sessions
- Long-running workers may stop if Android kills Termux
For these reasons:
Android is excellent for development, debugging and emergency coding, but production workloads should normally run on a proper Linux server.
73. Git Workflow
After making changes:
git status
Review:
git diff
Stage:
git add .
Commit:
git commit -m "Update registration agent"
Push:
git push
Never commit:
.env- passwords
- API keys
- JWT secrets
- database credentials
- private keys
74. Fresh Device Setup — Quick Version
For a completely new machine:
git clone <REPOSITORY> cd temp-identity-agent/backend
Create environment:
python3 -m venv .venv source .venv/bin/activate
Install:
pip install -r requirements.txt
Install PostgreSQL.
Create:
- database
- user
- password
Configure:
DATABASE_URL=
Install Redis:
apt install redis-server -y
Start Redis.
Verify:
redis-cli ping
Expected:
PONG
Run migrations:
python manage.py migrate
Create admin:
python manage.py createsuperuser
Install Playwright browser:
playwright install chromium
Start Celery:
celery -A config worker --loglevel=info
Start Django:
python manage.py runserver 0.0.0.0:8000
In another terminal:
cd frontend npm install npm run dev
75. Complete Local Checklist
Before reporting a bug, verify each item.
Python
python --version
Virtual environment
which python
Should point inside:
.venv/
Django
python manage.py check
Expected:
System check identified no issues
PostgreSQL
Test connection.
Redis
redis-cli ping
Expected:
PONG
Celery
celery -A config worker --loglevel=info
Expected:
Connected to redis://... celery@... ready.
Playwright
playwright install --list
Chromium
Run the browser test.
Django
python manage.py runserver
Frontend
npm run dev
76. Complete Production Checklist
Before production:
-
DEBUG=False - Strong
SECRET_KEY - Production PostgreSQL
- Production Redis
- Django web service
- Celery worker
- Playwright browser available
- Database migrations applied
- Static files configured
- CORS configured
- CSRF configured
- HTTPS enabled
- Frontend deployed
- Backend deployed
- Frontend API URL configured
- Environment variables configured
- Secrets not committed to Git
- Authentication tested
- Registration job tested
- Celery job processing tested
- Error handling tested
- Logs monitored
77. Final Architecture
The final system looks like this:
USER │ ▼ ┌───────────────┐ │ Vercel │ │ Next.js │ │ Frontend │ └───────┬───────┘ │ HTTPS │ ▼ ┌───────────────┐ │ Railway / │ │ Render │ │ Django API │ └───────┬───────┘ │ ┌───────────┼────────────┐ │ │ │ ▼ ▼ ▼ ┌────────────┐ ┌─────────┐ ┌─────────────┐ │ PostgreSQL │ │ Redis │ │ Other APIs │ │ │ │ │ │ / Services │ └────────────┘ └────┬────┘ └─────────────┘ │ ▼ ┌──────────────┐ │ Celery │ │ Worker │ └──────┬───────┘ │ ▼ ┌──────────────┐ │ AI Agent │ │ Orchestrator │ └──────┬───────┘ │ ▼ ┌──────────────┐ │ Playwright │ │ Chromium │ └──────────────┘
78. The Most Important Lesson
The project is not simply:
Django + React
It is a distributed application composed of multiple services:
Frontend + Django + PostgreSQL + Redis + Celery + Playwright + AI Agent
If one critical service is unavailable, another component may fail.
For example:
Redis OFF ↓ Celery cannot receive jobs ↓ Registration endpoint may fail
Or:
Celery ON ↓ Playwright browser missing ↓ Registration task fails
Or:
Playwright fails ↓ Error handler executes ↓ Async/sync ORM boundary bug ↓ Additional exception
Understanding these dependencies makes debugging much easier.
79. Final Recommended Development Strategy
When something breaks, don't immediately change the code.
Test each layer independently.
Layer 1
redis-cli ping
Layer 2
celery -A config worker --loglevel=info
Layer 3
python manage.py check
Layer 4
python manage.py runserver
Layer 5
Test authentication.
Layer 6
Test registration job creation.
Layer 7
Verify Celery receives the job.
Layer 8
Verify Playwright launches Chromium.
Layer 9
Verify the agent executes.
Layer 10
Verify the final database state.
This layered approach prevents wasting hours debugging the wrong component.
Conclusion
Getting a modern full-stack AI application running locally can involve considerably more than installing Python and running Django.
The complete stack needs to be understood as a collection of cooperating services:
PostgreSQL ↓ Django ↓ Redis ↓ Celery ↓ AI Agent ↓ Playwright ↓ Browser
The frontend then communicates with the Django API:
Next.js ↓ Django REST API
On a development computer these services can run locally.
On Android, Termux and a Linux/PRoot environment can provide a surprisingly capable development environment, although browser automation and long-running services require additional care.
For production, the recommended architecture is:
Vercel ↓ Railway / Render ↓ Managed PostgreSQL + Managed Redis + Celery Worker + Playwright-compatible environment
Once every component is understood independently, setting up the project on another device becomes a repeatable process rather than a trial-and-error exercise.
The goal of this guide is therefore not just to get the project running once, but to make the setup reproducible for the next computer, phone, developer, or deployment.
One important note
I deliberately did not invent exact commands for things that depend on the repository's actual implementation, such as the precise frontend framework scripts, production settings module, database configuration implementation, or Docker/Playwright image. Those should be taken directly from the repo rather than guessed.
If you want this to become the definitive
for your actual repository, the next step should be an audit of the uploaded project files so I can replace those placeholders with the exact commands, environment variables, service names, API endpoints, deployment configuration, and directory structure from your codebase.README.md