Docker up won't overwrite config file: Read-only file system

I’m trying to install a container containing the latest version of Ganesha NFS. I’ve written a compose file with a little help from Google’s AI, which looks like this:

version: '3.8'

services:
  nfs-ganesha:
    image: longhornio/nfs-ganesha
    container_name: nfs-server
    privileged: true
    ports:
      - "111:111"      # rpcbind
      - "2049:2049"    # nfs
    volumes:
      - /var/data/export:/export
      - /var/data/home:/home
      - /var/data/root:/root
      - /var/data/info:/info
      # Überschreiben der Standard-Konfiguration im Container:
      - ./ganesha.conf:/etc/ganesha/ganesha.conf:ro
    environment:
      - CLIENT_LIST="10.20.0.0/24,192.168.178.0/24"

I’ve also written a ganesha.conf file:

EXPORT
{
    Export_Id = 1;
    Path = /var/data/export;
    Pseudo = /export;
    Access_Type = RW;
    Squash = No_Root_Squash;
    FSAL {
        Name = VFS;
    }
    Export_Id = 2;
    Path = /var/data/home;
    Pseudo = /home;
    Access_Type = RW;
    Squash = No_Root_Squash;
    FSAL {
        Name = VFS;
    }
    Export_Id = 3;
    Path = /var/data/root;
    Pseudo = /root;
    Access_Type = RW;
    Squash = No_Root_Squash;
    FSAL {
        Name = VFS;
    }
    Export_Id = 4;
    Path = /var/data/info;
    Pseudo = /info;
    Access_Type = RO;
    Squash = Root_Squash;
    FSAL {
        Name = VFS;
    }
}

I’m using Docker 29.5.3 (API v. 1.54) on Ubuntu 24.04 LTS.

When trying to pull the image and run the container, everything looks fine:

mixtile@blade3n2:~$ sudo docker compose up -d
WARN[0000] /home/mixtile/docker-compose.yml: the attribute `version` is obsolete, it will be ignored, please remove it to avoid potential confusion 
[+] up 8/8
 ✔ Image longhornio/nfs-ganesha Pulled                                                                                                                                41.6s
 ✔ Container nfs-server         Started                                                                                                                                2.3s

…but I get an error message labeled FATAL in the log, and the container doesn’t appear in docker ps:

mixtile@blade3n2:~$ docker logs 71db6d797d55
Creating NFS disk image with size 1024MB ...
1024+0 records in
1024+0 records out
1073741824 bytes (1.1 GB, 1.0 GiB) copied, 1.20888 s, 888 MB/s
mke2fs 1.45.4 (23-Sep-2019)
Discarding device blocks: done                            
Creating filesystem with 262144 4k blocks and 65536 inodes
Filesystem UUID: 0eab5b38-b3b2-4d5c-b04a-f65748fb4aee
Superblock backups stored on blocks: 
        32768, 98304, 163840, 229376

Allocating group tables: done                            
Writing inode tables: done                            
Creating journal (8192 blocks): done
Writing superblocks and filesystem accounting information: done

Initializing Ganesha NFS server
==================================
export path: /data/nfs
==================================
* Writing configuration
/opt/start_nfs.sh: line 64: /etc/ganesha/ganesha.conf: Read-only file system

So is it impossible to replace a config file, which comes with the image, with a new one?

You made it read-only

The “ro” at the end means read-only. If you just try

- ./ganesha.conf:/etc/ganesha/ganesha.conf

then it will be writable. As long as the process do in-place edit without creating a new file replacing the old one, that should be enough. You may need to make sure the file is wrtable by the user in the container.

By the way that image is 5 years old. Are you sure you want to use it?

Haven’t found a newer one, which works on ARM64. All others I’ve tried seem to be x86_64-only.

OK, the error is now gone, but the file is still not taken by docker:

mixtile@blade3n2:~$ docker exec -it 11829b6f098c /bin/bash
bash-4.4# ls -al /etc/ganesha
total 16
drwxr-xr-x 2 root root 4096 Oct 15  2020 .
drwxr-xr-x 1 root root 4096 Jun  9 16:13 ..
-rw-rw-r-- 1 1000 1000  298 Jun  9 16:13 ganesha.conf
-rw-r--r-- 1 root root  557 Jul 13  2020 vfs.conf
bash-4.4# cat /etc/ganesha/ganesha.conf

NFSV4 { Graceless = true; }
EXPORT{
    Export_Id = 0;
    Path = "/data/nfs";
    Pseudo = "/";
    FSAL {
        name = VFS;
    }
    Access_type = RW;
    Disable_ACL = true;
    Squash = No_Root_Squash;
    Protocols = 4;
}

EXPORT_DEFAULTS{
    Transports = UDP, TCP;
    SecType = sys;
}

Even worse: I’ve just found out that docker (or NFS?) overwrite the copy of the ganesha.conf file on the host for whatever reason.

You bind mounted a file from the host to the container. The error message showed that a process wanted to edit the file. So it iis expected that now it is able to edit and change the file on the host. If you only want a base configuration without modifying anything on the host, you will need to build an image into which you copy the config file instead of bind mounting from the host.

Alternatively, you could mount the file to another location in the container, and create an entrypoint that copies the base config file and modifies that without changing the original file.

I assume it was taken, but overwritten as you noticed on the host. A bind mount is just making a file available at another location. You have a single file.

Normally I would say you should try creating a Dockerfile to create your own NFS server, but that could be difficult if you have never done that. It would take time for me too. I’m not sure why there is no more recent pre-built and trusted Docker image for that. I tried to find one for you for about an hour. But if you found the source code for any of the NFS servers, including a Dockerfile, you could still try to build it. For using it for local test projects, you can use an old image temporarily. But I would not rely on it in the long term.

Well, exactly that was what I did not wanna happen: The server should have taken my version. Instead, it overwrote it with its default one.

Yep, this is what annoys me, too: You’ve gotta inspect several search results to find the one that fits you. For me, it was quite hard to sort out the images, which supported ARM64 (there’s apparently no possibility to filter by platform).

In the meantime, I’ve found out that you can use Ceph to configure the NFS backend, too. As I’ve already got a Ceph cluster, I only had to activate NFS and then define the desired exports: CephFS & RGW Exports over NFS — Ceph Documentation So: At least for myself, I’ve found a workaround.

Usually containers can be configured through environment variables, so it was not designed for what you needed. It probbaly generated its own config based its defaults that could be overridden

There was another image I used before, but only for a blogpost to demonstrate accessing files in Docker Desktop. That is not maintained either. So last time I made a compose project for testing NFS, but it is not good enough for sharing as a maintained, trusted image. If it is useful, I can test it again and share how it can be made. Since I use a an ARM64 MacBook, at lest the image was built for arm64.

Good idea.

Most likely your /etc/ganesha is being volume-mounted, so Docker is hiding the image file and using the host version instead.

Check your run/compose for something like:


-v /host/dir:/etc/ganesha

If yes, edit the file on the host, not inside the container.

Docker itself won’t overwrite it — mounts or startup scripts are the usual cause.

Already tried that: No matter whether I edit the file on the host, or in the container shell, it always gets overwritten.