How to make Postgres in gitlab-ce Docker image NOT use Unix sockets?

Problem to solve

I’ve recently upgraded my Proxmox server from 8.4 to 9, after which first everything looked good, but the Gitlab Docker container started to consume 100 % CPU in some puma process at some point. The used container image was somewhat old, don’t know the exact version any more, so I decided to just upgrade before further debugging. I switched to 18.2.1-ce.0 and am now running into a migration error, because Postgres is unable to start:

2025-08-10_14:49:28.62521 LOG:  could not create Unix socket for address "/var/opt/gitlab/postgresql/.s.PGSQL.5432": Permission denied
2025-08-10_14:49:28.62522 WARNING:  could not create Unix-domain socket in directory "/var/opt/gitlab/postgresql"
2025-08-10_14:49:28.62534 FATAL:  could not create any Unix-domain sockets
2025-08-10_14:49:28.62780 LOG:  database system is shut down

I’m somehwat sure that the problem is related to AppArmor, because whenever the container starts, I see the following logs in dmesg:

[164147.994516] audit: type=1400 audit(1754837366.474:1585466): apparmor="DENIED" operation="create" class="net" info="failed protocol match" error=-13 profile="docker-default" pid=534533 comm="gitaly" family="unix" sock_type="stream" protocol=0 requested="create" denied="create" addr=none

In theory I don’t care about AppArmor too much, but just want to get that problem fixed. So I though of making PostgreSQL simply NOT use sockets at all any more, but wasn’t able to do so. The following configs changes enable that Postgres uses TCP/IP, but it doesn’t disable using sockets. Might be that the additiuonal setting unix_socket_directories is not forarded as expected or …

1420 # postgresql['enable'] = true
1421 postgresql['listen_address'] = 'localhost'
1422 postgresql['unix_socket_directories'] = ''
1423 # postgresql['port'] = 5432
  1 2025-08-10_14:49:28.62161 LOG:  starting PostgreSQL 16.8 on x86_64-pc-linux-gnu, compiled by gcc (Ubuntu 13.3.0-6ubuntu2~24.04) 13.3.0, 64-bit
  2 2025-08-10_14:49:28.62174 LOG:  listening on IPv6 address "::1", port 5432
  3 2025-08-10_14:49:28.62174 LOG:  listening on IPv4 address "127.0.0.1", port 5432
  4 2025-08-10_14:49:28.62521 LOG:  could not create Unix socket for address "/var/opt/gitlab/postgresql/.s.PGSQL.5432": Permission denied
  5 2025-08-10_14:49:28.62522 WARNING:  could not create Unix-domain socket in directory "/var/opt/gitlab/postgresql"
  6 2025-08-10_14:49:28.62534 FATAL:  could not create any Unix-domain sockets
  7 2025-08-10_14:49:28.62780 LOG:  database system is shut down

What do I need to do to make Postgres within the Gitlab container not use Unix sockets at all?

I only found a workaround by disablinyg AppArmor entirely:

 33     security_opt:
 34       - 'apparmor:unconfined'

Steps to reproduce

I simply need to start the container and run into an endless loop of trying to upgrade and failing.

Versions

Please add an x whether options apply, and add the version information.

  • Self-managed
  • GitLab.com SaaS
  • Dedicated

Versions

After reading Database settings | GitLab Docs and guessing it might be localhost vs 127.0.0.1 PostgreSQL driver behaviour, I asked GitLab Duo Agentic Chat. Note that AI might make mistakes, and I cannot test the behaviour atm on ipad.

Try this docker compose entry to force tcp only:

environment:
  GITLAB_OMNIBUS_CONFIG: |
    postgresql['listen_address'] = '127.0.0.1'
    postgresql['port'] = 5432
    postgresql['unix_socket_directories'] = nil
    postgresql['unix_socket_group'] = nil
    postgresql['unix_socket_permissions'] = nil
    gitlab_rails['db_host'] = '127.0.0.1'
    gitlab_rails['db_port'] = 5432

I’ve already tried nil vs. ’’ and it didn’t make any difference. So I gave your additional two Postgres settings a chance in gitlab.rb and as ENV variables in the Docker compose file and it doesn’t change anything. Postgres still tries to create Sockets and fails with default AppArmor settings:

2025-08-14_06:00:37.76639 LOG:  starting PostgreSQL 16.8 on x86_64-pc-linux-gnu, compiled by gcc (Ubuntu 13.3.0-6ubuntu2~24.04) 13.3.0, 64-bit
2025-08-14_06:00:37.76644 LOG:  listening on IPv4 address "127.0.0.1", port 5432
2025-08-14_06:00:37.76918 LOG:  could not create Unix socket for address "/var/opt/gitlab/postgresql/.s.PGSQL.5432": Permission denied
2025-08-14_06:00:37.76920 WARNING:  could not create Unix-domain socket in directory "/var/opt/gitlab/postgresql"
2025-08-14_06:00:37.76921 FATAL:  could not create any Unix-domain sockets
2025-08-14_06:00:37.77089 LOG:  database system is shut down

I wonder if GitLab implements some whitelist or something and if the socket-related settings are even forwarded at all.The changed listen_address is used, but that was supported in the past as well, while the socket-related options wer not part of the original config. According to Postgres, setting unix_socket_directories to empty should do the trick, so if it’s simply never forwarded, that would easily explain things.

The following is how it looks on Windows for Postgres 16, which doesn’t support Unix sockets, and it looks the config option names itself are correct.

 68 #unix_socket_directories = ''   # comma-separated list of directories
 69           # (change requires restart)
 70 #unix_socket_group = ''     # (change requires restart)
 71 #unix_socket_permissions = 0777   # begin with 0 to use octal notation
 72           # (change requires restart)

I feared as much, I did not think it makes much of a difference but wanted to share anyways. I’m not familiar with how the code works or is implemented, but this would be my next step to understand the “code flow” and get a better understanding. unix_socket_directories · Search · GitLab

Found It's not possible to set bundled postgres to listen on an IP/Port (#2597) · Issues · GitLab.org / omnibus-gitlab · GitLab which discussed the initial support for TCP connection settings. PostgreSQL: Documentation: 17: 19.3. Connections and Authentication says

An empty value specifies not listening on any Unix-domain sockets, in which case only TCP/IP sockets can be used to connect to the server.

So, the PostgreSQL behavior seems to be deterministic here, which is a good learning. In my past OSS projects, the PostgreSQL C client library had strange 127.0.0.1 vs localhost behavior which always led to many support questions. But it seems I was on the wrong track because this is the server, not the client.

Next step - reproduce it. I’m not familiar with Proxmox so I used a simple docker compose now. I asked AI to generate me a simple docker-compose.yml to reproduce.

services:
  gitlab:
    image: gitlab/gitlab-ee:latest
    container_name: gitlab
    restart: always
    hostname: 'localhost'
    environment:
      GITLAB_OMNIBUS_CONFIG: |
        # External URL - use any local domain you prefer
        external_url 'http://gitlab.local'
        
        # Configure GitLab Rails to use TCP connection to bundled PostgreSQL
        gitlab_rails['db_host'] = '127.0.0.1'
        gitlab_rails['db_port'] = 5432
        
        # Configure bundled PostgreSQL to listen on TCP
        postgresql['enable'] = true
        postgresql['listen_address'] = '127.0.0.1'
        postgresql['port'] = 5432
        
        # Configure PostgreSQL authentication - use trust auth for localhost (no password)
        postgresql['trust_auth_cidr_addresses'] = ['127.0.0.1/32']
        postgresql['md5_auth_cidr_addresses'] = []
    ports:
      - '80:80'
      - '443:443'
      - '22:22'
      - '5432:5432'  # Expose bundled PostgreSQL on host
    volumes:
      - gitlab_config:/etc/gitlab
      - gitlab_logs:/var/log/gitlab
      - gitlab_data:/var/opt/gitlab

volumes:
  gitlab_config:
  gitlab_logs:
  gitlab_data:

Running this locally in docker compose foreground in Rancher Desktop on my Macbook works.

docker compose up

Maybe the way the Docker container is restarted does not reload the configuration? I use these commands:

docker compose up down
docker compose up -d

Can you share your docker compose yml config, and the commands you are using for restart/up/down?

That won’t help too much, the problem is related to having AppArmor in the host. Docker containers get a default AppArmor profile when started and the Proxmox/Debian I use prevents Unix sockets being created as path in the volume I use for GitLab. Consequently, disabling AppArmor for the container solves the problem as well.

Restarting isn’t a problem as well, I use the following, pretty safely always creating new containers:

 27 docker '--compose' '--file' '[...].yaml' 'down'
 28 docker '--compose' '--file' '[...].yaml' 'pull'
 29 docker '--compose' '--file' '[...].yaml' 'up' '--detach'

So, whatever you test without AppArmor, won’t tell too much.

  1 name: 'gitlab'
  2 services:
  3   gitlab-ce:
  4     container_name: 'gitlab-ce'
  5     image:          'gitlab/gitlab-ce:18.2.1-ce.0'
  6     hostname: 'gitlab-ce.tst.sch'
  7     restart:  'unless-stopped'
  8
  9     environment:
 10       GITLAB_OMNIBUS_CONFIG: |
 11         external_url 'http://192.168.178.44:10081'
 12         gitlab_rails['gitlab_shell_ssh_port'] = 10022
 13
 14     networks:
 15       - 'gitlab'
 16
 17     # The webserver inside the container always listens on the port given by "external_url"! Which
 18     # is e.g. different to SSH, which seems to listen on port 22 always. Seems safest to align ports
 19     # or we might end up with wrong external URLs in mails or something.
 20     # https://forum.gitlab.com/t/whats-the-correct-value-of-external-url-with-custom-published-host-in-docker/119115 21     #
 22     # 10080 isn't used, because it's blocked by default by many browsers these days.
 23     # https://searchfox.org/mozilla-central/source/netwerk/base/nsIOService.cpp#106
 24     ports:
 25       - '127.0.0.1:10022:22'
 26       - '127.0.0.1:10081:10081'
 27       - '127.0.0.1:10443:443'
 28
 29     # AppArmor prevents creating Unix sockets by Postgres. Wasn't able to disable Unix sockets and
 30     # keeping AppArmor and not sure if I want to maintain my own profile yet.
 31     #
 32     # https://forum.gitlab.com/t/how-to-make-postgres-in-gitlab-ce-docker-image-not-use-unix-sockets/129462
 33     security_opt:
 34       - 'apparmor:unconfined'
 35
 36     # Docker gives only 64 MiB per container by default, but we need more.
 37     shm_size: '256m'
 38
 39     volumes:
 40       - type:   'volume'
 41         source: 'gitlab-ce'
 42         target: '/etc/gitlab'
 43         volume:
 44           subpath: 'conf'
 45       - type:   'volume'
 46         source: 'gitlab-ce'
 47         target: '/var/opt/gitlab'
 48         volume:
 49           subpath: 'data'
 50       - type:   'volume'
 51         source: 'gitlab-ce'
 52         target: '/var/log/gitlab'
 53         volume:
 54           subpath: 'logs'
 55
 56 networks:
 57   gitlab:
 58     external: false
 59     name:     'gitlab'
 60
 61 volumes:
 62   gitlab-ce:
 63     external: true

Thanks for the config details. My config above works without creating a unix socket but instead uses tcp on 127.0.0.1. I think that is what you have been looking for initially.

Your second config doesn’t contain disabling unix_socket_directories at all and even with that explicitly disabled Postgres still created Unix sockets, as I already wrote. And you said yourself that you are not even using AppArmor, so are not triggering the problem at all.

So why do you think that a socket is not created? How did you verify? It doesn’t matter if Postgres provides TCP/IP additionally and a client might use that, it needs to provide TCP/IP exclusively. What exactly in your new config do you think is responsible for that?