A Java developer using testcontainers with Oracle XE is trying to copy an SQL initialization script into the container using .withCopyFileToContainer() and copyFileToContainer(). Despite the container starting successfully and no errors being logged, the file never appears inside the container. They also attempted manual container lifecycle management and tried both classpath and absolute host paths. Additionally, they want to know about container reuse and logging configuration. The developer is unsure why the file copy isn’t working and seeks guidance on proper usage of file copy into a running Testcontainer.
I’ve definitely run into this issue before, and it took me some time to figure it out. The main thing to keep in mind when working with withCopyFileToContainer is that it must be called before starting the container. This is because it registers the file copy operation as part of the container’s initialization process. If you try to call withCopyFileToContainer after start(), the file won’t be copied. It just won’t work.
For example, you should do something like this:
OracleContainer oracle = new OracleContainer("gvenzl/oracle-xe:18-slim")
.withCopyFileToContainer(MountableFile.forClasspathResource("init.sql"), "/docker-entrypoint-initdb.d/init.sql");
oracle.start();
This way, the file will be copied automatically when the container starts. Just make sure that your file is either on the classpath or use MountableFile.forHostPath() if you’re working with an absolute path. The file copy happens during the startup, so you won’t see any issues if it’s set up correctly.
Ah, I ran into the exact same behavior. The trick is, like Yanisleidi mentioned, calling copyFileToContainer after the container has already started doesn’t do anything unless you manually exec into the container. This is why pre-registering the file copy with withCopyFileToContainer is considered the best practice in Testcontainers, it ensures everything is in place before the container starts.
And for logging—this is something that helped me a lot, I recommend adding withLogConsumer(new Slf4jLogConsumer(LOGGER)). This way, you can monitor the container’s output directly and easily troubleshoot any issues related to the initialization script, including seeing if the file copy actually happened.
Definitely! On top of what Yanisleidi and Richaa mentioned, if you plan on reusing containers (which is common for efficiency), you can enable container reuse by adding this line to your configuration:
TestcontainersConfiguration.getInstance().updateUserConfig("testcontainers.reuse.enable", "true");
However, just a heads-up, if you’re reusing containers, withCopyFileToContainer won’t re-copy the files on subsequent runs. This is why any SQL initialization scripts you use should be idempotent, meaning they can run multiple times without causing issues.
If you still need to copy files dynamically at runtime, Testcontainers does allow for that using:
oracle.copyFileToContainer(MountableFile.forClasspathResource("init.sql"), "/tmp/init.sql");
But be careful—make sure your container is in the correct state and that you manually execute any scripts after copying. This approach works for specific cases, but if you want to stick to the withCopyFileToContainer method, starting the container with that registration remains the cleaner approach.