October DealsAmazon USOctober deal check: compare before you payAmazon US: current deals, useful picks and tech finds.Check DealsSlow PC?RecommendedPC slow today? Run a repair scan before it gets worseResolve common Windows issues and optimize system performance.Scan NowOctober DealsAmazon USDeal season is back - check today's better picksAmazon US: current deals, useful picks and tech finds.See Picks×
Skip to content
World desk11 min

How to Build a Django and Gunicorn Application with Docker

Build and run a Django application with Gunicorn in Docker using a multi-stage image, Compose port mapping, separate development and production stages, and a practical production checklist.
Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

The reliable production pattern is a multi-stage Docker image that installs Django and Gunicorn into a runtime environment, runs Gunicorn on 0.0.0.0:8000, and lets Docker Compose publish that container port for local verification. Use Django’s development server only in a development stage; before production, handle static files, HTTPS, secrets, error reporting, performance settings, and Django’s deployment checks explicitly.

The architecture you are building

A Dockerized Django deployment has several distinct responsibilities. Docker packages the application and its Python dependencies. Gunicorn is the WSGI process that serves Django in the production container. Compose describes how to build and run that container. A reverse proxy or hosting platform may sit in front of it, terminate HTTPS, and serve static files, depending on your hosting stack.

As an Amazon Associate I earn from qualifying purchases.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

The production request path is therefore:

  1. A client connects to your public HTTPS endpoint or host.
  2. Your proxy or container platform forwards application requests to the container’s port 8000.
  3. Gunicorn imports the Django WSGI callable, such as myapp.wsgi:application.
  4. Django handles the request and returns the response.

The container must bind Gunicorn to 0.0.0.0, not only to the loopback interface. Binding to 127.0.0.1 would make the process reachable only inside the container and would prevent a published Docker port from reaching it.

“Running Gunicorn in Docker containers is the most common deployment pattern for modern Python applications.”

#1 Best Overall
Sale
TOZO A1 Wireless Earbuds Bluetooth 5.3 Light Weight in Ear Headphones | IPX5 Waterproof,2 Mics for AI Calls,Immersive Premium Sound Bass Headset with Charging Case,32 EQ via App Black
  • [Ultra-Lightweight Ear Buds Designed for Small Ears] Each earbud weighs only 3.7g and features a compact, ergonomic in-ear design made especially for small ears. Secure, low-profile, and comfortable for workouts, all-day wear or overnight sleeping.The ultra-slim profile sits flush in your ear with no hard edges poking or rubbing, so you can even sleep on your side without discomfort.
  • [Immersive Stereo Sound with TOZO OrigX Technology] TOZO OrigX tuning delivers clear vocals, balanced mids, and natural stereo sound for music, podcasts, and videos.
  • [Long Battery Life for Daily Use] Get up to 7 hours of playtime on a single charge, with up to 32 hours total using the charging case—ideal for workdays, commuting, and extended listening sessions.
  • [Bluetooth 5.3 & Stable Connection] Bluetooth 5.3 provides fast pairing, stable wireless performance, and reduced dropouts as you move around home or office.
  • [Deep Bass with Clear Vocals] High-performance drivers produce punchy bass while keeping vocals clean and detailed for everyday listening.

That pattern does not make Django’s built-in server suitable for production. The development server is useful for local iteration, while Gunicorn is the production WSGI process.

What you need before creating the image

  • A Django project with a WSGI module. In the examples below, the project package is named myapp; replace that name with your package.
  • Docker Engine with the Compose plugin, so the docker compose command is available.
  • A dependency file, normally requirements.txt, committed with the application.
  • A settings strategy that can provide environment-specific values without baking secrets into the image.

Keep the project package name separate from the application name in your own documentation. Gunicorn’s target uses the Python package containing wsgi.py, not necessarily the name of an individual Django app created with startapp.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Create a dependency file that includes Gunicorn

Gunicorn must be installed in the image, alongside Django and the other packages your project imports. A minimal dependency file looks like this:

Django
Gunicorn

In a real project, include every runtime dependency and use the dependency-locking or pinning approach your team has chosen. Reproducible builds depend on the dependency file being explicit and kept under version control. Development-only tools do not need to be copied into a production image unless the application actually imports them at runtime.

Write a production Dockerfile

A multi-stage Dockerfile separates dependency installation from the smaller runtime stage. The first stage can contain build tooling; the final stage receives the prepared virtual environment and the application source. This keeps the production image focused on what is needed to run the service.

FROM python:3-slim AS builder

ENV VIRTUAL_ENV=/opt/venv
RUN python -m venv $VIRTUAL_ENV
ENV PATH="$VIRTUAL_ENV/bin:$PATH"

WORKDIR /build
COPY requirements.txt .
RUN pip install --no-cache-dir --upgrade pip && 
    pip install --no-cache-dir -r requirements.txt

FROM python:3-slim AS runtime

ENV PYTHONUNBUFFERED=1 
    VIRTUAL_ENV=/opt/venv 
    PATH="/opt/venv/bin:$PATH"

WORKDIR /app
COPY --from=builder /opt/venv /opt/venv
COPY . /app

RUN useradd --create-home --shell /usr/sbin/nologin appuser && 
    chown -R appuser:appuser /app /opt/venv

USER appuser
EXPOSE 8000

CMD ["gunicorn", "myapp.wsgi:application", "--bind", "0.0.0.0:8000"]

Why each part matters

  • Builder stage: creates a virtual environment and installs the dependencies listed in requirements.txt. If a dependency needs compilation, the build stage is the appropriate place for that tooling.
  • Runtime stage: starts from a clean Python image and copies only the prepared environment and source tree.
  • PYTHONUNBUFFERED=1: makes Python write output without waiting for a buffer, which helps container logs appear promptly to the platform collecting them.
  • WORKDIR /app: gives Django and Gunicorn a predictable current directory.
  • EXPOSE 8000: documents the port the process listens on. It does not publish that port to the host by itself; Compose or a container platform must do that.
  • USER appuser: runs the service as a non-root user, a security practice recommended in Gunicorn’s Docker guidance.
  • Gunicorn command: imports the WSGI callable and binds it to every container interface on port 8000.

The exact Python base-image tag, operating-system packages, and dependency versions should match your application’s compatibility policy. Do not silently copy a local virtual environment into the image: build the environment inside the image so it matches the image’s operating system and Python runtime.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Rank #2
Sale
Smart Watch for Men Women Compatible with iPhone Samsung Android Phone 1.69 inch Full Touch Screen IP68 Waterproof Bluetooh Fitness Tracker Heart Rate/Sleep Monitor (Black)
  • 【IP68 Waterproof Multifunctinal Smart Watch】Torjalph fitness activity tracker smart watch is IP68 waterproof technology ,you can wear it when swimming,handwashing,it's rain-proof which means that you perform multiple exercise modes outside without worrying about sweat or rain corroding your fitness smart watch,and this watch equipped with a 230 mAh large capacity battery magnetic charging ,and this sports activity tracker watch can be used 5-7 days If fully charged.
  • 【Larger 1.83'' Full Screen Watch & Multi-dial Selection】1.83 inch full HD color touch screen smart watch for men / women provides excellent 240*284 resolution image quality ,This Bluetooth smart watch offers a better touch experience and remarkable immersion and ,more than 200 watch faces for you to choose from App"Da Fit ", you can change the dial style according to your mood to wear keeping the world on your wrist
  • 【Accurate Activity Tracker Smart Watch 】sports watch activity tracker uses sweat and dust resistant breathable silicone strap, our Fitness Tracker Smart Watch for Android iOS Phones supports 12 sports modes,walking,running,bicycle,swimming,badminton,basketball,football,rope skipping. This bluetooth calls smart watch for men women is lightweight and stylish, bringing more convenient and relaxing sports experience while also providing more protection.
  • 【Your 24 Hour Personal Daily Health Monitor】Fitness watch for women men full touch screen IP67 waterproof bluetooth smartwatch for Android iOS Phones with heart rate blood pressure monitor multifunction Andriod smart watch with steps counter sleep monitor sports fitness watch, monitoring blood oxygen saturation allows you to understand your physical condition in real time to track fitness progress ,to know your health status in time.
  • 【More Functions Bluetooth Call Smart Watch】This fitness activity smart watch full screen for iPhone and Android phones includes a bunch of new features including:The bluetooth smart watch can hang up the phone, receive and display WhatsAPP /Text /Facebook /Twitter /Messenger reminder.Support sedentary reminder, alarm clock, stopwatch, timer,weather information,music control, remote camera control compatible with Android 5.0 and above or iOS 9.0 and above smartphones.

Keep local artifacts out of the build context

Docker sends the build context to the daemon or builder. A .dockerignore prevents local caches, source-control metadata, and a developer’s virtual environment from being sent or copied accidentally.

.venv/
__pycache__/
*.pyc
.git/

You can add other generated directories, local secrets, test output, and editor files according to your repository. Do not ignore files that the image needs, such as manage.py, the project package, templates, migrations, or the dependency file.

Define the Compose service

Compose can build the image and map the host’s port 8000 to the container’s port 8000. A minimal production-shaped local service is:

services:
  web:
    build: .
    ports:
      - '8000:8000'
    command: gunicorn myapp.wsgi:application --bind 0.0.0.0:8000

The command in Compose is intentionally the same production command shown in the Dockerfile. Keeping one clear command avoids accidentally testing one server locally and deploying another. If your image already has the correct CMD, the Compose command can be omitted; leaving it visible is useful when the Compose file is the operational reference for the service.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Start it from the directory containing the Dockerfile and Compose file:

docker compose up --build

The --build flag rebuilds the image before starting the service. Once the container is running, visit http://localhost:8000 or use a local HTTP client. The host port is the first number in 8000:8000; the second number is the port inside the container.

Rank #3
New Bee Guitar Cable 10ft Electric Instrument Bass AMP Cord
  • [Low Noise High Fidelity] New bee guitar cord with 22AWG oxygen-free-copper center conductors provides enhanced signal transfer, the PVC insulation material and the high-density stranded copper double shield provide noise rejection for quiet operation
  • [Ideal for Choice] New bee 1/4 straight and right angle metal connectors, ensures a secure connection in any instrument, pedal, or amp jack. L shape great fro on stage guitar stands
  • [Wide Compatible] Suitable for mixer, power amplifier, microphone, effector, decoder, equalizer, electoronic organ, electric guitar, electric bass and other electronic equipments. Widely used in the installation of smart home, karaoke speaker, professional stage audio, etc
  • [Easy Disassemble] Making incidental repairs quick and easy! Very nice, flexible cable
  • [Dont Hesite to Order] 24 hours customer services and professional technology team are standing by

Useful Compose lifecycle commands

  • docker compose up --build builds and starts the service while displaying its logs.
  • docker compose up -d --build starts it in the background.
  • docker compose logs -f web follows the web service logs.
  • docker compose down stops and removes the Compose-managed containers and network.

These commands do not create a production database, TLS endpoint, or static-file service. They verify that the image can start and that the WSGI process is reachable through the published port.

Verify the WSGI import before debugging Docker networking

If the container exits immediately, first check the Gunicorn target. For a project whose package contains myapp/wsgi.py, the target is myapp.wsgi:application. A typo in the module name or callable produces an import error before Docker networking is relevant.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Check the logs with:

docker compose logs web

Typical startup failures include a missing dependency, an invalid settings value, a missing environment variable, or a migration-related command being run at startup without the required database being available. Read the first traceback in the logs rather than repeatedly rebuilding the image; a source-code or environment error will survive a rebuild.

Separate development from production

Development and production have different optimization goals. A development container should make source edits visible quickly. A production container should be deterministic and should launch Gunicorn. Docker’s documented approach uses a separate development stage with Django’s built-in server and Compose Watch to synchronize source changes without rebuilding for every edit.

Concern Development stage Production stage
Server Django’s built-in development server Gunicorn WSGI process
Source changes Compose Watch synchronization can update files without a full image rebuild Build a new image and deploy an immutable version
Primary goal Fast feedback while editing Controlled, repeatable runtime behavior
Exposure Local machine or a deliberately isolated development network Protected by the hosting platform, proxy, firewall, and HTTPS configuration
Deployment suitability Not suitable for production traffic Intended for production application traffic

Do not solve slow local iteration by replacing the production command with runserver. Instead, select the development stage or Compose configuration explicitly. This preserves a meaningful production test: the command you verify locally is the command you intend to deploy.

Handle Django settings and environment values deliberately

A container image should be portable across environments. Values such as the allowed hostnames, database connection, debug mode, secret key, and trusted origins vary between a developer laptop, staging, and production. Supply them through the environment or your platform’s secret mechanism rather than committing production secrets to the image or repository.

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Rank #4
BSIMB 15.6" Digital Family Calendar & Chore Chart, No Subscription Fees
  • Digital Family Calendar: BSIMB digital calendar wall touch screen puts an end to your chaotic life. Designed for busy families, the digital calendar keeps you organised and in step with your family. Assign different colours and tasks to each family member to make family scheduling easier and more intuitive.
  • Easy Setup and Auto-Sync: Plug in, connect to WLAN and auto-syn your electric calendar in minutes. Digital wall calendar compatible with Google calendar, iCloud calendar, Outlook calendar, Cozi calendar and Yahoo calendar. Add events directly on the device or through the ecalendar app. Electronic calendar stays current whether you're at work or traveling—no manual updates needed.
  • All-In-One Home Assistant: Smart calendar builds habits and encourage independence with personalised chores. Display daily meal plan to reduce the daily ‘What's for dinner?’ stress. To-do lists keep track of everything you want. Turning chores into valuable achievements with stars and rewards, making life easier and more enjoyable.
  • Manage Anytime Anywhere: BSIMB electronic calendar for family stay connected with the powerful ecalendar app. Access and manage your digital wall calendar anytime, anywhere with free features like stars & rewards, photo screensaver, chore charts, meals plans, to-do lists etc. Electronic planner paid features like Magic Import tailor advanced tools for users with special needs.
  • Stay in Touch with Loved Ones: Share photos or videos from your phone to electronic wall calendar with app, instantly update your life moment, and keep in touch with your family, especially those who are far away; you can also surprise your smart calendar digital wall by sending him a wish card; it's also great for keeping tech-illiterate elders in touch with the youngsters.
  • Keep production debug behavior disabled.
  • Set host and origin values for the actual domains that will reach the application.
  • Provide the production secret through a protected environment or secret store.
  • Make the database and cache endpoints configurable per environment.
  • Ensure settings that write files point to directories the runtime user can access.

Do not assume that a value available in your shell is automatically available inside Compose. Declare the environment mapping in the Compose configuration or configure it through the deployment platform, then confirm the container receives the expected non-secret configuration.

Static files are a separate production responsibility

Django’s deployment guidance requires an explicit static-file plan. Application responses and static assets have different caching and serving needs, and the correct arrangement depends on the hosting stack.

Application-managed static files

In one arrangement, the Django deployment collects static assets into the configured static root and an application-aware serving layer makes them available. This requires a writable collection location during the build or release process and a runtime arrangement that can read the collected files.

Reverse-proxy or dedicated static serving

In another arrangement, a reverse proxy, object store, or dedicated static service serves the collected assets while Gunicorn handles dynamic requests. This can keep large or cacheable assets away from the WSGI process, but it adds configuration outside Django.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Whichever architecture you choose, document when collection runs, where the resulting files live, and how a new image or release updates them. A container that serves dynamic pages successfully can still produce a broken site if its CSS, JavaScript, or images were never collected or are not reachable at the configured URL.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Run Django’s deployment checks before production

Django’s documentation states: “Finally, before you deploy your application to production, you should run through our deployment checklist to ensure that your configurations are suitable.” Run the checklist command against the settings you will actually deploy:

python manage.py check --deploy

Run it in the same image and environment shape used for release when possible. The command can reveal insecure or incomplete settings, but a clean result is not a substitute for reviewing your infrastructure and application behavior.

Production review list

  • Do not use manage.py runserver for production traffic. Launch Gunicorn as the container process.
  • Review critical settings. Confirm debug, secret, host, origin, cookie, database, and file-storage values for the production environment.
  • Configure HTTPS. Decide where certificates terminate and ensure the application and proxy agree on secure requests and forwarded headers.
  • Apply static-file configuration. Collect assets and verify that the public paths return the expected files.
  • Arrange error reporting. Container logs should be collected, retained, and visible to the people responsible for the service; application-level error reporting should also be configured where appropriate.
  • Apply performance optimizations. Review database queries, caching, compression, connection behavior, and the Gunicorn process configuration for your workload rather than copying arbitrary values.
  • Use a non-root runtime user. The Dockerfile should drop privileges before starting Gunicorn.
  • Make dependencies reproducible. Keep the dependency and environment definitions under version control and rebuild from them during release.

Test the image as an operator, not only as a developer

A successful image build proves that Docker can assemble layers. A useful verification also proves that the process starts, listens on the intended interface, imports the WSGI module, and returns a response through the published port.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
  1. Build and start with docker compose up --build.
  2. Watch the web logs for Gunicorn startup and import errors.
  3. Request the application through the host port, not by connecting to an internal container address.
  4. Check a page that exercises Django settings and templates, not only a static container response.
  5. Request a known static asset and verify the static-file architecture you selected.
  6. Stop and start the service again to confirm that startup does not depend on an untracked local file.
  7. Run python manage.py check --deploy using the production-oriented settings before release.

If the application needs migrations, run them as an explicit release operation or controlled deployment step. Avoid hiding irreversible database changes inside a process-start command that may run more than once.

Troubleshoot the failures that occur most often

Symptom Likely cause What to check
Browser reports connection refused Gunicorn is not listening, the container stopped, or the port is not published Run docker compose ps, inspect docker compose logs web, and confirm the mapping is 8000:8000.
Container starts but host cannot connect Gunicorn bound to loopback instead of all interfaces Use --bind 0.0.0.0:8000 in the Dockerfile or Compose command.
Gunicorn says it cannot import the application Incorrect project package or WSGI callable Confirm the directory containing wsgi.py and use its dotted module path followed by :application.
ModuleNotFoundError appears at startup A runtime dependency is absent from the image Add it to requirements.txt and rebuild with docker compose up --build.
CSS or JavaScript returns 404 Static assets were not collected or are served by the wrong component Review the static root, collection step, URL, volume or proxy configuration, and file permissions.
Settings work locally but fail in Docker Environment variables were not passed into the container Check Compose environment configuration and the container’s startup logs without printing secret values.
Permission denied while writing files The non-root user cannot write to a configured directory Create the directory during the image build or release step and assign ownership deliberately.
Changes do not appear during development The production image was not rebuilt or source synchronization is not configured Use the development stage with Compose Watch, or rebuild intentionally; do not switch production to runserver.

Move from local Compose to a production platform

Local Compose is a convenient verification and development tool. Production requires decisions that Compose alone does not make: where the image is stored, how it is deployed, how HTTPS terminates, where logs go, how health and restarts are handled, and how persistent data is backed up.

When evaluating Docker-compatible hosting options, carry the same contract forward:

  • The platform must start the image’s Gunicorn command or an equivalent explicit command.
  • It must route external traffic to the container port on which Gunicorn listens.
  • It must provide a secure way to inject environment values and secrets.
  • It must expose logs and an operational restart or rollout mechanism.
  • It must support the static-file and database architecture you selected.

Do not treat a successful local browser check as proof that production is complete. Repeat the deployment checklist with production settings, test HTTPS and static assets at the real domain, and verify that error reporting reaches the intended operators.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

A concise release sequence

  1. Commit the Django source, dependency file, Dockerfile, .dockerignore, and Compose configuration.
  2. Build the multi-stage image and confirm that the final stage runs as a non-root user.
  3. Start the service with docker compose up --build and verify the application through port 8000.
  4. Inspect logs for Gunicorn startup and exercise a dynamic page.
  5. Run the static-file collection and verification procedure required by your chosen architecture.
  6. Run python manage.py check --deploy with production-oriented settings.
  7. Configure HTTPS, environment-specific settings, secret injection, error reporting, and performance controls on the destination platform.
  8. Deploy the image and repeat the endpoint, static-asset, log, and error checks against the production hostname.

This division keeps the responsibilities clear: Docker supplies a repeatable runtime, Gunicorn serves Django in production, Compose makes local verification straightforward, and the deployment environment supplies the networking, HTTPS, persistence, and operations around the container.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

Leave a Reply

Your email address will not be published. Required fields are marked *

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

More from the Wire

  1. World desk4 min
    How to Spot an AI Voice Scam Before Sending MoneyDon’t rely on how a caller sounds. Pause, call back through a known number, and verify the emergency with another trusted person before sending money.
  2. Mountain View desk4 min
    Google’s SynthID Detector: How to Check AI-Generated Images, Video and AudioGoogle’s SynthID Detector looks for an embedded watermark in supported images, video and audio. Here is what its results do—and do not—show.
  3. Redmond desk20 min
    How to create a link to File or Folder in Windows 11Windows 11 gives you several ways to point to a file or folder without moving or duplicating it. You can create a desktop shortcut,…
Recommended PC Tool
Recommended PC Tool
PC Slower Than It Used to Be?Free scan - under a minute
Outdated Drivers Are Slowing You DownFree scan - exact matches

Two free Windows tools

One Free Minute Could Fix That PC

Before you go - each of these free tools takes about a minute and tackles what quietly slows a Windows PC down.

Special offer. View Outbyte info, uninstall instructions, EULA, and Privacy Policy.