So now we deployed multiple containers
but still there are a couple of areas
where we can improve our setup.
Now let me start by adding a new goal again,
so that we have one goal stored there,
and then let me show you one first issue we might have.
Let's say we change something in our goal,
and if it's just an extra character in a log message,
and therefore, we of course rebuild our image
with the Docker build command.
Thereafter I use the tag command to also
take these latest changes into my repository image
so to say.
And then we push this updated image, to Docker hub.
That's something we will most likely do at some point,
when we are working on a project.
We change something in code
and we wanna deploy these latest changes.
Now I already showed you how you can pick up these changes.
All you need to do in the end is go to yours service,
click update there, click force new deployment,
and then skip to review,
with all the default settings we used before,
and click update service.
And this updates to service, restarts it,
and restarts the tasks in there.
Based on the updated container images.
That's why in your cluster, on your service,
you'll temporarily see two tasks.
The old one keeps on running until the new one
is successfully deployed and up and running,
after which the old one will offer some time
shut down and be removed automatically.
And this new one,
is the new service based on the updated containers.
So let's wait for this start up to finish,
so that this new service, with the new tasks,
based on the updated containers is done and is running.
Let's wait for that to finish.
And once it is up and running,
let's wait until the auburn
the old service shuts down.
Which it will eventually do,
now that the new service
with the new containers is up and running.
It can take a couple of minutes for that old service
to shut down though.
So let's wait for that.
So now, after a couple of minutes, this old task was stopped
and now keep in mind
that previously we had one goal in our database.
Now I'll send the same, GET request
to the same domain, to the same URL and click send.
And you see it works.
We get back some goals, it's not crashing
but the goal we stored in the database before is lost.
And that of course happens,
because our database is running in a container.
And as long as a task is up and running,
data indeed will be persistent.
But if a task is shut down and restarted,
which is what happens when you update a service
for example, because you want to use a new container image,
then all the data is lost.
And that of course is something we saw locally already.
If you stop a container and then you remove it,
either with the rm command,
or because the container was started with the --rm flac.
Then all the data stored into container is lost.
And the same thing is happening here.
Now, locally dissolution wants to use a volume
and we can do the same year on ECS.
For that let's go to task definitions,
and click on goals, and then pick the latest
task definition which you find there.
You might only have one.
I created a couple of definitions off screen,
pick the top most one
and click create new revision to create a new configuration
based on the previous one.
Now in here, you can leave all the settings
which you currently have,
but if we scroll down to volumes,
we now wanna add a volume.
Now you can give this volume any name of your choice.
Al name it data also because this was the name I used
in my Docker compose file before,
though you don't have to use the same name.
This is totally detached.
Still I will go for data, and pick EFS.
EFS stands for elastic file system.
And it's a number service offered by AWS,
which allows us to attach a file system
to our server less executed containers.
And since we're using FARGET they are being executed
without servers managed by us.
EFS, Stanford will allow us to still attach hard drives.
You could say QD containers.
which will survive even if these containers are redeployed.
Now, initially here we have no file system,
which we could attach.
Therefore, we should go to the Amazon EFS console here
to create a new file system.
On this page, you should see something like this
and you can simply click create file system there.
Now you can give this file system,
any name of your choice and I'll name it, db storage.
But again, this name is up to you
and then you need to add a virtual private cloud.
And here, you should use the same vpc
you used for ECS before.
Now don't click create yet though, instead click customize.
And now here we need to customize one specific setting.
You can confirm this first page and move on to the next one.
But here on network access,
here we need to change something.
We should have to mount targets here.
If you don't add them, and add these subnets,
which you have in that vpc we chose.
But then here under security groups,
we need to change something.
For that, go to the ECT service page, in a new browser tab.
So did you keep that EFS tab open as well.
And there go to security groups
and create a new security group.
You can give this any name you want.
Al name it efs-sc for elastic file system security group.
Added to this vpc, which you also use for your file system
and for ECS, and then add an inbound rule.
And there you wanna choose, NFS from the dropdown
and here in the source,
choose that auburn, that goals security group
which you are using for managing your containers.
This setup will allow the containers
which run in this security group,
to then talk to anything running in this
to be created security group on port 2049.
And it turns out
that this is a port used by the elastic file system.
That's why we're creating this new security group,
for this elastic file system service,
and for the file system we're generating there.
So click create security group thereafter,
and give it a description ,
like this, then click create.
And once this is created, go back to the EFS wizard
and choose this new security group.
You might not see it there,
simply go back and click next again then.
And now you should be able to pick this,
and use that instead of the default one.
This security group.
With that click next,
confirm this screen and click next, and click create.
And this now creates this file system.
Now back in the ECS console now,
we can now click this refresh button here,
and now select this newly created file system,
which we just generate that there.
We could set an access point,
which basically would allow us to target some nested path
inside of the file system.
You can check out the docs for more information on that.
I will not do that.
I will use the entire file system as my volume here,
but if you had multiple volumes
and you don't want to create multiple files systems.
You could work with access points
to have different nested folders on that single file system
for the different volumes.
But for this one volume, I'll go with this approach
and click add.
Now we defined the volume.
It's a little bit as the finding the volume here
at the end of the Docker compose file.
It's not everything we wanna do.
We now also wanna connect it to our container.
So I'll go to the mongodb container now,
and simply click on the name to open up this confliq
and keep the configuration we used in the past,
but go down to storage and logging.
And here on mount points, you wanna select this data volume,
we just add it and bind it to the data/ db path
inside of the container.
And that's the same path I used here
in my Docker compose file.
We need to use this path because inside of the container
it is that path mongodb will write to.
Click update thereafter.
And once you did all of that,
you can click create to create this new task revision.
Then go to actions, update service,
to force redeployment of your service,
with this new revision.
And you're almost good to go.
I'm saying almost because here on platform version
at least at the point of time, I'm recording this.
You should pick version 1.4
because the strange thing at the moment is,
that latest is not really the latest version.
1.4 is, yeah that is strange.
It will change in the future.
And therefore when you're viewing this latest might work.
But if you try latest
and running this service fails thereafter,
choose 1.4.
Which is a version, which supports EFS volumes.
So for me, I choose 1.4.
Four, it's a new deployment,
click skip to revenue and click update service.
And now this service restarts or to tasks and containers
into service restart to be precise.
And once they are restarted
and one stays task, is the only running task,
we should be able to use our application again.
But now with a database where data persists.
So let's wait for this new task to be up and running.
And to be the only up and running task.
And once that is the case, we can continue.
Now, one stead all did finish starting up.
We can go back to postman
and send the request to our load balancing domain.
Now, of course, we're not able to fetch any goals
but we also don't get an error.
We just don't have any goals in that database.
but now it's for the last time that we don't have any goals.
If we save a new goal now
by sending this post request, we can of course get it.
But now this will all be stored on,
the elastic file system hard drive and therefore now,
even if we restart everything
and deploy brand new containers,
as long as we keep that volume,
our data will still be there.
And of course, we can verify this.
If we go to the goals app here and they are to our service
if we click on update here, we can restart this service,
and I wanna restart it on the same revision,
as before, but I want to force a new deployment,
and this will ensure that everything gets recreated
and dead normally would lead to our data being lost.
So here I'll skip to review and click update service,
and then we can view the service.
Now, again, it will take a couple of minutes now
until all the previous tasks have stopped.
And we only got that most recent task up and running,
but eventually that will be the case.
And when it is the case,
we should still be able to send GET request.
GET requests and get this first test goal here which I added
because it's not just stored on the container
or does temporary storage,
but instead it will be stored on the elastic file system
and that file system.
And the date on there will not be deleted
when we restart our tasks and containers.
So now here, I got this new deployment coming up
and to task being provisioned.
And as I mentioned, it will take a couple of minutes
until this will be the only running task.
And I'll be back one status the case.
And after a while, what you will notice
is that actually our new deployment,
doesn't really start up.
Instead after a while, you'll have a bunch of stopped tasks
and we can see the reason for why does it stop.
If we go into one of the stop tasks, have a look at the logs
and they're the mongodb container logs.
And the error or the problem is something
we can see here in one of the outputs here,.
Unable to lock the lock file.
Data db mongod lock resource temporarily unavailable
and never mongod the instances already running on
data db directory.
The problem is that we're using rolling deployments
which means a new task is started,
whilst the previous one is still running.
And only if the new task started successfully,
and is up and running in a healthy mode,
the previous task will be stopped.
This is a good strategy,
but here it means that it will have two tasks
with two mongodb containers
one container each.
Which are trying to interact with one,
and the same file system, at the same time.
And that causes an error here
because two databases,
try to write to the same file in the same folder,
at the same time.
Now this is a pretty niche scenario though
because we only have two tasks running at the same time,
when we try to deploy a new task, right.
Once it is deployed there only is one task
and we'll never have that problem.
So therefore it also means that both the currently running
and d to be deployed to task,
are trying to write to the exact same file,
in the same folder on EFS, at the same time.
And that won't happen for anything else you're doing
in your application.
If you have something where you try to write a file
to the disc,
when a user sends a request.
That only will happen for the currently running task,
not for the one which is currently to be deployed.
And besides that, you might write to a different file
for every request that's coming in.
So you wouldn't write to the same file twice.
It's really special to this database scenario.
Where both d currently running and to be deployed task rides
to the exact same file in the exact same folder,
on EFS.
And therefore, we could look for some work around,
and we might be able to find .
But actually I will replace the mongodb container
with a different solution anyways.
Therefore I'll not bother solving this niche problem
but instead, I will for now just manually remove
and stop the currently running task so that the
two be deployed task has a chance of becoming active.
Hence we can now wait a second,
until this new task is successfully up and running.
Once this is up and running,
let's try fetching the goals again.
And now you will see that one goal,
which we posted earlier is still there.
And it is still there because now the database files,
get stored on a physical hard drive,
which is detached from the containers.
Put in other words, we are using volumes.
And instead of Docker volumes,
where Docker managed some folders
somewhere on our host machine.
We now set up a volume with help of EFS,
where we indeed know,
where this data will be stored,
but we're still not doing that to change
that data from outside.
But instead to give that container a chance
of storing data somewhere,
where it will survive containers shuts down.
Now, that is how we can deploy multiple containers
at example of ECS, and how we can use volumes
at the example of EFS being used in conjunction with ECS.
As you can see,
it's more than just riding a Docker compose file,
but still overall, just a couple of steps,
you have to memorize and not too complex at all.
In the end, it's all about setting up this task definition,
where we define all our containers.
How they should be executed
and any volumes we might wanna use.
Nonetheless, as I already said,
I will not continue using that mongodb container
and I'll explain why and how to replace it,
in the next lecture.