# Running crowdsec as non-root user in Docker?

**URL:** <https://discourse.crowdsec.net/t/running-crowdsec-as-non-root-user-in-docker/2021>\
**Category:** crowdsec\
**Created:** [September 18, 2024, 7:15pm UTC](https://discourse.crowdsec.net/t/running-crowdsec-as-non-root-user-in-docker/2021 "2024-09-18T19:15:18Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![verybadsoldier](https://dub1.discourse-cdn.com/flex013/user_avatar/discourse.crowdsec.net/verybadsoldier/32/988_2.png) [@verybadsoldier](https://discourse.crowdsec.net/u/verybadsoldier)\
**Post date:** [September 18, 2024, 7:15pm UTC](https://discourse.crowdsec.net/t/running-crowdsec-as-non-root-user-in-docker/2021/1 "2024-09-18T19:15:18Z")

</div>

Hi everyone,

I am new to crowdsec and I have set up crowdsec using the Docker container from here in my home lab:  
[https://hub.docker.com/r/crowdsecurity/crowdsec](https://hub.docker.com/r/crowdsecurity/crowdsec)

The container seems to running as root by default. Is it possible to run it with a non-root user? I tried it, and it worked quite well for the most part, but I get e.g. this error on every startup:

```auto
crowdsec | time="2024-09-18T21:08:17+02:00" level=error msg="unable to open GeoLite2-City.mmdb : open /var/lib/crowdsec/data/GeoLite2-City.mmdb: permission denied"
crowdsec | time="2024-09-18T21:08:17+02:00" level=warning msg="unable to initialize GeoIP: open /var/lib/crowdsec/data/GeoLite2-City.mmdb: permission denied"

```

I think the reason is that this directory and its files are only accessible by root user and root group:

```auto
f5fb83303192:/$ ls -la /staging/var/lib/crowdsec/data/
total 70504
drwxr-xr-x 3 root root 4096 Sep 12 11:39 .
drwxr-xr-x 1 root root 4096 Sep 12 11:39 ..
-rw------- 1 root root 8404553 Sep 12 11:39 GeoLite2-ASN.mmdb
-rw------- 1 root root 63771586 Sep 12 11:39 GeoLite2-City.mmdb
drwx------ 2 root root 4096 Sep 12 11:39 trace

```

This directoy is created here in the Dockerfile:

> <https://github.com/crowdsecurity/crowdsec/blob/master/Dockerfile.debian#L55>

I can change manually the permissions in the running container which seems to work, and I guess, I could also patch the Dockerfile myself to adapt the permissions.

I am surprised I could not find any information online about running crowdsec as non-root user but maybe I had bad luck when searching. Is there an official way to do this? Or is it generally not advised to do so?

Thanks in advance for help!

---

<div class="post-metadata">

**Author:** ![isdnfan](https://dub1.discourse-cdn.com/flex013/user_avatar/discourse.crowdsec.net/isdnfan/32/1074_2.png) [@isdnfan](https://discourse.crowdsec.net/u/isdnfan)\
**Post date:** [December 23, 2024, 5:17pm UTC](https://discourse.crowdsec.net/t/running-crowdsec-as-non-root-user-in-docker/2021/2 "2024-12-23T17:17:31Z")

</div>

I’m running crowdsec as cusom user:

```auto
  crowdsec:
    image: docker.io/crowdsecurity/crowdsec:${CROWDSEC_VERSION}
    container_name: crowdsec
    restart: unless-stopped
    user: "1999:1999"

```

this works in general but you need to care about all the directories and create the manually as the limited user can not create it himself (in my case)

---

<div class="post-metadata">

**Author:** ![Molt](https://avatars.discourse-cdn.com/v4/letter/m/51bf81/32.png) [@Molt](https://discourse.crowdsec.net/u/Molt)\
**Post date:** [September 15, 2025, 7:02am UTC](https://discourse.crowdsec.net/t/running-crowdsec-as-non-root-user-in-docker/2021/3 "2025-09-15T07:02:42Z")

</div>

@isdnfan, how do you cope with the contents of `/var/lib/crowdsec/data/`

```auto
crowdsec | time=“2025-09-15T07:01:01Z” level=error msg=“open /var/lib/crowdsec/data/rdns_seo_bots.txt: permission denied”
crowdsec | time=“2025-09-15T07:01:01Z” level=error msg=“open /var/lib/crowdsec/data/rdns_seo_bots.regex: permission denied”
crowdsec | time=“2025-09-15T07:01:01Z” level=error msg=“open /var/lib/crowdsec/data/ip_seo_bots.txt: permission denied”

```

---

<div class="post-metadata">

**Author:** ![isdnfan](https://dub1.discourse-cdn.com/flex013/user_avatar/discourse.crowdsec.net/isdnfan/32/1074_2.png) [@isdnfan](https://discourse.crowdsec.net/u/isdnfan)\
**Post date:** [September 15, 2025, 7:27pm UTC](https://discourse.crowdsec.net/t/running-crowdsec-as-non-root-user-in-docker/2021/4 "2025-09-15T19:27:54Z")

</div>

nothing special, you create the directory in advance, chown to right UID and mount into the container

```auto
# ls -aln ./crowdsec
drwxr-xr-x 2 1999 1999 4096 Nov 14 2024 acquis.d
drwxr-xr-x 14 1999 1999 4096 May 5 10:02 config
drwxr-xr-x 2 1999 1999 4096 Aug 31 16:30 db
-rw-r--r-- 1 1999 995 687 Feb 23 2025 _my-ip-whitelist.yml
-rw------- 1 1999 995 1651 Sep 6 22:28 _my-nextcloud-whitelist.yml

```

```auto
# compose.yml
    volumes:
      - ./crowdsec/config/:/etc/crowdsec/
      - ./crowdsec/db/:/var/lib/crowdsec/data/
      - ./crowdsec/acquis.d/:/etc/crowdsec/acquis.d/:ro
      # map whole directory to make logrotate work
      - ./log/:/var/log/traefik/:ro
      - ./crowdsec/_my-nextcloud-whitelist.yml:/etc/crowdsec/parsers/s02-enrich/my-nextcloud-whitelist.yaml:ro
      - ./crowdsec/_my-ip-whitelist.yml:/etc/crowdsec/parsers/s02-enrich/_my-ip-whitelist.yml

```

---

<div class="post-metadata">

**Author:** ![Molt](https://avatars.discourse-cdn.com/v4/letter/m/51bf81/32.png) [@Molt](https://discourse.crowdsec.net/u/Molt)\
**Post date:** [September 18, 2025, 6:46am UTC](https://discourse.crowdsec.net/t/running-crowdsec-as-non-root-user-in-docker/2021/5 "2025-09-18T06:46:32Z")

</div>

But then it’ll initially be empty, won’t it? From what I see there are some default files in it, which are symlinked then.

---

<div class="post-metadata">

**Author:** ![apommel](https://avatars.discourse-cdn.com/v4/letter/a/7c8e57/32.png) [@apommel](https://discourse.crowdsec.net/u/apommel)\
**Post date:** [April 30, 2026, 10:05pm UTC](https://discourse.crowdsec.net/t/running-crowdsec-as-non-root-user-in-docker/2021/6 "2026-04-30T22:05:53Z")

</div>

For anyone having this issue and stumbling open it, I created a custom Dockerfile to allow to run CrowdSec as a non-root user in a container:

```auto
FROM crowdsecurity/crowdsec:v[[$VERSION]]

RUN apk add --no-cache su-exec
RUN cat <<'EOF' > /entrypoint.sh
#!/bin/sh
set -eu
PUID=${PUID:-1000}
PGID=${PGID:-1000}
chown -R ${PUID}:${PGID} /etc/crowdsec /var/lib/crowdsec /staging /usr/local/lib/crowdsec/plugins
exec su-exec ${PUID}:${PGID} /bin/bash "/docker_start.sh" "$@"
EOF
RUN chmod +x /entrypoint.sh

HEALTHCHECK --interval=30s --timeout=5s --retries=3 \
  CMD wget -qO- http://localhost:6060/metrics || exit 1

ENTRYPOINT ["/entrypoint.sh"]

```

You just have to add in your compose file or your run command the PUID and PGID environment variables to set your user (don’t use the USER directive). I don’t think it does a lot security wise as the container still has to start as root to deal with file ownership, but for people like me who do not want to have files created as root in their bind mounts, this solves this problem.

It’s working well on my side, if you see any improvement to be made don’t hesitate.
