When a Django project works locally but migration commands fail after deployment to a VPS, it can be frustrating and disruptive. On a Hong Kong VPS or an alternative like a US VPS or US Server, common causes range from environment mismatches to database configuration and resource limits. This article walks through practical, step-by-step diagnostics and fixes with technical details suitable for webmasters, enterprise operators, and developers.
Understanding how Django migrations work (principles)
Django migrations are Python code representations of schema changes that are applied to a relational database. They rely on:
- the project’s models and migration files stored in app_name/migrations/
- a working Python environment with the same Django version used when migrations were created
- a properly configured database connection in settings.py (DATABASES)
- database-specific features and extensions (for example Postgres extensions)
- transaction handling — Django applies migrations in transactions where supported
When a VPS adds variables such as different package versions, limited memory, or network latency to a remote DB (for example using a Hong Kong Server to host your DB while your app runs on a US VPS), migrations can fail for reasons that are not always obvious from the Django traceback.
Common failure scenarios and diagnostics
1. Authentication or connection failures
Symptoms: “could not connect to server”, “password authentication failed”, or timeouts. Check DATABASES in settings.py for correct host, port, user and password. For example, connecting to a Postgres instance on a Hong Kong Server from a US VPS adds network hops and possible firewall blocks.
- On the VPS, confirm basic connectivity: ping the DB host, or use psql/mysql client to connect from the app server.
- Check firewall rules and security groups (ufw, iptables, cloud provider firewall) on both sides.
- If using TLS, confirm certificates and SSL mode in DATABASES (OPTIONS for psycopg2 or mysqlclient).
2. Missing database extensions or incompatible features
Symptoms: errors like “function uuid_generate_v4() does not exist” or “extension postgis not found”. Some migrations depend on database extensions that must be enabled at the database level.
- For PostgreSQL, run CREATE EXTENSION IF NOT EXISTS “uuid-ossp”; as a DB superuser.
- Confirm extensions using dx in psql.
- If running on a managed database on a Hong Kong Server, check whether you have permission to enable extensions; you may need to request it from your provider or switch to a VPS where you control the DB instance.
3. Transaction and lock issues
Symptoms: migrations hang, or you see “deadlock detected” or “could not obtain lock on relation”. Long-running queries, concurrent migrations, or resource starvation (low memory/CPU) on a VPS can cause locks not to be released.
- Check pg_locks or show processlist in MySQL to find blocking queries.
- Use VACUUM ANALYZE or optimize tables where appropriate.
- When migrations hang due to locks, consider running them during low-traffic windows, or use a maintenance page.
4. Migration conflicts and history mismatches
Symptoms: “Conflicting migrations” or “no such column” after partial migration. This often happens when multiple branches or team members generate migrations independently, or when the migrations table (django_migrations) differs between environments.
- Inspect migrations with python manage.py showmigrations.
- If you must reconcile, you can mark migrations as applied using python manage.py migrate app_name 000X –fake or –fake-initial, but use with caution — only when you are certain the schema matches the target state.
- When collaborating, prefer squashing trivial migrations with python manage.py squashmigrations app_name start_migration end_migration to reduce branches.
5. Environment and package mismatches
Symptoms: import errors, attribute errors, or different behavior. Ensure the Python interpreter, Django version, and database drivers (psycopg2-binary for Postgres, mysqlclient for MySQL) match what was used during development.
- Use a virtual environment on the VPS and pin versions in requirements.txt.
- On low-memory VPS instances, pip install may fail due to lack of build tools. Install build-essential, libpq-dev (Postgres), default-libmysqlclient-dev (MySQL) before pip installing database drivers.
- Check installed packages with pip freeze and reconcile differences.
Step-by-step fixes — practical commands and checks
Preparation: gather information
Log into the VPS (SSH) and confirm environment: OS, Python, RAM, disk:
Run: uname -a; python3 –version; free -h; df -h
Confirm Django settings: check settings.DATABASES, settings.TIME_ZONE, and ALLOWED_HOSTS. If you use environment variables, ensure they are loaded in the systemd service or supervisor config that launches Django/Gunicorn.
Fix 1 — Connection and permission
Attempt to connect from the app VPS to the DB host using the native client: psql -h DB_HOST -U dbuser -d dbname -W or mysql -h DB_HOST -u dbuser -p. If that fails, verify:
- DB host is reachable and listening on the port (netstat -plnt or ss -plnt on DB server).
- pg_hba.conf (Postgres) or MySQL bind-address allows remote connections.
- Firewall allows the port (5432/3306) between the VPS and DB host.
Fix 2 — Enable required DB extensions
For Postgres example: connect as a superuser and run CREATE EXTENSION IF NOT EXISTS “uuid-ossp”;. For PostGIS, install the extension package and then CREATE EXTENSION postgis;. If you cannot run these because of managed DB limitations on a Hong Kong Server, move the DB to a full VPS or request the provider enable the extension.
Fix 3 — Resolve lock and resource issues
If migrations hang, inspect running queries: SELECT pid, now() – pg_stat_activity.query_start AS duration, state, query FROM pg_stat_activity WHERE state ‘idle’ ORDER BY duration DESC; Kill long-running blocking sessions if appropriate: SELECT pg_terminate_backend(pid);.
Consider adding swap to the VPS if migrations fail due to memory spikes: fallocate -l 1G /swapfile; chmod 600 /swapfile; mkswap /swapfile; swapon /swapfile. Then add to /etc/fstab to persist.
Fix 4 — Migration reconciliation
Use python manage.py showmigrations to identify unapplied or conflicting migrations. If you need to mark a migration as applied without changes (schema already matches), use:
python manage.py migrate app_name 000X –fake
To squash many tiny migrations and reduce future conflict likelihood:
python manage.py squashmigrations app_name start_migration end_migration
Fix 5 — Rebuild environment and dependencies
Recreate the virtualenv on the VPS and install pinned packages: python3 -m venv venv; source venv/bin/activate; pip install -r requirements.txt. Install OS-level dev packages first to ensure binary wheels can be built.
Application scenarios and advantages of different server locations
Choosing between a Hong Kong Server and a US VPS/US Server depends on traffic patterns and compliance needs. For a site whose users are primarily in Hong Kong or Mainland China, a Hong Kong VPS reduces latency and can improve database-query roundtrip times for migrations and runtime DB operations. Conversely, a US VPS or US Server might be preferable for a U.S.-centric audience or to colocate with other US-based services.
- Latency-sensitive operations: localizing DB and app in the same region reduces migration timeouts and lock exposure.
- Compliance and data residency: laws sometimes require data to remain in a specific jurisdiction; select a Hong Kong Server if regional residency is required.
- Resource control: VPS gives you root access to install DB extensions and tune kernel parameters, avoiding managed-hosting limitations that could block migration fixes.
How to select a VPS configuration for reliable migrations
When provisioning a VPS—whether you choose a Hong Kong VPS or a US Server—consider the following:
- Memory: migrations and package builds can be memory-intensive; choose at least 1–2GB for small apps or add swap.
- Disk I/O: migrations that alter large tables can be heavy on I/O; use SSD-backed storage where possible.
- CPU: concurrent DDL operations and compression tasks benefit from more CPU cores.
- Network: if your database is remote, pick a region to minimize latency between app and DB servers (Hong Kong Server vs US VPS choice).
- Snapshot/backups: take a DB snapshot before running risky migrations so you can quickly roll back.
Summary
Fixing Django migration failures on a VPS is usually a combination of diagnostics and environment hardening: confirm connectivity and credentials, enable required DB extensions, resolve locks and resource constraints, reconcile migration history carefully (using –fake only when justified), and ensure your Python/Django environment matches your development stack. For teams hosting in or near Hong Kong, using a Hong Kong Server can reduce latency and simplify operations; for other use cases a US VPS or US Server may be the better geographic fit. Always test migrations in a staging environment that mirrors your production VPS and keep backups before applying schema changes.
For reliable VPS hosting and to evaluate options for your deployment, see Server.HK (https://server.hk/) and their Hong Kong VPS offerings at https://server.hk/cloud.php.