Home > OS >  How to change a container's source code and generate a new image from it?
How to change a container's source code and generate a new image from it?

Time:09-30

I have deployed this using Kubernetes:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: voting-app-deploy
  labels:
    name: voting-app-deploy
    app: demo-voting-app
spec:
  replicas: 1
  selector:
    matchLabels:
      name: voting-app-pod
      app: demo-voting-app
    
  template:
    metadata:
      name: voting-app-pod
      labels:
        name: voting-app-pod
        app: demo-voting-app
    spec:
      containers:
        - name: voting-app
          image: kodekloud/examplevotingapp_vote:v1
          ports:
            - containerPort: 80

With this Service:

apiVersion: v1
kind: Service
metadata:
  name: voting-service
  labels:
    name: voting-service
    app: demo-voting-app
spec:
  type: NodePort
  ports:
    - port: 80
      targetPort: 80
      nodePort: 30004
  selector:
    name: voting-app-pod
    app: demo-voting-app

After checking if the Pods are running, I get a shell to the running container where I can see the source code and make changes using vi:

kubectl exec -it podsname -- sh

The problem is whenever I destroy the deployment and bring it back I lose all my changes in the source code.

This is the application's Dockerfile, which I got from within the running container:

# Using official python runtime base image
FROM python:2.7-alpine

# Set the application directory
WORKDIR /app

# Install our requirements.txt
ADD requirements.txt /app/requirements.txt
RUN pip install -r requirements.txt

# Copy our code from the current folder to /app inside the container
ADD . /app

# Make port 80 available for links and/or publish
EXPOSE 80

# Define our command to be run when launching the container
CMD ["gunicorn", "app:app", "-b", "0.0.0.0:80", "--log-file", "-", "--access-logfile", "-", "--workers", "4", "--keep-alive", "0"]

So, how can I get this source code and generate a new image?

CodePudding user response:

You should use volumes.

Volumes will allow you to map the src code folder in the container to a path outside of your container and it will not be destroyed during restart since it will be store outside of your container.

You can see a working sample with explanation here: enter image description here


emptyDir

emptyDir is the default volume and it's being deleted when the pod is deleted, but I'm using it here to show you a sample on how to use volumes.

apiVersion: v1
kind: Pod
metadata:
  name: test-pd
spec:
  containers:
  - image: k8s.gcr.io/test-webserver
    name: test-container
    volumeMounts:
    - mountPath: /cache
      name: cache-volume
  volumes:
  - name: cache-volume
    emptyDir: {}

CodePudding user response:

Quick and dirty

If you change your code often and this isn't a production environment you can use the --reload that's according to this thread is available since gunicorn 19.0. this option makes the server reload your code changes into new workers.

Then when you want to save your new image you can use docker commit to "commit" or save your changes to a new image like so:

docker commit running_container_name_or_id imagerepo/image-name:tag

Though this isn't that recommended in the long run just for small fixes and checks.

Long term preferred usage If you want a long term method method either develop locally with a mounted bind-mount (map a folder from the host machine to the docker container) and build a final image for kubernetes, or you could mount your source code using a config map like in this example:

apiVersion: v1
kind: ConfigMap
metadata:
  name: file-configmap
  namespace: default
data:
  config.conf: |
    [mysqld]
    binlog-format=mixed

Pod (usage in deployment is the same):

apiVersion: v1
kind: Pod
metadata:
  name: 
spec:
  containers:
    - name: container-name
      image: image-name
      volumeMounts:
      - name: my-file-volume
        mountPath: /path/in/container/config.conf
        subPath: config.conf
  volumes:
    - name: my-file-volume
      configMap:
        name: file-configmap

CodePudding user response:

In you container(kubectl exec), use ps | grep gunicorn find the process of your application. Killed it then start it again.

  • Related