Docker-compose config for running as a specific user with persisted data

1. Describe your incident:

I am trying to configure a docker-compose file to run graylog as a specific user in linux mint as I have changed the storage directory for /usr/share/graylog/data in order to persist the files in the host OS it is /opt/config/graylog_data

Unfortunately nothing I have tried has worked the graylog container doesn’t seem to have privileges to write to its own docker volume stored files however I do have permission for my configured /usr/share/graylog/data directory (For some reason it successfully created all the required folders in /usr/share/graylog/data but fails to create ‘config/graylog.conf’ I had to manually create this file then it started throwing the exception trying to create /etc/graylog/server folder)

The docker container logs are currently erroring on creating the following folder

Caused by: IOException: Directory '/etc/graylog/server' could not be created
	at FileUtils.openOutputStream(FileUtils.java:361)
	at FileUtils.writeStringToFile(FileUtils.java:2015)
	at FileUtils.writeStringToFile(FileUtils.java:1983)
	at NodeId.persist(NodeId.java:85)
	at NodeId.generate(NodeId.java:75)

2. Describe your environment:

GRAYLOG_PASSWORD_SECRET="hash"
GRAYLOG_ROOT_PASSWORD_SHA2="otherhash"
GRAYLOG_HTTP_EXTERNAL_URI="192.168.2.11:9002"
# The directory where data and configuration will be stored.
CONFIGROOT=/opt/config/
#User Group IDs and User ID's
LOGPUID=1000
LOGPGID=1000
# Your timezone, https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
TZ=Australia/Sydney
GRAYLOG_GID=1100
GRAYLOG_UID=1100

docker-compose.yml

version: "3.8"

services:
  mongodb:
    image: "mongo:4.2"
    environment:
      - PUID=${LOGPUID} # default user id, defined in .env
      - PGID=${LOGPGID} # default group id, defined in .env
      - TZ=${TZ} # timezone, defined in .env
    volumes:
      - /etc/localtime:/etc/localtime:ro
      - ${CONFIGROOT}/mongodb_data:/data/db
    restart: unless-stopped
    networks:
      - graylog

  elasticsearch:
    image: "docker.elastic.co/elasticsearch/elasticsearch-oss:7.10.2"
    environment:
      - PUID=${LOGPUID} # default user id, defined in .env
      - PGID=${LOGPGID} # default group id, defined in .env
      - TZ=${TZ} # timezone, defined in .env
      - http.host=0.0.0.0
      - transport.host=localhost
      - network.host=0.0.0.0
      - "ES_JAVA_OPTS=-Xms512m -Xmx512m"
    ulimits:
      memlock:
        hard: -1
        soft: -1
    mem_limit: 1g
    volumes:
      - /etc/localtime:/etc/localtime:ro
      - ${CONFIGROOT}/es_data:/usr/share/elasticsearch/data
    restart: unless-stopped
    networks:
      - graylog

  graylog:
    image: "graylog/graylog:4.2.5"
    entrypoint: "/usr/bin/tini -- wait-for-it elasticsearch:9200 --  /docker-entrypoint.sh"
    user: ${GRAYLOG_UID}:${GRAYLOG_GID}
    group_add:
      - 0 
      - 1000
    environment:
      - GRAYLOG_PUID=${GRAYLOG_UID} # default user id, defined in .env
      - GRAYLOG_PGID=${GRAYLOG_GID} # default group id, defined in .env
      - TZ=${TZ} # timezone, defined in .env
      - GRAYLOG_PASSWORD_SECRET=${GRAYLOG_PASSWORD_SECRET}
      - GRAYLOG_ROOT_PASSWORD_SHA2=${GRAYLOG_ROOT_PASSWORD_SHA2}
      - GRAYLOG_HTTP_EXTERNAL_URI=http://${GRAYLOG_HTTP_EXTERNAL_URI}/
      - GRAYLOG_MONGODB_URI=mongodb://mongodb:27017/graylog
      - GRAYLOG_ELASTICSEARCH_HOSTS=http://elasticsearch:9200
    links:
      - mongodb
      - elasticsearch
    depends_on:
      - mongodb
      - elasticsearch
    ports:
    - "5044:5044/tcp"   # Beats
    - "5140:5140/udp"   # Syslog
    - "5140:5140/tcp"   # Syslog
    - "5555:5555/tcp"   # RAW TCP
    - "5555:5555/udp"   # RAW UDP
    - "9002:9002/tcp"   # Server API
    - "12201:12201/tcp" # GELF TCP
    - "12201:12201/udp" # GELF UDP
    - "13301:13301/tcp" # Forwarder data
    - "13302:13302/tcp" # Forwarder config
    volumes:
      - /etc/localtime:/etc/localtime:ro
      - ${CONFIGROOT}/graylog_data:/usr/share/graylog/data
    restart: unless-stopped
    networks:
      - graylog

networks:
  graylog:
    driver: bridge

3. What steps have you already taken to try and solve the problem?

I’ve created a non login enabled new user for graylog with uid and gid as 1100 in the host os
uid=1100(graylog) gid=1100(graylog) groups=1100(graylog)
I’ve given that account ownership of /opt/config/graylog_data recursively
drwxr-xr-x 8 graylog graylog 4096 Jan 18 22:36 graylog_data
I’ve tried adding
user: ${GRAYLOG_UID}:${GRAYLOG_GID}
environment:

  • GRAYLOG_PUID=${GRAYLOG_UID} # default user id, defined in .env
  • GRAYLOG_PGID=${GRAYLOG_GID} # default group id, defined in .env
  • GRAYLOG_UID=${GRAYLOG_UID} # default user id, defined in .env
  • GRAYLOG_GID=${GRAYLOG_GID} # default group id, defined in .env
  • PUID=${LOGPUID} # default user id, defined in .env
  • PGID=${LOGPGID} # default group id, defined in .env
    group_add:
    • 0
    • 1000
    • 1100

I’ve added each of these items above incrementally when the previous one did not resolve it

I’ve tried coping over the example config from within the container
cp graylog.conf.example /usr/share/graylog/data/config/graylog.conf

Nothing seems to help I have entered the console in the container and I don’t have write permission as graylog to /etc folder which the install is trying to create a graylog folder in

The id properties look correct in the container, but i don’t seem to have root access in the docker container though it looks like the group_add has successfully added the graylog to the root group

graylog@5bbbf358d857:/etc$ id
uid=1100(graylog) gid=1100(graylog) groups=1100(graylog),0(root)
graylog@5bbbf358d857:/etc$ mkdir test
mkdir: cannot create directory ‘test’: Permission denied
graylog@5bbbf358d857:/etc$

As far as I understand this is in a default docker volume somewhere and the user should have full permissions to it?

4. How can the community help?

Please tell me how to run graylog as a specific user or what to do to rectify the issue

Helpful Posting Tips: Tips for Posting Questions that Get Answers [Hold down CTRL and link on link to open tips documents in a separate tab]

Hello && Welcome

I believe this post will explain this issue.

Hope that help

Hi @gsmith so what I understand from that post is the graylog docker implementation is effectively broken or at least built incorrectly and there is no work around? is that correct?

I have created a local user outside of docker with the same uid and gid 1100 and given it ownership of the folders it should work with that?

Hello

From my research about this subject, It was made that way. I don’t know exactly why. There are a couple more instances that some else in the community tried to do the same. The only way this could be corrected if you rebuild the Docker Container but I’m not a Docker type of guy.

Not sure you’ll have to try it out and if its work please let use know here what you did.

I’ve managed to get it working sortof

I’m letting it handle its own storage and I’ll just have to abandon knowledge of where its stored and the ability to back it up and restore if I migrate pcs (Unfortunately im pretty certain the config is stored within the docker container not in the db where it should be so backups are a bit of a failure)

I have managed to keep elasticsearch and mongodb with known folders so I can access and back them up at least so maybe ill have content if not the graylog config and setup

Graylog was not respecting my port change either so I had to manually force it by changing the outside of docker port to 9002 - "9002:9000/tcp" # Server API

New env file

GRAYLOG_PASSWORD_SECRET="a hash"
GRAYLOG_ROOT_PASSWORD_SHA2="another hash"
GRAYLOG_HTTP_EXTERNAL_URI="192.168.2.11:9002"
# The directory where data and configuration will be stored.
CONFIGROOT=/opt/config/
#User Group IDs and User ID's
LOGPUID=1000
LOGPGID=1000
# Your timezone, https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
TZ=Australia/Sydney

New compose file

version: "3.8"

services:
  mongodb:
    image: "mongo:4.2"
    environment:
      - PUID=${LOGPUID} # default user id, defined in .env
      - PGID=${LOGPGID} # default group id, defined in .env
      - TZ=${TZ} # timezone, defined in .env
    volumes:
      - /etc/localtime:/etc/localtime:ro
      - ${CONFIGROOT}/mongodb_data:/data/db
    restart: unless-stopped
    networks:
      - graylog

  elasticsearch:
    image: "docker.elastic.co/elasticsearch/elasticsearch-oss:7.10.2"
    environment:
      - PUID=${LOGPUID} # default user id, defined in .env
      - PGID=${LOGPGID} # default group id, defined in .env
      - TZ=${TZ} # timezone, defined in .env
      - http.host=0.0.0.0
      - transport.host=localhost
      - network.host=0.0.0.0
      - "ES_JAVA_OPTS=-Xms512m -Xmx512m"
    ulimits:
      memlock:
        hard: -1
        soft: -1
    mem_limit: 1g
    volumes:
      - /etc/localtime:/etc/localtime:ro
      - ${CONFIGROOT}/es_data:/usr/share/elasticsearch/data
    restart: unless-stopped
    networks:
      - graylog

  graylog:
    image: "graylog/graylog:4.2.5"
    entrypoint: "/usr/bin/tini -- wait-for-it elasticsearch:9200 --  /docker-entrypoint.sh"
    environment:
      - TZ=${TZ} # timezone, defined in .env
      - GRAYLOG_PASSWORD_SECRET=${GRAYLOG_PASSWORD_SECRET}
      - GRAYLOG_ROOT_PASSWORD_SHA2=${GRAYLOG_ROOT_PASSWORD_SHA2}
      - GRAYLOG_HTTP_EXTERNAL_URI=http://${GRAYLOG_HTTP_EXTERNAL_URI}/
      - GRAYLOG_HTTP_PUBLISH_URI=http://${GRAYLOG_HTTP_EXTERNAL_URI}/
      - GRAYLOG_MONGODB_URI=mongodb://mongodb:27017/graylog
      - GRAYLOG_ELASTICSEARCH_HOSTS=http://elasticsearch:9200
    links:
      - mongodb
      - elasticsearch
    depends_on:
      - mongodb
      - elasticsearch
    ports:
    - "5044:5044/tcp"   # Beats
    - "5140:5140/udp"   # Syslog
    - "5140:5140/tcp"   # Syslog
    - "5555:5555/tcp"   # RAW TCP
    - "5555:5555/udp"   # RAW UDP
    - "9002:9000/tcp"   # Server API
    - "12201:12201/tcp" # GELF TCP
    - "12201:12201/udp" # GELF UDP
    - "13301:13301/tcp" # Forwarder data
    - "13302:13302/tcp" # Forwarder config
    volumes:
      - /etc/localtime:/etc/localtime:ro
      - graylog_data:/usr/share/graylog/data
    restart: unless-stopped
    networks:
      - graylog

networks:
  graylog:
    driver: bridge
volumes:
  graylog_data:
    driver: local

@duindain
Nice,
I’ve been meaning to start learning about Docker stuff but I have a unlimited supply of Virtual Machine here so I don’t really bother. I need to stop being lazy and start :laughing:

They are brilliant “when created correctly”
You can set up a list of co-dependant products/containers in a docker compose file and move it to any machine on any platform and have that set of services running and working together just by a few command line calls

I have a compose file for graylog and its 2 dependencies and another for media that installs about 10 items with all the interconnections and stuff working and they don’t have to be the same OS or version of OS and they can have different versions of requirements internally (php, apache or node, .net, mono and python and hundreds more) and it all works regardless

If you need to change pcs you can copy the existing saved config across and with pulling down with the compose file you back 100% without any need to reconfigure its as if it was the same machine effectively, they are quite resource efficient too

I need to look into kubernetes and micro clusters and services soon when you have a pool of containers and it can cycle them up and down and provision more in response to load but its not something I’ve needed yet just interesting

Anyway thanks for your help @gsmith

1 Like

No problem, glad to help out when I can @duindain :+1:

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.