0

I created a Dockerfile for my website development (Jekyll in this case, but I do not think that matters much).

In case this information is helpful, I code locally using Visual Studio Code and the Remote Containers extension. This extension allows me to manage my code locally while keeping it in sync with the container.

To publish my website, I run a GitHub Action that creates a container from my Dockerfile and then runs all the build code from an entrypoint.sh file. Here is the pertinent code from my Dockerfile:

FROM ruby:alpine as jekyll

ENV env_workspace_directory=$workspace_directory

... more irrelevant code ...

RUN echo "#################################################"
RUN echo "Copy the GitHub repo to the Docker container"
RUN echo "COPY . ${env_workspace_directory}"
COPY . ${env_workspace_directory}

RUN echo "#################################################"
RUN echo "Run the entrypoint "
ENTRYPOINT ["/entrypoint.sh"]

Because I am using the Remote Containers VS Code extension, I do not want the Dockerfile to contain the COPY . ${env_workspace_directory} code. Instead, I only want that code to run when used as a GitHub Action.

So I guess I have two questions, with the first being ideal:

  1. Is it possible to write like-type code that will copy the contents of the currently open GitHub branch (or at least the main branch), including all files and subfolders into the Docker container using the entrypoint.sh file instead? If so, what would that entrypoint.sh code look like?

  2. Is it possible to leave the COPY command in the Dockerfile and make it conditional? For example "Only run the COPY command if running from a GitHub Action"?

For #1 above, I reviewed this Stack Overflow article that says you can use the docker cp command, but I am unsure if that is (a) correct and (b) how to be sure I am using the $workspace_directory.

I am very new to Dockerfiles, writing shell commands, and GitHub Actions, so apologies if this question is an easy one or if more clarifications are required.

Here is the Development repo if that is useful.

Bill
  • 582
  • 1
  • 7
  • 21
  • docker cp should work fine. $workspace_directory is a pseudo-code variable in this case. If you are using bash, $PWD would be your current working directory. If you git switched to the branch you want to be on, you can docker cp your files ```docker cp /path/to/files/fodlers/you/want/to/copy container_id_or_name:/destination/path/for/file/folder/you/want/to/copy``` I wouldn't put this in a dockerfile. Just docker cp when you bring up the container. You can also use a docker volume. Just mount the working directory to somewhere in the container. – Brandon Kauffman Sep 12 '22 at 22:59
  • Thank you. Get you help me understand what that source`/path/to/files/folders/you/want/to/copy` structure is when you are acting in a GitHub Action and wanting to get all root and sub folders and files in GitHub? – Bill Sep 13 '22 at 00:24

1 Answers1

0

A Docker volume mount happens after the image is built but before the main container process is run. So if you do something like

docker run -v "$PWD/site:/site" your-image

then the entrypoint.sh script will see the host content in the container's /site directory, even if something different had been COPYed in the Dockerfile.

There are no conditionals or flow control in Dockerfiles, beyond shell syntax within individual RUN instructions. You could in principle access a Git repository in your container process, but managing the repository location, ssh credentials, branches, uncommitted files, etc. can get complex.

Depending on how you're using the image, I could suggest two approaches here.

If you have a deploy-time action that uses this image in its entirety to build the site, then just leave your Dockerfile as-is. In development use a bind mount to inject your host content; don't especially worry about skipping the image COPY here.

Another approach is to build the image containing the Jekyll tool, but to treat the site itself as data. In that case you'd always run the image with a docker run -v or Compose volumes: option to inject the data. In the Dockerfile you might create an empty directory to be safe

RUN mkdir "${env_workspace_directory}" # consider a fixed path

and in your entrypoint script you can verify the site exists

if [ ! -f "$env_workspace_directory/_site.yml" ]; then
  cat >&2 <<EOF
There does not seem to be a Jekyll site in $env_workspace_directory.
Please re-run this container with the site mounted.
EOF
  exit 1
fi
David Maze
  • 130,717
  • 29
  • 175
  • 215