starting container process caused: exec: "[\"/bin/sh -c\"": stat ["/bin/sh -c": no such file or directory - docker

I am building and deploying an application via Docker and ECS Fargate. I have my entrypoint command defined in the ECS Task definition. Upon pushing the image into a private ECR repository, I am getting this error when ECS Fargate attempts to deploy the docker image. Any advice would be helpful. Below is the dockerfile, Task Definition, and the error.
Dockerfile
FROM centos:7
COPY /src/main/build/application.zip /tmp/application.zip
COPY /src/main/residual-container-setup/application/init.sh /tmp/init.sh
#Environment variables and Entry point being defined via task definition
Task Definition
{
"containerDefinitions": [
{
"logConfiguration": {
"logDriver": "awslogs",
"options": {
"awslogs-group": "/ecs/application",
"awslogs-region": "us-east-2",
"awslogs-stream-prefix": "ecs"
}
},
"entryPoint": [
"[\"/bin/sh -c\"",
"\"/tmp/init.sh\"]"
],
"portMappings": [
{
"hostPort": 9003,
"protocol": "tcp",
"containerPort": 9003
}
],
"cpu": 0,
"environment": [
{
"name": "HOST",
"value": "dev.application.com"
},
{
"name": "REST_PORT",
"value": "8003"
}
],
"mountPoints": [],
"volumesFrom": [],
"image": "xxxxxxxxxxxx.dkr.ecr.us-east-2.amazonaws.com/application:latest",
"essential": true,
"name": "application"
}
]
Error
container_linux.go:380: starting container process caused: exec: "[\"/bin/sh -c\"": stat ["/bin/sh -c": no such file or directory
I attempted running the container locally with the following command: `docker run -it $docker_image /bin/sh
I was unable to even exec into the container. I believe I may need to install additionally in the image to get this to work. Any advice would be helpful.
Update
I have updated the dockerfile to update the permissions on the init script using the following command: chmod +x /tmp/init.sh
I have also update the task definition entrypoint attribute to ["/bin/sh", "-c", "/tmp/init.sh"]
After making these changes I am now being presented with the following:
container_linux.go:380: starting container process caused: exec: "-c": executable file not found in $PATH

Your entrypoint is defined wrongly.
The way you did it Linux thinks the path to the binary is "/bin/sh -c". If you check the container image I'm pretty sure you do not find that file either.

Related

how to bring up failed container

have a container that failed after a long setup and i want to log in (exec bash) at that point instead of executing the slow setup again. Is there any way?
The container is a left over from a docker build process, it is still the FROM ... AS builder stage.
if i try to start it, it will fail right away.
$ docker start -ai 3d35a7f7a7b4
/bin/sh: mvn: command not found
trying to exec anything right away doesn't work either
$ docker start 3d35a7f7a7b4 & docker exec 3d35a7f7a7b4 -it /bin/sh
[1] 403273
3d35a7f7a7b4
unable to upgrade to tcp, received 500
[1]+ Done docker start 3d35a7f7a7b4
more info:
$ docker inspect 3d35a7f7a7b4
[
{
"Id": "3d35a7f7a7b4018ebbbd9aa59356714d7fed291a43752cbcb86dd852c946cc1e",
"Created": "2022-07-06T23:56:37.001004587Z",
"Path": "/bin/sh",
"Args": [
"-c",
"mvn --version"
],
"State": {
"Status": "exited",
"Running": false,
"Paused": false,
"Restarting": false,
"OOMKilled": false,
"Dead": false,
"Pid": 0,
"ExitCode": 127,
"Error": "",
"StartedAt": "2022-07-07T00:02:35.755444447Z",
"FinishedAt": "2022-07-07T00:02:35.75741167Z"
},
"Image": "sha256:4819e2469963fdf531ec5bce5401b7ae7d28cd403528c0109512b5170ef61752",
...
this is not an optimal answer. Here just for documentation (and for people to vote up if it is the best one can do with docker)
docker run can be used on the image of the stopped container, and you can pass the CMD parameter right away. But any other peculiarity of the stopped container will also have to be repeated. e.g. network.
for the example on the question:
host$ docker run -it sha256:4819e2469963fdf531ec5bce5401b7ae7d28cd403528c0109512b5170ef61752 /bin/bash
container# _

Delete a file before starting a docker container

I'm using this Graphite Docker Image and it is using an entrypoint called "/entrypoint" and I think no additional command: https://hub.docker.com/r/graphiteapp/graphite-statsd/dockerfile
Now my goal is to delete a specific file everytime when the container starts and BEFORE the script /entrypoint is running.
I tried to override the default entrypoint with --entrypoint "rm -f /opt/graphite/path/to/file; /entrypoint", but then the container is always restarting the whole time. This is the result (docker inspect):
[
{
"Id": "dcd0f2ba87fe3aae8089b40ea3e350c51750cb1cc2f890b066278e2cb52ce013",
"Created": "2020-07-16T03:31:29.76953014Z",
"Path": "rm",
"Args": [
"-f",
"/opt/graphite/path/to/file;",
"/entrypoint"
],
"State": {
"Status": "restarting",
...
...
...
...
Can you help me telling the right way to delete a file before starting a container?
Thank you in advance!

Mounted volume using volume-from is empty

So here's what I'm trying to do:
Nginx container linked to -> Rails container running Puma
Using docker-compose, this solution works great. I'm able to start both containers and the NGINX container has access to the volume in the linked container using volumes_from.
First, the relevant bits of the Dockerfile for Rails:
ENV RAILS_ROOT /www/apps/myapp
RUN mkdir -p $RAILS_ROOT
WORKDIR $RAILS_ROOT
.... lots of files get put in their proper places ....
EXPOSE 3000
VOLUME [/www/apps/myapp/]
CMD puma -C config/puma.rb
Nginx config is pretty basic, relevant parts are here:
ENV RAILS_ROOT /www/apps/myapp
# Set our working directory inside the image
WORKDIR $RAILS_ROOT
EXPOSE 80
EXPOSE 443
Again, this all works great in docker-compose. However, in ECS, I'm trying to use the following task definition:
{
"family": "myapp",
"containerDefinitions": [
{
"name": "web",
"image": "%REPOSITORY_URI%:nginx-staging",
"cpu": 512,
"memory": 512,
"portMappings": [
{
"containerPort": 80,
"protocol": "tcp"
},
{
"containerPort": 443,
"protocol": "tcp"
}
],
"links": [
"myapp"
],
"volumesFrom": [
{
"sourceContainer": "myapp",
"readOnly": false
}
],
"essential": true,
"logConfiguration": {
"logDriver": "awslogs",
"options": {
"awslogs-group": "awslogs-myapp-staging",
"awslogs-region": "us-west-2",
"awslogs-stream-prefix": "awslogs-myapp-nginx"
}
}
},
{
"image": "%REPOSITORY_URI%:v_%BUILD_NUMBER%",
"name": "myapp",
"cpu": 2048,
"memory": 2056,
"essential": true,
...bunch of environment variables, etc.
}
The task starts in ECS as expected, and the myapp container looks perfect. However, when I check out the nginx container on the EC2 instance host with
docker exec -it <container> bash
I land in /www/apps/myapp, but the directory is empty. I've tried to mount drives and do several other things and I'm at a loss here... anyone have any ideas as to how to get the files from the linked container to be usable in my nginx container?
And of course, right after I post this I find the solution. So no one else has to feel this pain, here it is:
VOLUME [/www/apps/myapp/]
VOLUME ["/www/apps/myapp/"]
sigh

Marathon With Private Docker Repo

I'm having issues pulling from a private docker repo when I add a marathon application. I've tarred my ~/.docker folder (including the docker.config file which contains my login information) and distributed that along to my mesos slaves as /etc/docker.tar.gz (I'm using docker 1.6.2).
I've then added a new marathon app with:
dcos marathon add app marathon.json
My marathon.json is as follows:
{
"id": "api",
"cpus": 1,
"mem": 1024,
"instances": 1,
"container": {
"type": "DOCKER",
"docker": {
"image": "company/api",
}
},
"args": ["java", "-jar", "api.jar"],
"uris": [
"file:///etc/docker.tar.gz"
]
}
The marathon app never starts, however. In my slave logs I've found the following line:
Container x for executor y of framework z failed to start: Failed to 'docker pull company/api': exit status = exited with status 1 stderr = time="2015-11-12T00:03:57Z" level=fatal msg="Error: image company/api:latest not found"
How can I get this to pull correctly?

Mesos cannot deploy container from private Docker registry

I have a private Docker registry that is accessible at https://docker.somedomain.com (over standard port 443 not 5000). My infrastructure includes a set up of Mesosphere, which have docker containerizer enabled. I'm am trying to deploy a specific container to a Mesos slave via Marathon; however, this always fails with Mesos failing the task almost immediately with no data in stderr and stdout of that sandbox.
I tried deploying from an image from the standard Docker Registry and it appears to work fine. I'm having trouble figuring out what is wrong. My private Docker registry does not require password authentication (turned off for debugging this), AND if I shell into the Meso's slave instance, and sudo su as root, I can run a 'docker pull docker.somedomain.com/services/myapp' successfully every time.
Here is my Marathon post data for starting the task:
{
"id": "myapp",
"cpus": 0.5,
"mem": 64.0,
"instances": 1,
"container": {
"type": "DOCKER",
"docker": {
"image": "docker.somedomain.com/services/myapp:2",
"network": "BRIDGE",
"portMappings": [
{ "containerPort": 7000, "hostPort": 0, "servicePort": 0, "protocol": "tcp" }
]
},
"volumes": [
{
"containerPath": "application.yml",
"hostPath": "/var/myapp/application.yml",
"mode": "RO"
}
]
},
"healthChecks": [
{
"protocol": "HTTP",
"portIndex": 0,
"path": "/",
"gracePeriodSeconds": 5,
"intervalSeconds": 20,
"maxConsecutiveFailures": 3
}
]
}
I've been stuck on this for almost a day now, everything I've tried seems to be yielding the same result. Any insights on this would be much appreciated.
My versions:
Mesos: 0.22.1
Marathon: 0.8.2
Docker: 1.6.2
So this turns out to be an issue with volumes
"volumes": [
{
"containerPath": "/application.yml",
"hostPath": "/var/myapp/application.yml",
"mode": "RO"
}
]
Using the root path of the container of the root path may be legal in docker, but Mesos appears not to handle this behavior. Modifying the containerPath to a non-root path resolves this, i.e
"volumes": [
{
"containerPath": "/var",
"hostPath": "/var/myapp",
"mode": "RW"
}
]
If it is a problem between Marathon and the registry, the answer should be in the http logs of your registry. If Marathon connects, there will be an entry. And the Mesos master log should contain a clue as well.
It doesn't really sound like a problem between Marathon and Registry though. Are you sure you have 'docker,mesos' in /etc/mesos-slave/containerizers?
Did you --despite having no authentification-- try to follow Using a Private Docker Repository?
To supply credentials to pull from a private repository, add a .dockercfg to the uris field of your app. The $HOME environment variable will then be set to the same value as $MESOS_SANDBOX so Docker can automatically pick up the config file.

Resources