Hardware FixRecommendedDevice not working? Your driver may be the problemCheck updates for common hardware issues.Fix DriversHalloween DealsAmazon USHalloween week deals: useful picks before month-endAmazon US: current deals, useful picks and tech finds.Check DealsWindows FixRecommendedWindows errors stealing your time? Find the fix fastScan stability, cleanup and performance issues.Fix Now×
Skip to content
World desk10 min

How to Install Drupal with Docker Compose (PostgreSQL, Persistence, and Troubleshooting)

Run Drupal 10 with PostgreSQL using Docker Compose, finish the browser installer, and keep your site files and database safe across container restarts.
Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

The quickest repeatable way to run Drupal locally is to define Drupal and PostgreSQL in a Compose file, start both containers, and finish Drupal’s browser installer at http://localhost:8080. In the installer, select PostgreSQL and use postgres as the database host—not localhost. The hostname is the PostgreSQL service name inside the Compose network.

This guide shows a working setup, explains which data survives container recreation, covers Drupal’s database alternatives, and gives recovery steps for the failures most likely to occur during installation.

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.

What you need before installing

Install Docker Desktop, or install Docker Engine, the Docker CLI, and the Docker Compose plugin. Docker documents both installation paths. Docker Desktop is generally the simpler choice on Windows and macOS; a Linux host can use the Engine, CLI, and Compose plugin directly.

Drupal’s documentation recommends Linux or a similar operating system for hosting and describes Windows as supported for development environments. The containers isolate most host-specific details, but Docker itself still must be running before you start the project.

  • A working Docker installation with the docker compose command.
  • A terminal opened in a new, empty project directory.
  • Enough disk space for Drupal core, extensions, uploaded media, generated files, and backups. Drupal.org states that core files require about 100 MB (2025), but total site storage is not fixed and depends on the site.
  • At least PHP 8.3 or a higher PHP 8 version and a minimum PHP memory size of 64 MB are listed by Drupal.org (2025). The official Drupal container supplies PHP for the application; these figures are useful when evaluating custom images or a non-containerized companion service.

Choose a directory that you can back up. The Compose file, any bind-mounted Drupal files, and the PostgreSQL data volume together define your installation.

Create the Compose project

1. Make a project directory

  1. Create and enter a directory, for example drupal-compose.
  2. Create a file named compose.yaml in that directory.

Compose reads the file in the current directory when you run commands such as docker compose up. Keeping the file under version control makes the service definitions reproducible, but do not commit production passwords or other secrets.

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

2. Start with the official two-service definition

The following arrangement is adapted from the Docker Official Image example. It exposes Drupal on port 8080 and puts both services on the project’s default Compose network.

services:
  drupal:
    image: drupal:10-apache
    ports:
      - "8080:80"
    volumes:
      - /var/www/html/modules
      - /var/www/html/profiles
      - /var/www/html/themes
      - /var/www/html/sites
    restart: always
  postgres:
    image: postgres:16
    environment:
      POSTGRES_PASSWORD: example
    restart: always

The four Drupal volume entries are container paths. They allow image initialization to populate Drupal’s site directories and allow those files to remain available when the Drupal container is recreated. The short example does not define persistent storage for PostgreSQL, so it is suitable for learning but should not be treated as a durable site.

3. Add an explicit PostgreSQL volume for a durable local site

Before installing content you care about, add a named volume at PostgreSQL’s data directory and declare it at the end of the file:

services:
  drupal:
    image: drupal:10-apache
    ports:
      - "8080:80"
    volumes:
      - /var/www/html/modules
      - /var/www/html/profiles
      - /var/www/html/themes
      - /var/www/html/sites
    restart: always
  postgres:
    image: postgres:16
    environment:
      POSTGRES_PASSWORD: example
    volumes:
      - postgres_data:/var/lib/postgresql/data
    restart: always

volumes:
  postgres_data:

This named volume is separate from the Drupal file mounts. It holds PostgreSQL’s database files when the database container is stopped or recreated. A container restart is not a backup: protect the volume with a backup plan appropriate to your environment.

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

The password in this example is intentionally simple so the browser setup is easy to follow. Replace it before using the project beyond a throwaway demonstration, and keep the replacement out of publicly shared Compose files.

Launch Drupal and PostgreSQL

  1. In the directory containing compose.yaml, run docker compose up.
  2. Wait for both images to download and for initialization to complete. The first launch can take longer because Docker must pull the Drupal and PostgreSQL images and PostgreSQL must create its initial cluster.
  3. Open http://localhost:8080 in a browser. Docker’s official instructions describe visiting that address, or http://host-ip:8080 when connecting through another host.

Keep the terminal attached during the first start so you can see errors. When you are satisfied that the services start correctly, stop the foreground process with Ctrl+C and relaunch in the background with docker compose up -d. The containers’ restart policy is always, so Docker will attempt to restart them after a failure or daemon restart.

To see the project’s state, run docker compose ps. To inspect startup messages, use docker compose logs drupal or docker compose logs postgres. Add -f to follow a log stream while reproducing a problem.

Complete Drupal’s browser installer

Choose the installation profile and language

Open the site at port 8080 and follow Drupal’s installer. Select the language and installation profile requested by your project. The profile determines which initial configuration Drupal creates; it does not change the Compose networking described below.

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

Enter the PostgreSQL connection details

When Drupal asks for a database, select PostgreSQL and enter these values for the Compose file above:

Drupal field Value Why
Database type PostgreSQL The database service uses the postgres:16 image.
Database name postgres The PostgreSQL image creates this default database for the initial setup when no other database name is specified.
Database username postgres This is the default administrative database user created by the image.
Database password example It matches POSTGRES_PASSWORD in compose.yaml.
Database host postgres This is the Compose service name and the DNS name visible to Drupal on the project network.
Database port Leave the default PostgreSQL port unless you changed the container configuration Drupal connects to the database over the internal Compose network, not through the host’s published web port.

Do not enter localhost as the database host. Inside the Drupal container, localhost refers to the Drupal container itself. The name postgres resolves to the separate PostgreSQL container because it matches the service key.

If you change the service key, use the new key as the host. Likewise, if you change the password or create a different database user, the values in Drupal must match the database environment and initialization state.

Set the site and administrator information

Continue through the form for the site name, site email, administrator username, administrator password, and administrator email. Drupal’s Composer documentation describes this web setup as collecting database credentials, an administrator name, and basic site information. Use an administrator password that is unique to this site.

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

Submit the installer and wait for Drupal to create its schema and initial configuration. A successful completion redirects you into the new site. If the form reports a database connection error, stop and check the troubleshooting section rather than repeatedly submitting unchanged values.

How persistence works

Drupal code, themes, modules, and site files

The example mounts /var/www/html/modules, /var/www/html/profiles, /var/www/html/themes, and /var/www/html/sites. These mounts are intended to let initialization populate the directories and retain site files when the container is replaced. They cover important Drupal-managed content, including the sites tree where site-specific settings and uploaded files are commonly kept.

They do not turn every path in the image into an independently backed-up host directory. Treat the Compose definition and the mounted data as separate assets: preserve the YAML file, inspect what Docker created for the anonymous Drupal volumes, and back up the site files you need to restore.

PostgreSQL data

The explicit postgres_data volume is the durable location for PostgreSQL’s data directory. Running docker compose stop or recreating a container does not remove a named volume. Conversely, a command that removes the project’s volumes can delete the database, so read the confirmation carefully before using a destructive cleanup command.

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.

A volume is not a logical database backup. For a recoverable site, schedule database dumps and copy Drupal’s files to storage outside the Docker host. Test restoration before relying on the backup.

What happens after a restart

With the named PostgreSQL volume and the Drupal mounts in place, docker compose restart restarts the services without intentionally deleting their data. If the Docker daemon or host reboots, restart: always instructs Docker to bring the containers back when the daemon is available. You still need to verify that the volume is attached and that the site opens after a host-level restart.

Database choices: PostgreSQL, MySQL, or SQLite

Drupal supports MariaDB, MySQL, PostgreSQL, and SQLite. The container image can use SQLite without a second database container. MySQL and PostgreSQL require a separate database service whose credentials and service-name hostname agree with Drupal’s installer.

Choice Containers Operational complexity Best fit Development-to-production similarity
SQLite One Drupal container Lowest for a disposable local demo; no database service to initialize A quick experiment or temporary prototype Lower when production uses a server database
PostgreSQL Drupal plus PostgreSQL Requires a second service, credentials, a database volume, and database backups A multi-service development stack or a PostgreSQL production target High when production also uses PostgreSQL
MySQL or MariaDB Drupal plus the selected database service Comparable multi-service setup; use matching image variables and a service-name host Projects that must match existing MySQL-compatible hosting High when production uses the same engine

For this walkthrough, PostgreSQL is used because the supplied Compose example defines it explicitly. If you switch engines, do not keep PostgreSQL’s credentials or hostname assumptions: select the corresponding Drupal database type and configure the second service according to that image’s documented environment variables.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Common installation problems and fixes

The browser cannot open port 8080

  • Confirm Docker is running and execute docker compose ps.
  • Check the Drupal logs with docker compose logs drupal.
  • Make sure another host process is not already using port 8080. Change the left side of "8080:80" to an unused host port, such as "8081:80", then open the matching URL.
  • When connecting from another machine, use the Docker host’s IP address and the published port rather than that remote machine’s localhost.

Drupal says it cannot connect to PostgreSQL

  • Use postgres for the database host. Do not use localhost or the host machine’s IP address for this internal connection.
  • Check that the database service is running with docker compose ps and inspect docker compose logs postgres.
  • Confirm the installer password exactly matches POSTGRES_PASSWORD.
  • Allow PostgreSQL to finish first-time initialization, then reload the installer. The service may be running while its initial database setup is still in progress.
  • If you changed POSTGRES_PASSWORD after the named volume was initialized, the existing database keeps its original credentials. Changing the environment value alone does not reset an already initialized database.

The site worked, then the database disappeared

Check whether the PostgreSQL service had a named volume before the container was removed. The short official example does not include one. Add postgres_data:/var/lib/postgresql/data, declare postgres_data under the top-level volumes key, and restore from a dump if the original database files were deleted.

A Drupal module reports a missing PHP extension

The Drupal image does not include every PHP extension that modules may require. When a module needs an absent extension, build a custom image with a Dockerfile that starts FROM drupal:10-apache and installs the required extension, then change the Compose service to build that image. Identify the module’s exact requirement before modifying the image; installing unrelated extensions increases maintenance work.

Changes appear to vanish after container recreation

Determine where the change was written. Files under the mounted Drupal paths and data under postgres_data are designed to persist. Files written elsewhere in the container filesystem can disappear when the container is replaced. Keep custom code in a deliberate bind mount or image build, and keep database content in PostgreSQL rather than in temporary container layers.

Safe lifecycle commands

Goal Command Effect
Start in the foreground docker compose up Creates or starts services and displays live logs.
Start in the background docker compose up -d Creates or starts services and returns control of the terminal.
View service status docker compose ps Shows whether the Drupal and PostgreSQL containers are running.
Follow Drupal logs docker compose logs -f drupal Streams web-container output while you diagnose startup or request errors.
Follow PostgreSQL logs docker compose logs -f postgres Streams database initialization and connection output.
Stop services without removing them docker compose stop Stops containers while leaving the project resources and volumes in place.
Restart services docker compose restart Restarts the existing containers without intentionally deleting volumes.
Remove the project docker compose down Removes the project’s containers and network; named volumes are retained unless you explicitly request volume removal.

Use destructive volume-removal options only when you intentionally want a clean installation. Removing the PostgreSQL volume removes the database stored there.

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

When this setup is appropriate

This Compose project is well suited to local development, module and theme work, demonstrations, and reproducible test environments. It gives Drupal a predictable database hostname and lets you start the stack with one command.

It is not, by itself, a production hardening plan. Before exposing a site publicly, replace example credentials, review filesystem permissions, protect administrator access, configure backups, decide how secrets are supplied, and place the web service behind the HTTPS and network controls required by your hosting environment. The official example’s restart: always setting improves availability after a Docker restart but does not provide monitoring, database replication, or disaster recovery.

Installation checklist

  • Docker Desktop or Docker Engine, CLI, and Compose plugin installed.
  • compose.yaml saved in the directory from which you run Compose.
  • Drupal exposed on a free host port, such as 8080:80.
  • PostgreSQL service named postgres.
  • Drupal volume mounts present for modules, profiles, themes, and sites.
  • A named PostgreSQL volume added before creating valuable content.
  • Installer database type set to PostgreSQL.
  • Installer host set to postgres, with database name and credentials matching the Compose configuration.
  • Site administrator details completed and a unique password chosen.
  • Backups planned for both the PostgreSQL database and Drupal’s retained files.

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
Crashes, No Sound, or Screen Glitches?Free driver scan
Windows Errors? Fix Them Before They SpreadFree repair scan

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.