How to write files from Docker image to EFS?

2k Views Asked by At

Composition

  • Jenkins server on EC2 instance, uses EFS
  • Docker image for above Jenkins server

Need

  • Write templates to directory on EFS each time ECS starts the task which builds the Jenkins server

Where is the appropriate place to put a step to do the write?

Tried

If I do it in the Dockerfile, it writes to the Docker image, but never propagates the changes to EFS so that the templates are available as projects on the Jenkins server.

I've tried putting the write command in jenkins.sh but I can't figure out how that is run, anyway it doesn't place the templates where I need them.

2

There are 2 best solutions below

0
On

You need to start the task with a volume, then mount that volume into the container. This way you have persistent storage across multiple Jenkins start/stop cycles.

Your task definition would look something like the below (I've removed the non relevant parts). The important components are mountPoints and volumes. Not that this is not the same as volumesFrom as you aren't mounting volumes from another container, but rather running them in a single task.

This also assumes you're running Jenkins in the default JENKINS_HOME directory as well as having mounted your EFS drive to /mnt/efs/jenkins-home on the EC2 instance.

{
  "requiresAttributes": ...
  "taskDefinitionArn": ... your ARN ...,
  "containerDefinitions": [
    {
      "portMappings": ...
      .... more config here .....   
      "mountPoints": [
        {
          "containerPath": "/var/jenkins_home",
          "sourceVolume": "jenkins-home",
        }
      ]
    }
  ],
  "volumes": [
    {
      "host": {
        "sourcePath": "/mnt/efs/jenkins-home"
      },
      "name": "jenkins-home"
    }
  ],
  "family": "jenkins"
}

Task definition within ECS:

ECS Task Definition for Jenkins task

0
On

The original question included:

Write templates to directory on EFS each time ECS starts the task

In addition to @luke-peterson's answer you can use the shell script as an entry point in your docker file, in order to copy files between the mounted EFS folder and the container.

Instead of ENTRYPOINT, use following directive in your dockerfile:

CMD ["sh", "/app/startup.sh"]

And inside startup.sh you can copy files freely and run the app (.net core app in my example):

cp -R /app/wwwroot/. /var/jenkins-home 
dotnet /app/app.dll

Of course, you can also do it programmatically insede the app itself.