AWS Elastic beanstalk: how to set ulimit when using docker images - amazon-web-services

I am using docker environment in an Elastic beanstalk cluster but having trouble with open files limit. I verified that on the host my open files limit is 65535, but in the docker container the soft limit is 1024 and hard limit is 4096. I'd like to increase these limits inside the container, but when I tried to do that manually I got error even with root:
root#4020d4faf5fc:/# ulimit -n 20000
bash: ulimit: open files: cannot modify limit: Operation not permitted
A similar thread also shares some ideas but seems like those are related to increasing limit of the host vs container.

You would need the SYS_RESOURCE Linux capability to set ulimit from within the container, which would typically be specified using the --cap-add flag with docker run.
With Elastic Beanstalk this can be accomplished in the following ways:
If you are already using docker-compose, then add it to your compose file as usual (under services.<your service> key)
ulimits:
nofile:
soft: 20000
hard: 20000
If you use Dockerrun.aws.json version 1 for single-container Docker environments, see Task Definition Resource Limits:
{
"AWSEBDockerrunVersion": "1",
.
.
.
"ulimits": [
{
"name": "nofile",
"softLimit": 20000,
"hardLimit": 20000
}
]
}
If you use Dockerrun.aws.json version 2 for multi-container Docker environments, this gist may be useful
{
"AWSEBDockerrunVersion": "2",
"containerDefinitions": [
{
.
.
.
"ulimits": [
{
"hardLimit": 20000,
"name": "nofile",
"softLimit": 20000
}
]
}
]
}
See also the Elastic Beanstalk Docker docs.

Related

How to get SYS_PTRACE on AWS Elastic Beanstalk with Amazon Linux 2, single-container, no Docker Compose

I need to do get the SYS_PTRACE kernel capability on my docker container. Here's the Docerrun.aws.json:
{
"AWSEBDockerrunVersion": "1",
"Authentication": {
"Bucket": "some-bucket",
"Key": "somekey"
},
"Image": {
"Name": "somename",
"Update": "true"
},
"Ports":[
{
"HostPort": 80,
"ContainerPort": 80
},
a few more ports
]
}
Remember, this is Amazon Linux 2, which is a whole new distribution and EB platform. We're not using Docker Compose (wherein you could add that to the yml).
I tried just adding in the following section:
"linuxParameters": {
"capabilities": {
"add": ["SYS_PTRACE"]
}
}
It was simply ignored.
Thanks!
It seems to me, this setting is not supported in v1. When looking into the docs under section "Docker platform Configuration - without Docker Compose" [1], linuxParameters is not listed as part of "Valid keys and values for the Dockerrun.aws.json v1 file". You might have to switch to v2 by using multi container Docker. The docs for v2 state that "the container definition and volumes sections of Dockerrun.aws.json use the same formatting as the corresponding sections of an Amazon ECS task definition file". [2]
It looks like your code above would work in v2 because it is a valid task definition section, see [3].
[1] https://docs.aws.amazon.com/elasticbeanstalk/latest/dg/single-container-docker-configuration.html
[2] https://docs.aws.amazon.com/elasticbeanstalk/latest/dg/create_deploy_docker_v2config.html
[3] https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task_definition_parameters.html

Docker port mapping on AWS Elastic Beanstalk

I have a Docker container specified through Dockerfile which has to be run with the -p flag in order to function properly. On my local machine, after running
docker run -d -p 5000:5000 blagtagger:v0.4.3
the port mapping is shown as 0.0.0.0:5000->5000/tcp and everything works smoothly.
Now, I need to deploy it on AWS Elastic Beanstalk, so I prepared my Dockerrun.aws.json file as follows:
{
"AWSEBDockerrunVersion": "1",
"Ports": [
{
"ContainerPort": 5000,
"HostPort": 5000
}
]
}
However, the container port does not seem to map to the host port correctly. The port mapping is shown as 5000/tcp.
How can I ask Beanstalk to set the mapping to 0.0.0.0:5000->5000/tcp?
It turns out there is no elegant way to accomplish this. Along the lines of the answers here and here, I added the following in a file named .ebextensions/01-commands.config:
commands:
00001_add_port_mapping:
cwd: /tmp
command: 'sed -i "s/docker run -d/docker run -p 5000:5000 -d/" /opt/elasticbeanstalk/hooks/appdeploy/enact/00run.sh'
and discarded the Dockerrun.aws.json file.

AWS Elastic Beanstalk deploying Docker with simple SpringBoot Eureka image failure

I'm new to AWS and Elastic Beanstalk. I'm trying to test a multi-container Docker deployment with a simple Spring Boot Docker image https://hub.docker.com/r/springcloud/eureka/ just to see something working for now.
I'm uploading a very simple Dockerrun.aws.json file to the Beanstalk console:
{
"AWSEBDockerrunVersion": 2,
"containerDefinitions": [
{
"name": "eureka1",
"image": "springcloud/eureka",
"essential": true,
"memory": 128,
"portMappings": [
{
"hostPort": 80,
"containerPort": 8761
}
]
}
]
}
The springcloud/eureka Docker image starts by default the server on port 8761, and I'm mapping the host's port 80 to the container's port 8761.
So opening the application's url (something like http://sample-env-1.xxx.eu-central-1.elasticbeanstalk.com/ ), it should display the Eureka server interface... It doesn't. It just says "Unable to connect" standard browser page.
The logs don't appear to indicate an error... Or at least I can't see any obvious error.
Seems like I was putting the "memory" parameter to 128 which probably was not enough. Switching it to "memoryReservation": 128 made it work.
"memory" indicates the Hard Limit and "memoryReservation" indicates Soft Limit. One should always use a soft limit if the developer is not sure about the memory requirement.

Unable to access jarfile - Docker on Elastic Beanstalk

I am trying to deploy a Docker image of a Spring Boot application to AWS Elastic Beanstalk and I'm encountering this error in /var/log/eb-activity.log:
Docker container quit unexpectedly after launch: Docker container quit unexpectedly on Wed Jun 22 11:56:25 UTC 2016:
Error: Unable to access jarfile /home/packedit/app/packed-it.jar. Check snapshot logs for details. (Executor::NonZeroExitStatus)
This is a single container on Elastic Beanstalk with the following Dockerrun.aws.json:
{
"AWSEBDockerrunVersion": "1",
"Image": {
"Name": "packedit/packedit-api",
"Update": "true"
},
"Ports": [
{
"ContainerPort": "8080"
}
],
"Volumes": [
{
"HostDirectory": "/var/app/packedit",
"ContainerDirectory": "/home/packedit/app"
}
],
"Logging": "/home/packedit/app/logs"
}
This is the Dockerfile:
FROM java:8
MAINTAINER my#email.com
VOLUME /tmp
EXPOSE 8080
ENV USER_NAME packedit
ENV APP_HOME /home/$USER_NAME/app
ENV APP_FILENAME packed-it.jar
RUN useradd -ms /bin/bash $USER_NAME
RUN mkdir -p $APP_HOME/data
ADD $APP_FILENAME $APP_HOME/$APP_FILENAME
RUN chown -R $USER_NAME $APP_HOME/
USER $USER_NAME
WORKDIR $APP_HOME
RUN bash -c 'touch $APP_FILENAME'
# Can't use $APP_FILENAME here because ENTRYPOINT does not do ENV replacement
# See: http://stackoverflow.com/a/28854410/336752
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","packed-it.jar"]
I have successfully deployed the Docker image to an EC2 instance using ECS but I have not succeeded with Elastic Beanstalk. My guess is that I am doing something wrong with the volumes but I am struggling to understand the documentation. I originally started with a multicontainer configuration but have simplified to try and isolate my issue.
Thanks for any advice.
You need to remove the line
"ContainerDirectory": "/home/packedit/app"
from your Dockerrun.aws.json.
It seems like the confusion is with how docker volumes work. The volumes are allocated at runtime and persist on consecutive runs on the same machine.
Here is what is happening. The docker image is built with jar in /home/packedit/app but since you have defined a volume in the same location, an empty volume is created when it is run and mounted in that location. Hence, the same directory of the image is ignored.
Here is how you can reproduce the issue locally:
docker build .
docker run -v /home/packedit/app IMAGEID_FROM_OUTPUT_OF_PREVIOUS_COMMAND

Error deploying Play Framework on AWS Beanstalk Docker

Im running a Play Framework app on AWS Beanstalk with Docker (64bit Amazon Linux 2015.03 v1.4.1 running Docker 1.6.0).
Docker File:
FROM relateiq/oracle-java8
MAINTAINER XXXX
EXPOSE 9000
ADD files /
WORKDIR /opt/docker
RUN ["chown", "-R", "daemon", "."]
RUN ["chmod", "+x", "bin/app"]
USER daemon
ENTRYPOINT ["bin/app"]
CMD []
Dockerrun.aws.json
{
"AWSEBDockerrunVersion": "1",
"Ports": [{
"ContainerPort": "9000"
}]
}
When the instance first starts I get about 1 minute where its deployed as normal, then after I browse a few pages the error shows:
502 Bad Gateway
nginx/1.6.2
The error in the ElasticBeanstalk logs is:
Play server process ID is 1 This application is already running (Or delete /opt/docker/RUNNING_PID file).
I also get in the /var/log/docker-events.logthe following messages every 30 seconds:
2015-05-30T20:07:58.000000000Z d0425e47095e5e2637263a0fe9b49ed759f130f31c041368ea48ce3d99d1e947: (from aws_beanstalk/current-app:latest) start
2015-05-30T20:08:15.000000000Z d0425e47095e5e2637263a0fe9b49ed759f130f31c041368ea48ce3d99d1e947: (from aws_beanstalk/current-app:latest) die
2015-05-30T20:08:16.000000000Z d0425e47095e5e2637263a0fe9b49ed759f130f31c041368ea48ce3d99d1e947: (from aws_beanstalk/current-app:latest) start
2015-05-30T20:08:31.000000000Z d0425e47095e5e2637263a0fe9b49ed759f130f31c041368ea48ce3d99d1e947: (from aws_beanstalk/current-app:latest) die
Can anyone see my issue? Cheers.
Adding the following to build.sbt should resolve the issue:
javaOptions in Universal ++= Seq("-Dpidfile.path=/dev/null")