I am learning Docker and would appreciate some wisdom.
My current assumption of Docker is that the Dockerfile and resulting Image build from it only store the actual environment itself. And not the application files/server. We utilize Volumes to store and run application code in a container. In a production Docker example that needs to be mounted on the fly. How does one use application code (because it's not stored in the Image... right?) in the Image itself.
When I use my Docker Image in development I start a container with a mounted volume of my local working directory. Here's my command to do that.
docker run -v $(pwd):/app image_name
1. Do I pull from GitHub in the actual Dockerfile to add and use the application code in the container?
2. Is there a way to store the application code on the Docker Image itself?
For example, this is my very simple Dockerfile:
FROM ruby:3.1.1-alpine3.15
RUN apk update -q
RUN apk add bash yarn git build-base nodejs mariadb-dev tzdata
ENV RAILS_ENV production
WORKDIR /app
COPY Gemfile /app/Gemfile
COPY Gemfile.lock /app/Gemfile.lock
COPY package.json /app/package.json
COPY yarn.lock /app/yarn.lock
RUN gem install bundler
RUN gem update bundler
RUN bundle install
COPY entrypoint.sh /usr/bin
RUN chmod +x /usr/bin/entrypoint.sh
ENTRYPOINT ["entrypoint.sh"]
EXPOSE 3000
CMD ["rails", "server", "-b", "0.0.0.0"]
Thank you in advance, any advice would be greatly appreciated.
EDIT 05/16/22
Thank you to Joe and David Maze for clarifying how building Docker Images work.
This is my revised Dockerfile which includes my application code in the Docker Image once it is built. Utilizing COPY . .
FROM ruby:3.1.1-alpine3.15
RUN apk update -q
RUN apk add bash yarn git build-base nodejs mariadb-dev tzdata
ENV RAILS_ENV production
WORKDIR /app
COPY Gemfile /app/Gemfile
COPY Gemfile.lock /app/Gemfile.lock
COPY package.json /app/package.json
COPY yarn.lock /app/yarn.lock
RUN gem install bundler
RUN gem update bundler
RUN bundle install
COPY . .
COPY entrypoint.sh /usr/bin
RUN chmod +x /usr/bin/entrypoint.sh
ENTRYPOINT ["entrypoint.sh"]
EXPOSE 3000
CMD ["rails", "server", "-b", "0.0.0.0"]
I still use
COPY Gemfile /app/Gemfile
COPY Gemfile.lock /app/Gemfile.lock
COPY package.json /app/package.json
COPY yarn.lock /app/yarn.lock
According to David Maze's answer on this Stackoverflow post. Because bundling and installing dependencies takes a long time. In the future when I change my application code but my dependencies haven't changed, Docker can detect that they haven't changed and reuse previous Image layers, also skipping my RUN bundle install
step. Making Image build time faster.
This revised Dockerfile allows me to start a Docker Container from an Image with my application code already with this command.
docker run image_name
I can also start the Rails server in development environment by overriding the Dockerfile's environment variables.
docker run -e RAILS_ENV=development image_name
Thanks again!