Copy a file from local to docker container via a shell script

Viewed 808

I have the following folder structure

db

 - build.sh
 - Dockerfile
 - file.txt

build.sh

PGUID=$(id -u postgres)
PGGID=$(id -g postgres)
CS=$(lsb_release -cs)

docker build --build-arg POSTGRES_UID=${PGUID} --build-arg POSTGRES_GID=${PGGID} --build-arg LSB_CS=${CS} -t postgres:1.0 .

docker run -d postgres:1.0 sh -c "cp file.txt ./file.txt"

Dockerfile

FROM ubuntu:19.10
RUN apt-get update
ARG LSB_CS=$LSB_CS
RUN echo "lsb_release: ${LSB_CS}"
RUN apt-get install -y sudo \
  && sudo sh -c 'echo "deb http://apt.postgresql.org/pub/repos/apt eoan-pgdg main" > /etc/apt/sources.list.d/pgdg.list'
RUN  apt-get install -y wget \
  && apt-get install -y gnupg \
  && wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | \
  sudo apt-key add -
RUN apt-get update
RUN apt-get install tzdata -y
ARG POSTGRES_GID=128
RUN groupadd -g $POSTGRES_GID postgres
ARG POSTGRES_UID=122
RUN useradd -r -g postgres -u $POSTGRES_UID postgres
RUN apt-get update && apt-get install -y postgresql-10
RUN locale-gen en_US.UTF-8
RUN echo "host all  all    0.0.0.0/0  md5" >> /etc/postgresql/10/main/pg_hba.conf
RUN echo "listen_addresses='*'" >> /etc/postgresql/10/main/postgresql.conf

EXPOSE 5432

CMD ["pg_ctlcluster", "--foreground", "10", "main", "start"]

file.txt

"Hello Hello"

Basically i want to be able to build my image, start my container and copy file.txt in my local to the docker container.

I tried doing it like this docker run -d postgres:1.0 sh -c "cp file.txt ./file.txt" but it doesn't work. I have also tried other options as well but also not working.

At the moment when i run my script sh build.sh, it runs everything and even starts a container but doesn't copy over that file to the container.

Any help on this is appreciated

1 Answers

Sounds like what you want is a mounting the file into a location of your docker container.

You can mount a local directory into your container and access it from the inside:

mkdir /some/dirname
copy filet.txt /some/dirname/

# run as demon, mount /some/dirname to  /directory/in/container, run sh
docker run -d -v /some/dirname:/directory/in/container postgres:1.0 sh

Minimal working example:

On windows host:

d:\>mkdir d:\temp
d:\>mkdir d:\temp\docker
d:\>mkdir d:\temp\docker\dir
d:\>echo "SomeDataInFile" > d:\temp\docker\dir\file.txt

# mount one local file to root in docker container, renaming it in the process
d:\>docker run -it -v d:\temp\docker\dir\file.txt:/other_file.txt  alpine

In docker container:

/ # ls
bin       etc       lib      mnt     other_file.txt  root    sbin      sys       usr
dev       home      media    opt     proc            run     srv       tmp       var

/ # cat other_file.txt
"SomeDataInFile"
/ # echo 32 >> other_file.txt
/ # cat other_file.txt
"SomeDataInFile"
32
/ # exit

this will mount the (outside) directory/file as folder/file inside your container. If you specify a directory/file inside your docker that already exists it will be shadowed.

Back on windows host:

d:\>more d:\temp\docker\dir\file.txt
"SomeDataInFile"
32

See f.e Docker volumes vs mount bind - Use cases on Serverfault for more info about ways to bind mount or use volumes.

Related