From the team behind aidrop.it — one workspace to build, host, and keep changing your code.

A Django deployment needs a production server, a reachable database, applied migrations, and a way to serve static files. On aidrop.it, put PostgreSQL outside the application container and collect static assets into the image. Verify the result by saving a test record in the admin, deploying again, and finding the record afterward.

Start with an existing Django repository, committed migrations, and pinned dependencies. Connect your agent through the quickstart and choose a Project with application and database capacity.

1. Prepare production settings and static files

Run Django through a production WSGI or ASGI server, with debug disabled and an explicit list of accepted hostnames. Prepare static assets during the image build, then configure something to serve them. A successful collectstatic command only gathers files; it does not make the admin stylesheet reachable over HTTP.

Follow Django's deployment checklist for the project's version. Read SECRET_KEY from the environment, set DEBUG=False, and parse ALLOWED_HOSTS into exact hostnames. Run manage.py check --deploy with production settings and resolve the findings. Verify HTTPS handling through the proxy before enabling redirects that could loop.

For a small WSGI app, WhiteNoise can serve collected static files. Set STATIC_ROOT, place its middleware directly after SecurityMiddleware, and run python manage.py collectstatic --noinput during the build. Use isolated build settings if initialization requires credentials; production secrets are runtime-only and must not enter image layers.

User uploads need separate storage, such as an HTTPS object-storage service compatible with the app. The runtime's read-only application directory and temporary scratch space are not a media archive. See why local files disappear between deployments.

2. Attach PostgreSQL and configure the connection

Database attachment and Django configuration are separate steps. The attachment opens the Service's network path to a managed resource. Django still needs a connection string and settings that parse it. Inspect the Project's existing resources first, then reuse an appropriate instance or request a new one within the plan's capacity.

For a new Service, deploy a health-only bootstrap to obtain its ID and public hostname. Use shared_resources_list, create or select the database, and attach it with shared_resource_update. A new database instance requires explicit confirmation. Store the returned connection string as DATABASE_URL using project_secret_set.

Store SECRET_KEY and the exact assigned hostname for ALLOWED_HOSTS too. Make the complete Service require those three names. Django does not parse DATABASE_URL by itself: configure a parser or explicitly construct DATABASES. See the database-attachment walkthrough.

3. Apply migrations and verify the admin

Apply the committed migrations once before allowing users into the new app, and stop the release if they fail. Then start the production server on the configured port. Coordinate migrations as the deployment grows; do not let multiple processes apply them concurrently.

For the initial single-process app, an entrypoint can run python manage.py migrate --noinput and, only on success, execute gunicorn config.wsgi:application --bind 0.0.0.0:8000. Replace config with the actual module; direct worker temporary files to /tmp if needed. Add a lightweight /health endpoint that returns no private data.

Push the complete revision and call service_build for the existing Service with Dockerfile mode, port 8000, health path /health, and the three required secret names. Poll service_get and inspect failures through service_logs. Create the initial administrator through a controlled one-off process; never commit a default password.

Open the admin over HTTPS, check its CSS, sign in, and save a synthetic record. Deploy another revision and check that record again. Confirm the migration reached the intended database before considering the application ready.

Copy this Django release checklist

Record these checks beside the deployed commit. Verify the database, authentication, static files, and persistence after redeployment. Include upload checks if the application accepts files.

Repository: <repo>     Project: <project>     Commit: <sha>
[ ] Production settings pass check --deploy after review.
[ ] DEBUG is false; allowed hosts are explicit.
[ ] Static files are in the image and admin CSS loads.
[ ] PostgreSQL is attached to the correct Service.
[ ] DATABASE_URL, SECRET_KEY, ALLOWED_HOSTS reach runtime.
[ ] Migrations succeeded once against the intended database.
[ ] Production server listens on 0.0.0.0:8000; /health works.
[ ] HTTPS admin login and a CSRF-protected save both succeed.
[ ] A test record survives a second deployment.
[ ] Media storage survives redeployment, if uploads exist.
[ ] Database export and restore have a tested procedure.
Record the public URL and failures without exposing credentials.

FAQ

Can I use SQLite for this deployment? Use managed PostgreSQL for persistent application records. A database file inside the container is unsuitable for a read-only, replaceable application filesystem.

Does aidrop.it run Django's development server? Configure your image to start a production WSGI or ASGI server. For this example, Gunicorn serves the WSGI application on port 8000.

Does collecting static files handle uploads too? No. Static files ship with the application. User uploads arrive later and require durable media storage with appropriate access rules.

Before the next deploy

Get it running from the session you are already in

Connect your coding agent over MCP and ask it to deploy. aidrop builds the repository and runs it on a public address; when a build or the app fails, the log says why, and your agent fixes it and builds again.