Install Discourse for development using Docker

The root cause may be that pg15 modified the default authentication rules.

Configuration file path: /etc/postgresql/15/main/pg_hba.conf

File content is as follows:

# Database administrative login by Unix domain socket
local   all             postgres                                peer

# TYPE  DATABASE        USER            ADDRESS                 METHOD

# "local" is for Unix domain socket connections only
local   all             all                                     peer
# IPv4 local connections:
host all all 0.0.0.0/0 md5
# IPv6 local connections:
host all all ::/0 md5
# Allow replication connections from localhost, by a user with the
# replication privilege.
local   replication     all                                     peer
host    replication     all             127.0.0.1/32            scram-sha-256
host    replication     all             ::1/128                 scram-sha-256

The command executed for backup is as follows:

pg_dump --schema=public -T public.pg_* --file=‘/src/tmp/backups/default/2026-02-02-063003/dump.sql.gz’ --no-owner --no-privileges --verbose --compress=4 --username=postgres discourse_development

The command above reports an error because of the rule local all postgres peer: Peer authentication failed for user "postgres"

Solution idea: Change peer to trust to allow all local environment commands. This means no further authentication (and no password input) is required for any command.

Specific steps:

  1. Copy /etc/postgresql/15/main/pg_hba.conf from the container to local

sudo docker cp discourse_dev:/etc/postgresql/15/main/pg_hba.conf ~/discourse/data/pg_hba.conf

Grant permissions 644

sudo chmod 644 ~/discourse/data/pg_hba.conf

Modify the configuration in data/pg_hba.conf

# Database administrative login by Unix domain socket
local   all   postgres   trust
  1. Modify the d/boot_dev file to mount data/pg_hba.conf into the container, overwriting the default pg configuration file.
docker run -d \
    -p $local_publish:8025:8025 \
    -p $local_publish:3000:3000 \
    -p $local_publish:4200:4200 \
    -p $local_publish:9292:9292 \
    -p $local_publish:9405:9405 \
    -v "$DATA_DIR:/shared/postgres_data:delegated" \
    # The line below is newly added, mounting the configuration file into the container, and only giving the container read-only permission
    -v "$SOURCE_DIR/data/pg_hba.conf:/etc/postgresql/15/main/pg_hba.conf:ro" \
    -v "$SOURCE_DIR:/src:delegated" \
    -e UNICORN_BIND_ALL=true \
    $mount_plugin_symlinks \
    $ENV_ARGS \
    --hostname=discourse \
    --name=discourse_dev \
    --restart=always \
    discourse/discourse_dev:release /sbin/boot
  1. Stop and remove the current container, then rebuild the new container
d/shotdown_dev
d/boot_dev
  1. After rebuilding, start the frontend and backend applications, and test if the backup is normal
d/rails s

# Execute in another command line
d/ember-cli

On the backup page, click backup, wait a few seconds, and then view the backup file list.

1 Like

Based on the experience above, the desire to connect to the postgreSQL database in Docker using a local database client can now be realized.

Modify the configuration in the d/boot_dev file as follows:

docker run -d \
    -p $local_publish:8025:8025 \
    -p $local_publish:3000:3000 \
    -p $local_publish:4200:4200 \
    -p $local_publish:9292:9292 \
    -p $local_publish:9405:9405 \
    # Add port mapping
    -p $local_publish:55432:5432 \
    -v "$DATA_DIR:/shared/postgres_data:delegated" \
    # Keep configuration file mapping
    -v "$SOURCE_DIR/data/pg_hba.conf:/etc/postgresql/15/main/pg_hba.conf:ro" \
    -v "$SOURCE_DIR:/src:delegated" \
    -e UNICORN_BIND_ALL=true \
    $mount_plugin_symlinks \
    $ENV_ARGS \
    --hostname=discourse \
    --name=discourse_dev \
    --restart=always \
    discourse/discourse_dev:release /sbin/boot

Allow all requests to connect to pg:

In the data/pg_hba.conf file, modify the configuration as follows:

# IPv4 local connections:
host all all 0.0.0.0/0 trust
# IPv6 local connections:
host all all ::/0 trust

Rebuild

d/shutdown_dev
d/boot_dev

Now you can connect using a local database client

I am using DBeaver here.

  1. Database port number is 55432, consistent with d/boot_dev. It is 55432 here to avoid conflicts with existing local ports.
  2. Database name
  3. It is recommended to check “Show all databases”
  4. Username
  5. Test the connection
  6. Click OK to save

Finally, I can happily view the data in the database locally.

1 Like

Is it normal that this installation does not display the menu correctly?

Hello, although everything seems to be working after following this tutorial on an Ubuntu 26.04 machine, no emails appear to be sending.

I did start d/mailhog in a dedicated terminal, and I can see the HTML/CSS code of the email sent after a test user registered, but the user receives nothing at the email address I provided…

What did I miss, and how can I fix it? :folded_hands:

mail should appear in at http://localhost:8025 I believe (mailhog port).

this is not a Production install so no email will be sent across the internet - for that you need a full Production install and a compatible email service (which these days usually costs real money as managing trust costs :money_bag: )

1 Like

Thanks @merefield, I did see localhost:8025, but for some reason it wasn’t working, and now everything is fine.

1 Like

Does this solution work? I was unable to get beyond d/boot_dev --init.

Update:
I see, if your developer UID isn’t 1000, like the user discourse in the discourse_dev container this just falls apart it seems.

Update 2:
Yeah I created a user with UID 1000 and everything just worked. So that is definitely the problem.

I tried creating some basic steps to get this running with an alternate UID but with how this is written it wasn’t worth it boot_dev tries to create directories at different parts of the process as the host user while also running docker commands that utilize those directories that were created so you are constantly fighting new directories that are the wrong permission etc etc. I’ll look at the code and see if there is a solution worth upstreaming. It might be worth noting in the documentation this only works for UID 1000. I’ll send a PR and see what upstream says.

2026-05-22 05:48:13.857 UTC [347] FATAL:  data directory "/shared/postgres_data" has wrong ownership
2026-05-22 05:48:13.857 UTC [347] HINT:  The server must be started by the user that owns the data directory.
A bunch of problems I ran into
nastee@station ~/vendsrc/discourse > ./d/boot_dev --init
Using source in: /home/nastee/vendsrc/discourse
Using data in:   /home/nastee/vendsrc/discourse/data/postgres
release: Pulling from discourse/discourse_dev
.....
Digest: sha256:e118af085d4be0486d4d9bfa83ac1c519d9975bed9a08180d10d5ad7c508632c
Status: Downloaded newer image for discourse/discourse_dev:release
docker.io/discourse/discourse_dev:release
f517752802e70b8a9110972bb3ddc0e9343d0c430603e4a9ae3eacc5ec69a2cf
Installing gems...
There was an error while trying to write to `/src/Gemfile.lock`. It is likely that you need to grant write permissions for that path.

Thanks to: There was an error while trying to write to `/src/Gemfile.lock`. It is likely that you need to grant write permissions for that path - #2 by jacque006

I set that file to 777 (yuck), I do that, and it at least installs Gems now but the next docker exec process tries to write to the source directory and cannot since it isn’t running as my user so I get:

 EACCES  EACCES: permission denied, open '/src/_tmp_82_62be1aeb82e80c1d1054dac8bdbc5923'

Ok why not, sudo chmod 4777 . where . is the cloned source directory I am running d/

Which gets me to:

 EACCES  Error while trying to symlink "../../../node_modules/.pnpm/prettier@3.8.1/node_modules/prettier" to "/src/docs/developer-guides/node_modules/prettier". The error happened while trying to create the parent directory for the symlink target. Details: Error: EACCES: permission denied, mkdir '/src/docs/developer-guides/node_modules'

after hitting another perm problem and just giving into chmod 777 -R .

eventually culminating at:

connection to server on socket "/var/run/postgresql/.s.PGSQL.5432" failed: No such file or directory