eclipse-ee4j / glassfish.docker

Official supported GlassFish docker
Eclipse Public License 2.0
5 stars 4 forks source link

touch: cannot touch 'CONTAINER_ALREADY_STARTED_PLACEHOLDER': Permission denied #15

Open aripddev opened 1 month ago

aripddev commented 1 month ago

I get the following error when using com.google.cloud.tools:jib-maven-plugin.

The error is because of this line: https://github.com/eclipse-ee4j/glassfish.docker/blob/ff801b0d307839953505b99f050bd26ab9a8096f/7.0.17/docker-entrypoint.sh#L11

I checked UID and GID, both are correct:

$ id
uid=1000(glassfish) gid=1000(glassfish) groups=1000(glassfish)

Plugin settings:

<plugin>
  <groupId>com.google.cloud.tools</groupId>
  <artifactId>jib-maven-plugin</artifactId>
  <configuration>
    <from>
      <image>ghcr.io/eclipse-ee4j/glassfish</image>
    </from>
    <to>
      <image>company/project</image>
    </to>
    <container>
      <appRoot>/opt/glassfish7/glassfish/domains/domain1/applications</appRoot>
      <creationTime>USE_CURRENT_TIMESTAMP</creationTime>
      <user>glassfish:glassfish</user>
    </container>
    <extraDirectories>
      <paths>
        <path>
          <from>target</from>
          <into>/opt/glassfish7/glassfish/domains/domain1/autodeploy</into>
          <includes>${project.artifactId}-${project.version}.war</includes>
        </path>
      </paths>
    </extraDirectories>
  </configuration>
</plugin>

Error output:

2024-09-30 20:21:34 touch: cannot touch 'CONTAINER_ALREADY_STARTED_PLACEHOLDER': Permission denied
2024-09-30 20:21:36 java.lang.RuntimeException: the domain directory is not writable.
2024-09-30 20:21:36 at com.sun.enterprise.glassfish.bootstrap.MainHelper.verifyDomainRoot(MainHelper.java:212)
2024-09-30 20:21:36 at com.sun.enterprise.glassfish.bootstrap.MainHelper.findInstanceRoot(MainHelper.java:306)
2024-09-30 20:21:36 at com.sun.enterprise.glassfish.bootstrap.GlassFishMain.main(GlassFishMain.java:83)
2024-09-30 20:21:36 at com.sun.enterprise.glassfish.bootstrap.ASMain.main(ASMain.java:31)
2024-09-30 20:21:36 Exception in thread "main" java.lang.RuntimeException: the domain directory is not writable.
2024-09-30 20:21:36 at com.sun.enterprise.glassfish.bootstrap.MainHelper.verifyDomainRoot(MainHelper.java:212)
2024-09-30 20:21:36 at com.sun.enterprise.glassfish.bootstrap.MainHelper.findInstanceRoot(MainHelper.java:306)
2024-09-30 20:21:36 at com.sun.enterprise.glassfish.bootstrap.GlassFishMain.main(GlassFishMain.java:83)
2024-09-30 20:21:36 at com.sun.enterprise.glassfish.bootstrap.ASMain.main(ASMain.java:31)
2024-09-30 20:21:36 Launching GlassFish on Felix platform
dmatej commented 1 month ago

I don't know the jib-maven-plugin, but are you sure that <user>glassfish:glassfish</user> means the same as inside the container? The stacktrace following the first error has the same meaning. The documentation of the plugin says:

The user and group to run the container as. The value can be a username or UID along with an optional groupname or GID. The following are all valid: user, uid, user:group, uid:gid, uid:group, user:gid.

I burned my fingers several times this way - there are two overlapping worlds, one inside the container, second outside. Inside we set just UID and GID and the whole infrastructure of GlassFish is created under this user. Other users don't have permissions to change files there.

I have created another reproducer for this with TestContainers:

    @SuppressWarnings({"rawtypes", "resource"})
    @Container
    private final GenericContainer server = new GenericContainer<>(System.getProperty("docker.glassfish.image"))
        .withCommand("startserv").withExposedPorts(8080)
        .withCreateContainerCmdModifier(t -> t.withUser("2000"))
        .withLogConsumer(o -> System.err.print("GF: " + o.getUtf8String()));

Then the GlassFish container uses user 1000 for directories, but I started the container as user 2000. And it ended this way:

INFO: Container glassfish:7.0.18 is starting: 950e51766823b6706f983587ee84b0db602623aa96b825716094a53dc49b71e3
GF: touch: cannot touch 'CONTAINER_ALREADY_STARTED_PLACEHOLDER': Permission denied
GF: /usr/local/bin/docker-entrypoint.sh: line 28: /opt/glassfish7/bin/startserv: Permission denied
GF: GF: říj 04, 2024 1:03:13 DOP. org.testcontainers.containers.GenericContainer tryStart
SEVERE: Could not start container

So I suppose the glassfish user on your system doesn't have the same uid as the glassfish user inside the container (which uses UID 1000 by default).

I tried yet this:

    @Container
    private final GenericContainer server = new GenericContainer<>(System.getProperty("docker.glassfish.image"))
        .withCommand("startserv").withExposedPorts(8080)
        .withCreateContainerCmdModifier(t -> t.withUser("glassfish-oh-my"))
        .withLogConsumer(o -> System.err.print("GF: " + o.getUtf8String()));

Result:

SEVERE: Could not start container
com.github.dockerjava.api.exception.InternalServerErrorException: Status 500: {"message":"unable to find user glassfish-oh-my: no matching entries in passwd file"}

Then I tried to use my own host user dmatej - with the same result. Makes sense, when I use name (not id), the same user name must be defined in both worlds, and should have also the same id, especially if we would map external directory for writing from the container.

Finally I used the value 1000, and test passed.

Where did you execute the id command? Inside the container or on your system?

aripddev commented 1 month ago

I executed the id command inside the container. On my sistem it is different.

dmatej commented 1 month ago

Can you try that with <user>1000:1000</user> for sure?

OndroMih commented 1 month ago

The problem is that the JIB plugin modifies the owner of the domain directory and applications and autodeploy directories so that they are owned by the root user: image

GlassFish the runs as the glassfish user and the directories are not writable.

This does not happen if you run a contains from the base GlassFish docker image - all the directories are owned by the glassfish user. I don't know what the <user>glassfish:glassfish</user> setting in the container element does but it doesn't set the owner of the directories.

aripddev commented 1 month ago

You are right. I tried all possibilities of user, uid, user:group, uid:gid, uid:group, user:gid and also created a new user (named glassfish, uid=1000), but it still didn't work. It should be a bug of the jib-maven-plugin.

OndroMih commented 1 month ago

You can also try using the new runnable GlassFish Embedded using the same Docker container with version 7.0.18: https://github.com/eclipse-ee4j/glassfish.docker/wiki/Example:-Using-GlassFish-Embedded-with-the-docker-Command. It doesn't modify files in the container and shouldn't have problems even if the root user owns the directories.