Sara
Sara

Reputation: 11

Citus + Patroni in Docker: could not change permissions of directory "/var/lib/postgresql/data": Operation not permitted

I want to set up a cluster in Docker that contains citus + patroni and the corresponding etcd for Postgres

I have this dockerfile:

FROM postgres:16

RUN apt-get update && \
    apt-get install -y python3 python3-pip python3-venv build-essential libpq-dev

RUN python3 -m venv /patroni-venv

RUN /bin/bash -c "source /patroni-venv/bin/activate && \
    pip install patroni[etcd] psycopg2-binary behave coverage flake8>=3.0.0 mock pytest-cov pytest setuptools"


COPY patroni.yml /etc/patroni.yml

ENTRYPOINT ["/bin/bash", "-c", "source /patroni-venv/bin/activate && patroni /etc/patroni.yml"]

This docker-compose:

version: '3'

services:
  etcd:
    image: quay.io/coreos/etcd:v3.5.0

    container_name: etcd
    networks:
      - citus_network
    ports:
      - "2389:2379"
      - "2390:2380"
    command:
      - /usr/local/bin/etcd
      - --data-dir=/etcd-data
      - --name=etcd0
      - --listen-client-urls=http://0.0.0.0:2389
      - --advertise-client-urls=http://etcd:2389
      - --listen-peer-urls=http://0.0.0.0:2390
      - --initial-advertise-peer-urls=http://etcd:2390
      - --initial-cluster=etcd0=http://etcd:2390
      - --enable-v2=true
  citus:
    image: citusdata/citus:10.2
    container_name: citus
    environment:
      POSTGRES_PASSWORD: your_password
    networks:
      - citus_network
    depends_on:
      - etcd
    ports:
      - "5433:5432"  # Cambiar puerto para evitar conflicto
    volumes:
      - citus_data:/var/lib/postgresql/data
  patroni:
    build:
      context: .
      dockerfile: Dockerfile
    container_name: patroni
    environment:
      PATRONI_NAME: citus
      PATRONI_ETCD_HOSTS: etcd:2389
      PATRONI_POSTGRESQL_DATA_DIR: /var/lib/postgresql/data
      PATRONI_POSTGRESQL_PGPASSWORD: your_password
      PATRONI_POSTGRESQL_LISTEN: 0.0.0.0:5432
      PATRONI_POSTGRESQL_CONNECT_ADDRESS: patroni:5432
      PATRONI_SUPERUSER_USERNAME: postgres
      PATRONI_SUPERUSER_PASSWORD: your_password
    networks:
      - citus_network
    depends_on:
      - etcd
      - citus
    ports:
      - "8009:8008"  # Cambiar puerto para evitar conflicto
    volumes:
      - patroni_data:/var/lib/postgresql/data

networks:
  citus_network:
    driver: bridge

volumes:
  citus_data:
  patroni_data:

And this is my patroni.yml:

scope: citus
namespace: /db/
name: citus

restapi:
  listen: 0.0.0.0:8008
  connect_address: patroni:8008

etcd:
  host: etcd:2389
  protocol: http
  version: "v3"

bootstrap:
  dcs:
    ttl: 30
    loop_wait: 10
    retry_timeout: 10
    maximum_lag_on_failover: 1048576
    postgresql:
      use_pg_rewind: true
      parameters:
        wal_level: replica
        hot_standby: "on"
        wal_keep_segments: 8
        max_wal_senders: 5
        max_replication_slots: 5

  initdb:
    - encoding: UTF8
    - data-checksums

  pg_hba:
    - host replication repl_user 0.0.0.0/0 md5
    - host all all 0.0.0.0/0 md5

  users:
    admin:
      password: admin_password
      options:
        - createrole
        - createdb

postgresql:
  listen: 0.0.0.0:5432
  connect_address: patroni:5432
  data_dir: /var/lib/postgresql/data
  bin_dir: /usr/lib/postgresql/16/bin
  authentication:
    superuser:
      username: postgres
      password: your_password
    replication:
      username: repl_user
      password: repl_password
  parameters:
    unix_socket_directories: '/var/run/postgresql, /tmp'

After several attempts I have not been able to solve this error:

2024-05-26 21:04:02,630 INFO: Selected new etcd server http://etcd:2389
2024-05-26 21:04:02,641 INFO: No PostgreSQL configuration items changed, nothing to reload.
2024-05-26 21:04:02,648 INFO: Lock owner: None; I am citus
2024-05-26 21:04:02,656 INFO: trying to bootstrap a new cluster
The files belonging to this database system will be owned by user "patroni_user".
This user must also own the server process.

The database cluster will be initialized with locale "en_US.utf8".
The default text search configuration will be set to "english".

Data page checksums are enabled.

initdb: error: could not change permissions of directory "/var/lib/postgresql/data": Operation not permitted
2024-05-26 21:04:02,686 INFO: removing initialize key after failed attempt to bootstrap the cluster
2024-05-26 21:04:02,687 INFO: renaming data directory to /var/lib/postgresql/data.failed
2024-05-26 21:04:02,687 ERROR: Could not rename data directory /var/lib/postgresql/data
Traceback (most recent call last):
  File "/patroni-venv/lib/python3.11/site-packages/patroni/postgresql/__init__.py", line 1317, in move_data_directory
    os.rename(self._data_dir, new_name)
OSError: [Errno 16] Device or resource busy: '/var/lib/postgresql/data' -> '/var/lib/postgresql/data.failed'
Process Process-1:
Traceback (most recent call last):
  File "/usr/lib/python3.11/multiprocessing/process.py", line 314, in _bootstrap
    self.run()
  File "/usr/lib/python3.11/multiprocessing/process.py", line 108, in run
    self._target(*self._args, **self._kwargs)
  File "/patroni-venv/lib/python3.11/site-packages/patroni/__main__.py", line 232, in patroni_main
    abstract_main(Patroni, configfile)
  File "/patroni-venv/lib/python3.11/site-packages/patroni/daemon.py", line 174, in abstract_main
    controller.run()
  File "/patroni-venv/lib/python3.11/site-packages/patroni/__main__.py", line 192, in run
    super(Patroni, self).run()
  File "/patroni-venv/lib/python3.11/site-packages/patroni/daemon.py", line 143, in run
    self._run_cycle()
  File "/patroni-venv/lib/python3.11/site-packages/patroni/__main__.py", line 201, in _run_cycle
    logger.info(self.ha.run_cycle())
                ^^^^^^^^^^^^^^^^^^^
  File "/patroni-venv/lib/python3.11/site-packages/patroni/ha.py", line 1980, in run_cycle
    info = self._run_cycle()
           ^^^^^^^^^^^^^^^^^
  File "/patroni-venv/lib/python3.11/site-packages/patroni/ha.py", line 1797, in _run_cycle
    return self.post_bootstrap()
           ^^^^^^^^^^^^^^^^^^^^^
  File "/patroni-venv/lib/python3.11/site-packages/patroni/ha.py", line 1681, in post_bootstrap
    self.cancel_initialization()
  File "/patroni-venv/lib/python3.11/site-packages/patroni/ha.py", line 1674, in cancel_initialization
    raise PatroniFatalException('Failed to bootstrap cluster')
patroni.exceptions.PatroniFatalException: Failed to bootstrap cluster

I am thankful for any kind of help

I need to be able to set up a citus + patroni without using ssl to connect to the database.

Is there any way to do it? Even if it means starting from 0

Upvotes: 1

Views: 446

Answers (1)

Sara
Sara

Reputation: 11

I finally managed to solve it. I leave the solution here in case it could help someone.

My final documents look like this: DOCKERFILE

FROM postgres:16

# Instalar dependencias necesarias
RUN apt-get update && \
    apt-get install -y python3 python3-pip python3-venv build-essential libpq-dev

# Crear un entorno virtual de Python
RUN python3 -m venv /patroni-venv

# Activar el entorno virtual y instalar las dependencias necesarias
RUN /bin/bash -c "source /patroni-venv/bin/activate && \
    pip install patroni[etcd] psycopg2-binary behave coverage flake8>=3.0.0 mock pytest-cov pytest setuptools"

# Copiar el archivo de configuración de Patroni
COPY patroni.yml /etc/patroni.yml

USER postgres

# Establecer el comando de inicio predeterminado para usar el entorno virtual
ENTRYPOINT ["/bin/bash", "-c", "source /patroni-venv/bin/activate && patroni /etc/patroni.yml"]

docker-compose.yml

version: '3'

services:
  etcd:
    image: quay.io/coreos/etcd:v3.5.0
    container_name: etcd
    networks:
      - citus_network
    ports:
      - "2389:2379"
      - "2390:2380"
    command:
      - /usr/local/bin/etcd
      - --data-dir=/etcd-data
      - --name=etcd0
      - --listen-client-urls=http://0.0.0.0:2389
      - --advertise-client-urls=http://etcd:2389
      - --listen-peer-urls=http://0.0.0.0:2390
      - --initial-advertise-peer-urls=http://etcd:2390
      - --initial-cluster=etcd0=http://etcd:2390
      - --enable-v2=true
  citus:
    image: citusdata/citus:10.2
    container_name: citus
    environment:
      POSTGRES_PASSWORD: your_password
    networks:
      - citus_network
    depends_on:
      - etcd
    ports:
      - "5433:5432"  # Cambiar puerto para evitar conflicto
    volumes:
      - citus_data:/var/lib/postgresql/data
  patroni:
    build:
      context: .
      dockerfile: Dockerfile
    container_name: patroni
    environment:
      PATRONI_NAME: citus
      PATRONI_SCOPE: postgres
      PATRONI_ETCD_HOSTS: etcd:2389
      PATRONI_POSTGRESQL_DATA_DIR: /var/lib/postgresql/data
      PATRONI_POSTGRESQL_PGPASSWORD: your_password
      PATRONI_POSTGRESQL_LISTEN: 0.0.0.0:5432
      PATRONI_POSTGRESQL_CONNECT_ADDRESS: patroni:5432
      PATRONI_SUPERUSER_USERNAME: postgres
      PATRONI_SUPERUSER_PASSWORD: your_password
    networks:
      - citus_network
    depends_on:
      - etcd
      - citus
    ports:
      - "8009:8008"  # Cambiar puerto para evitar conflicto
    volumes:
      - patroni_data:/var/lib/postgresql/data

  patroni2:
    build:
      context: .
      dockerfile: Dockerfile
    container_name: patroni2
    environment:
      PATRONI_NAME: patroni2
      PATRONI_SCOPE: postgres
      PATRONI_ETCD_HOSTS: etcd:2389
      PATRONI_POSTGRESQL_DATA_DIR: /var/lib/postgresql/data
      PATRONI_POSTGRESQL_PGPASSWORD: your_password
      PATRONI_POSTGRESQL_LISTEN: 0.0.0.0:5432
      PATRONI_POSTGRESQL_CONNECT_ADDRESS: patroni:5432
      PATRONI_SUPERUSER_USERNAME: postgres
      PATRONI_SUPERUSER_PASSWORD: your_password
    networks:
      - citus_network
    depends_on:
      - etcd
      - citus
    ports:
      - "8010:8008"  # Cambiar puerto para evitar conflicto
    volumes:
      - patroni_data2:/var/lib/postgresql/data

networks:
  citus_network:
    driver: bridge

volumes:
  citus_data:
  patroni_data:
  patroni_data2:

patroni.yml

scope: citus
namespace: /db/
name: citus

restapi:
  listen: 0.0.0.0:8008
  connect_address: patroni:8008

etcd:
  host: etcd:2389
  protocol: http
  version: "v3"

bootstrap:
  dcs:
    ttl: 30
    loop_wait: 10
    retry_timeout: 10
    maximum_lag_on_failover: 1048576
    postgresql:
      use_pg_rewind: true
      parameters:
        wal_level: replica
        hot_standby: "on"
        wal_keep_segments: 8
        max_wal_senders: 5
        max_replication_slots: 5

  initdb:
    - encoding: UTF8
    - data-checksums

  pg_hba:
    - host replication repl_user 0.0.0.0/0 md5
    - host all all 0.0.0.0/0 md5

  users:
    admin:
      password: admin_password
      options:
        - createrole
        - createdb

postgresql:
  listen: 0.0.0.0:5432
  connect_address: patroni:5432
  data_dir: /var/lib/postgresql/data
  bin_dir: /usr/lib/postgresql/16/bin
  authentication:
    superuser:
      username: postgres
      password: your_password
    replication:
      username: repl_user
      password: repl_password
  parameters:
    unix_socket_directories: '/var/run/postgresql, /tmp'

Additionally, before doing the build and up you have to create the volumes manually and change the permissions like this:

Good luck!

sudo mkdir -p /var/lib/docker/volumes/patroni_patroni_data/_data
sudo mkdir -p /var/lib/docker/volumes/patroni_patroni_data2/_data
sudo mkdir -p /var/lib/docker/volumes/citus_citus_data/_data
sudo chown -R 1000:1000 /var/lib/docker/volumes/patroni_patroni_data/_data
sudo chown -R 1000:1000 /var/lib/docker/volumes/patroni_patroni_data2/_data
sudo chown -R 1000:1000 /var/lib/docker/volumes/citus_citus_data/_data
sudo chmod -R 700 /var/lib/docker/volumes/patroni_patroni_data/_data
sudo chmod -R 700 /var/lib/docker/volumes/patroni_patroni_data2/_data
sudo chmod -R 700 /var/lib/docker/volumes/citus_citus_data/_data

Upvotes: 0

Related Questions