Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to update code in a docker container?

I've set up a docker django container and made its image using build using tutorial here. The tutorial shows how to make a basic django application and mounts the application to "/code", which as I understand, is contained in a data-volume.

However I want to understand that how will I be able to update and develop this code, and be able to ship/deploy it. Since when I make a commit, it's doesn't take account any changes in the code, since it's a part of the data volume.

Is there any way I can make the django code a part of the image, or update the image with the updated code?

like image 200
bilalba Avatar asked Sep 21 '16 11:09

bilalba


People also ask

Can you modify a Docker container?

Docker images can now be edited simply and reliably. This is an example of a Dockerfile for a Zabbix monitoring container. To change the image used by an existing container, we must first delete it, then edit the Docker file to make the necessary changes, and then recreate the container using the new file.

Do Docker containers automatically update?

Your containers are now set up to automatically update whenever you push a new Docker image to your image repository, or when an external maintainer updates an image you're watching.


1 Answers

In my experience Docker serves two purposes:

  1. To be able to develop code in a containerized environment. This is very useful as I am now able to get new developers on my team ready to work in about 5 mins Previously, this could have taken anywhere from an hour to several hours for misc issues, especially on older projects.
  2. To be able to package an application in a containerized environment. This is also a great time saver as the only requirement for the environment is to have Docker installed.

When you are developing your code you should mount the source/volume so that your changes are always reflected inside the container. When you want to package an app for deployment you should COPY the source into the container and package it appropriately.

Here is a docker-compose file I use to (1) build an image to develop against, (2) develop my code, and (3) ship it (I'm using spring boot):

version: '3.7' services:   dev:     image: '${MVN_BUILDER}'     container_name: '${CONTAINER_NAME}'     ports:       - '8080:8080'     volumes:       - './src:/build/src'       - './db:/build/db'       - './target:/build/target'       - './logs:/build/logs'     command: 'mvn spring-boot:run -Drun.jvmArguments="-Xmx512m" -Dmaven.test.skip=true'   deploy:     build:       context: .       dockerfile: Dockerfile-Deploy       args:         MVN_BUILDER: '${MVN_BUILDER}'     image: '${DEPLOYMENT_IMAGE}'     container_name: '${CONTAINER_NAME}'     ports:       - '8080:8080'   maven:     build:       context: .       dockerfile: Dockerfile     image: '${MVN_BUILDER}'     container_name: '${CONTAINER_NAME}' 
  1. I would run docker-compose build maven to build my base image. This is needed so that when I run my code in a container all the dependencies are installed in the image. The Dockerfile for this essentially copies to pom.xml into the image and downloads the dependencies needed for the app. Note this would need to be performed anytime dependencies change. Here is the Dockerfile to build that image that is referenced in the maven service:
### BUILD a maven builder. This will contain all mvn dependencies and act as an abstraction for all mvn goals FROM maven:3.5.4-jdk-8-alpine as builder  #Copy Custom Maven settings #COPY settings.xml /root/.m2/  # create app folder for sources RUN mkdir -p /build RUN mkdir -p /build/logs  # The WORKDIR instruction sets the working directory for any RUN, CMD, ENTRYPOINT, COPY and ADD instructions that follow it in the Dockerfile. WORKDIR /build COPY pom.xml /build #Download all required dependencies into one layer RUN mvn -B dependency:go-offline dependency:resolve-plugins RUN mvn clean install 
  1. Next, I would run docker-compose up dev to start my dev service and begin to develop my application. This service mounts my code into the container and uses Maven to start a spring boot application. Anytime I change the code spring boot restarts the server and my changes are reflected.

  2. Finally, once I am happy with my application I build an image that has my application packaged for deployment using docker-compose build deploy. I use a two-stage build process to first copy the source into a container and package it for deployment as a Jar then that Jar is put into the 2nd stage where I can simply run java -jar build/app.jar (in the container) to start my application and the first stage is removed. That's It! Now you can deploy this latest image anywhere Docker is installed.

Here is what that last Dockerfile (Dockerfile-Deploy) looks like:

ARG MVN_BUILDER ### Stage 1 - BUILD image FROM $MVN_BUILDER as builder COPY src /build/src RUN mvn clean package -PLOCAL  ### Stage 2 - Deploy Jar FROM openjdk:8 RUN mkdir -p /build COPY --from=builder /build/target/*.jar /build/app.jar EXPOSE 8080   ENTRYPOINT ["java","-jar","build/app.jar"]  

Here the .env file in the same directory as the docker-compose file. I use it to abstract image/container names and simply bump up the version number in one place when a new image is needed.

MVN_BUILDER=some/maven/builder:0.1 DEPLOYMENT_IMAGE=some/deployment/spring:0.1 CONTAINER_NAME=spring-container CONTAINER_NAME_DEBUG=spring-container-debug 
like image 98
Phil Ninan Avatar answered Oct 08 '22 10:10

Phil Ninan