SOLVED: Need a Little Dockerfile Help


Recommended Posts

Hi Guys,

 

I am perhaps a little rusty, or things have changed in the Docker landscape.

 

I am creating a container for CloudCommander. I have taken the original CC repo and made some slight improvements. I revamped the UI and added folder shortcut buttons that are somewhat user editable. NOT a great solution, but it somewhat does the job. I have been able to successfully build and push the new container into Docker Hub.

 

I have also create the unRAID temple .xml. But I have one thing I cannot resolve. In my Docker file, I create a folder called /config. I copy certain things to this folder - files that can be user configured. This is the folder that I want to map to /mnt/cache/appdata/cloudcmd. But it's not working.

 

When I build the docker, and I run the container in Docker Desktop, I am able to go into the /config folder, I see all the copied files. So I push the docker.

 

When I run the template in unRAID, I pick a new folder in /appdata, the container installs and all looks good. HOWEVER, the /appdata folder  and the /config folder do NOT have the copied files.

 

What am I missing? I am pasting my Dockerfile and the unRAID template... any help is greatly appreciated.

 

Dockerfile:

FROM node:lts-buster-slim
LABEL maintainer="Coderaiser"

RUN mkdir -p /usr/src/app

WORKDIR /usr/src/app

COPY package.json /usr/src/app/

RUN npm root set package-lock false && \
    npm install --production && \
    apt update && \
    apt install -y make bash nano mc g++ python3 && \
    npm i gritty && \
    npm cache clean --force && \
    apt remove -y make g++ python3 && \
    rm -rf /usr/include /tmp/* /var/cache/apt/*

COPY . /usr/src/app


VOLUME ["/config"]

RUN mkdir -p /config

COPY cloudcmd.css /usr/src/app/dist/


WORKDIR /

ENV cloudcmd_terminal true
ENV cloudcmd_terminal_path gritty
ENV cloudcmd_open false

EXPOSE 8000


ENTRYPOINT ["/usr/src/app/bin/cloudcmd.mjs"]


RUN cp -n /usr/src/app/cloudcmd.css /config/cloudcmd.css
RUN cp -n /usr/src/app/dist/index.html /config/index.html

RUN cp /usr/src/app/banner.png /config/banner.png
RUN cp /usr/src/app/favicon.ico /config/favicon.ico

RUN cp /config/cloudcmd.css /usr/src/app/dist/cloudcmd.css
RUN cp /config/index.html /usr/src/app/dist/index.html 

 

 

and here is the Template.xml:

 

<?xml version="1.0"?>
<Container version="2">
  <Name>CloudCommander</Name>
  <Repository>hernandito/cloudcommander</Repository>   
  <Registry>https://hub.docker.com/r/coderaiser/cloudcmd/</Registry>
  <Network>bridge</Network>
  <MyIP/>
  <Shell>sh</Shell>
  <Privileged>false</Privileged>
  <Support></Support>
  <Project/>
  <Overview>
	CloudCommander Hernandito is a simple web file browser with ....
  </Overview>
  <Category>Tools:</Category>
  <WebUI>http://[IP]:[PORT:8000]</WebUI>
  <TemplateURL>https://raw.githubusercontent.com/hernandito/Hernandito-Templates/main/unRAID-Templates/CloudCommander-HR.xml</TemplateURL>
  <Icon>https://i.imgur.com/Ng2rkTL.png</Icon>
  <ExtraParams/>
  <PostArgs/>
  <CPUset/>
  <DateInstalled>1641245969</DateInstalled>
  <DonateText/>
  <DonateLink/>
  <Description>&#xD;
	CloudCommander is a simple web file browser with a built in text editor and archive compress/extract 
  </Description>
  <Networking>
    <Mode>br0</Mode>
    <Publish/>
  </Networking>
  <Data>
    <Volume>
      <HostDir>/</HostDir>
      <ContainerDir>/UNRAID</ContainerDir>
      <Mode>rw</Mode>
    </Volume>
    <Volume>
      <HostDir>/mnt/cache/appdata/cloudcmd2</HostDir>
      <ContainerDir>/config</ContainerDir>
      <Mode>rw</Mode>
    </Volume>
  </Data>


  <Labels/>
    <Config Name="PUID" Target="PUID" Default="99" Mode="" Description="Container Variable: PUID" Type="Variable" Display="always" Required="false" Mask="false">99</Config>
	<Config Name="PGID" Target="PGID" Default="100" Mode="" Description="Container Variable: PGID" Type="Variable" Display="always" Required="false" Mask="false">100</Config>

	
	<Config Name="Config" Target="/config" Default="/mnt/cache/appdata/cloudcmd" Mode="rw" Description="Container Path: /config" Type="Path" Display="always" Required="true" Mask="false">/mnt/cache/appdata/cloudcmd</Config>
	<Config Name="Mount Path" Target="/UNRAID" Default="/" Mode="rw" Description="Container Path: /UNRAID" Type="Path" Display="always" Required="true" Mask="false">/</Config>
	<Config Name="HOME - Dont Change!" Target="HOME" Default="" Mode="" Description="Container Variable: HOME" Type="Variable" Display="always" Required="true" Mask="false">/root</Config>	
	<Config Name="Port" Target="8000" Default="8000" Mode="tcp" Description="Container Port: 8000" Type="Port" Display="always" Required="true" Mask="false">8000</Config>


	
</Container>

 

Here is some eye candy....

 

image.thumb.png.c28744db5c6ed363a7e160ae24f10f7c.png

 

 

Thank you!!

 

H.

 

 

Edited by hernandito
Mark solved
Link to comment
3 hours ago, tjb_altf4 said:

You'll need to copy those files at run time (i.e. cmd / entrypoint script), not at build time when the external folder isn't mounted.

Once you get that working, you'll also need to check the files exist before copying or you'll overwrite the files each time you start the container.

 

 

I strongly suspect this is the issue. I did add all the copy commands after the ENTRYPOINT line... but I cannot figure out why it does not work. I also tried COPY but again without luck.

Link to comment
3 hours ago, hernandito said:

I strongly suspect this is the issue. I did add all the copy commands after the ENTRYPOINT line... but I cannot figure out why it does not work. I also tried COPY but again without luck.

The trick is the entire dockerfile is build time, so you'll need to move that copy logic into the entrypoint (or cmd), which is called later at run time.

As you have an existing entrypoint used to start the application, you might have to do some testing to see what works best for you.

 

This is what one of my dockers looks like, copying the .sh from the build folder

COPY docker-entrypoint.sh /usr/local/bin/
ENTRYPOINT ["docker-entrypoint.sh"]

 

You could create your own docker-entrypoint.sh to manage those copy steps (don't forget to chmod +x the file).

I've added the old entrypoint command here at the end of the docker-entrypoint.sh... this "should" work, but you might need to do some further research and experimentation beyond this.

#!/usr/bin/env bash

# copy logic... you should put file detection here so as not to overwrite files on each startup
cp -n /usr/src/app/cloudcmd.css /config/cloudcmd.css
cp -n /usr/src/app/dist/index.html /config/index.html
cp /usr/src/app/banner.png /config/banner.png
cp /usr/src/app/favicon.ico /config/favicon.ico
cp /config/cloudcmd.css /usr/src/app/dist/cloudcmd.css
cp /config/index.html /usr/src/app/dist/index.html

# start cloudcmd
/usr/src/app/bin/cloudcmd.mjs

exec "$@"

 

Edited by tjb_altf4
  • Like 1
Link to comment
3 hours ago, hernandito said:

I did add all the copy commands after the ENTRYPOINT line... but I cannot figure out why it does not work.

Exactly as @tjb_altf4 wrote above...

 

If you want to have files in a directory that is mapped to a directory on the host, you have to do a initial copy script that is not located in the Dockerfile because if you do a mapping of a directory from the host to a container like you do in this instance for the /config directory the files from the container in this directory will be overridden by the directory from the host.

So to speak if the directory on the host is empty it will be also empty in the container, you can try this by removing the mapping from your template and you will have files in the /config directory (inside the container) but the changes are not persistent between container updates because the files in the /config directory are now only just a simple Docker layer that will be overwritten by a container update/rebuild.

 

Also as @tjb_altf4 said, don't forget to change permissions on them and also don't forget to put a check in your copy script that checks if the files are already exist in the /config directory to not overwrite the files when they already exist.

Link to comment
4 hours ago, tjb_altf4 said:

The trick is the entire dockerfile is build time, so you'll need to move that copy logic into the entrypoint (or cmd), which is called later at run time.

As you have an existing entrypoint used to start the application, you might have to do some testing to see what works best for you.

 

This is what one of my dockers looks like, copying the .sh from the build folder

COPY docker-entrypoint.sh /usr/local/bin/
ENTRYPOINT ["docker-entrypoint.sh"]

 

You could create your own docker-entrypoint.sh to manage those copy steps (don't forget to chmod +x the file).

I've added the old entrypoint command here at the end of the docker-entrypoint.sh... this "should" work, but you might need to do some further research and experimentation beyond this.

#!/usr/bin/env bash

# copy logic... you should put file detection here so as not to overwrite files on each startup
cp -n /usr/src/app/cloudcmd.css /config/cloudcmd.css
cp -n /usr/src/app/dist/index.html /config/index.html
cp /usr/src/app/banner.png /config/banner.png
cp /usr/src/app/favicon.ico /config/favicon.ico
cp /config/cloudcmd.css /usr/src/app/dist/cloudcmd.css
cp /config/index.html /usr/src/app/dist/index.html

# start cloudcmd
/usr/src/app/bin/cloudcmd.mjs

exec "$@"

 

 

 

Thank you guys... it worked!

 

Here is what I ended up adding...

 

COPY docker-entrypoint.sh /usr/local/bin/

RUN chmod +u /usr/local/bin/docker-entrypoint.sh

ENTRYPOINT ["sh","/usr/local/bin/docker-entrypoint.sh"]

 

I have added the template for this docker in my repo. It should show up soon on CA.

 

Thanks again!

 

H.

 

Link to comment
  • hernandito changed the title to SOLVED: Need a Little Dockerfile Help

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.