AWS ElasticBeanstalk can't find Dockerfile - amazon-web-services

I have the following directory layout
./www/index.php
Dockerfile
apache-config.conf
I then zip up the file and upload it onto Elastic Beanstalk, but I get the following error message:
[Instance: i-572d1ae8] Command failed on instance. Return code: 1 Output: Dockerfile and Dockerrun.aws.json are both missing, abort deployment. Hook /opt/elasticbeanstalk/hooks/appdeploy/pre/03build.sh failed. For more detail, check /var/log/eb-activity.log using console or EB CLI.
The log file contains the following message:
AppDeployPreHook/01unzip.sh] : Completed activity. Result:
Archive: /opt/elasticbeanstalk/deploy/appsource/source_bundle
creating: /var/app/current/DI_Test/
inflating: /var/app/current/DI_Test/.DS_Store
creating: /var/app/current/__MACOSX/
creating: /var/app/current/__MACOSX/DI_Test/
inflating: /var/app/current/__MACOSX/DI_Test/._.DS_Store
inflating: /var/app/current/DI_Test/apache-config.conf
inflating: /var/app/current/DI_Test/Dockerfile
inflating: /var/app/current/__MACOSX/DI_Test/._Dockerfile
creating: /var/app/current/DI_Test/www/
inflating: /var/app/current/DI_Test/www/.DS_Store
creating: /var/app/current/__MACOSX/DI_Test/www/
inflating: /var/app/current/__MACOSX/DI_Test/www/._.DS_Store
inflating: /var/app/current/DI_Test/www/index.php
[2015-10-29T14:01:33.279Z] INFO [2865] - [Application deployment/StartupStage0/AppDeployPreHook/03build.sh] : Starting activity...
[2015-10-29T14:01:33.579Z] INFO [2865] - [Application deployment/StartupStage0/AppDeployPreHook/03build.sh] : Activity execution failed, because: Dockerfile and Dockerrun.aws.json are both missing, abort deployment (ElasticBeanstalk::ExternalInvocationError)
caused by: Dockerfile and Dockerrun.aws.json are both missing, abort deployment (Executor::NonZeroExitStatus)
Why is my dockerfile not being read here? I can build the image and run it just fine without Elastic Beanstalk.

Sharing another possibility:
You were testing eb and you've just added your Dockerfile.
According to the doc
If git is installed, EB CLI uses the git archive command to create a
.zip file from the contents of the most recent git commit command.
That's saying if your Dockerfile is not committed, it won't be zipped in therefore your instance can't find it.

Compress those stuff within your project folder(go into your project folder and zip everything), instead of zipping your project folder.

You don't need to include parent directory in zip file. Suppose you want to zip ./www/index.php ,Dockerfile and apache-config.conf then,
zip dist.zip Dockerfile ./www/index.php apache-config.conf
The upload dist.zip.
http://docs.aws.amazon.com/elasticbeanstalk/latest/dg/using-features.deployment.source.html

I've come across this issue as well. It seems a Dockerrun.aws.json file is required as well. I believe that is because other files are included in the app. If you had only a Dockerfile and nothing else, it wouldn't be required.
Here's the documentation: http://docs.aws.amazon.com/elasticbeanstalk/latest/dg/create_deploy_docker_image.html

In my case there was a spelling mistake in Dockerfile name i.e DockerFile. Elastic Beanstalk is case sensitive.

Super newbie mistake, but when I had this problem it was because my Dockerfile was actually Dockerfile.txt. After removing the .txt extension and creating a plain file it worked fine.

I had the same issue. The solution is to go to the actual directory that you are trying to zip and then run: zip name_of_file.zip *. Then the Dockerfile will get the exact same zip filename "Dockerfile", which is what Elastic Beanstalk is looking for.
If you zip from outside your directory, the Dockerfile's name will be "directory/Dockerfile", and that is what causes Elastic Beanstalk to fail.

I had a different problem. Using directly json, the Dockerrun files can have the form of Dockerrun_${DOCKER_TAG}.aws.json.
Solution: In zips, only Dockerrun.aws.json is allowed.

Two possible problems:
1) When zipping the folder enter the folder and zip from the command line or in finder select each file individually then zip together.
Example: https://docs.aws.amazon.com/elasticbeanstalk/latest/dg/applications-sourcebundle.html
2) Elastic Beanstalk is case sensitive so make sure your file is labeled "Dockerfile" not "dockerfile"

I was trying to upload a zip which contained a singular file Dockerrun.aws.json. But docs state:
If you use only a Dockerfile or only a Dockerrun.aws.json file to deploy your application, you don't need to create a .zip file
So you can simply upload either one or another without zipping it.

To document just another way to get into this - added by mistake Dockerfile in the .ebignore file. I was testing non-docker and docker deploys and worked from the same directory. Dockerfile is not obviously needed with regular deploys but should not be added to .ebignore when doing docker deploys.

I added the dockerrun.aws.json and config.yml in a folder called .elasticbeanstalk/ which is in the root folder.

Related

.war file is not deployed in the Elastic Beanstalk environment

I'm deploying .war file with .ebextensions in EB environment using Jenkins pipeline. The deployment is succeeded and all the commands are executed in at the deployment stage, but when I check the /usr/share/tomcat8/webapps/ROOT/ I only see my .war file is there as it is, without extracting.
What would be the reason for this? and any idea about how to resolve that issue ? Please find my code snippet below.
zip -r app-${BUILD_NUMBER}.zip myapp.war .ebextensions
aws s3 cp myapp.war s3://inc-eb-deployments/inc-batch/myapp.war
Try deploying it to the webapps folder, not webapps/ROOT. Then tomcat should decompress to webapps/myapp.
If you want to deploy your application in the root directory you need to name your build output ROOT.war and place it in the webapps folder.
Once the ebextesnions are setup with .war file, which is being coupled with ebextensions(.zip format). In this case, .war file should be unzipped through the .ebextension file manually. Following is the sample code snippet.
fix_path:
command: "unzip <app-name>.war 2>&1 > /var/log/my_last_deploy.log"
This solution worked on my environment.

Need to move deployed folder - AWS CodeDeploy

So I want to deploy my application. I have a moving script that moves all the deployed files to where they need to be sent.
But when that script is running in BeforeInstall phase it's not capable of finding the files.
So I added a pwd to the script and the directory is "deployment-root". I suppose I need to cd into the deployment folder, but the id is always different.
Is there any way I can get that id in my appspec.yml file so that I can cd into it in my deploy scripts?
Thanks,
You don't have to do a manual copy, in appspect.yml, in "files" section, you can specify what and where your files copied to.
files:
- source: Config/config.txt
destination: /webapps/Config
- source: source
destination: /webapps/myApp
Provides information to CodeDeploy about which files from your application revision should be installed on the instance during the deployment's Install event.
More details via this page:
https://docs.aws.amazon.com/codedeploy/latest/userguide/reference-appspec-file-structure-files.html

CodeDeploy agent did not find an AppSpec file within the unpacked revision directory at revision-relative path "appspec.yml"

The CodeDeploy agent did not find an AppSpec file within the unpacked revision directory at revision-relative path "appspec.yml".
The revision was unpacked to directory "/opt/codedeploy-agent/deployment-root/0bb5a5aa-5894-4575-a69c-a7a4e79b4cdf/d-HQ5GBC7SW/deployment-archive"
The AppSpec file was expected but not found at path "/opt/codedeploy-agent/deployment-root/0bb5a5aa-5894-4575-a69c-a7a4e79b4cdf/d-HQ5GBC7SW/deployment-archive/appspec.yml".
I had the same problem and the other answer helped me reach the right conclusion. In my situation, I had the appspec.yml file in my git repo, but I forgot to add it to the artifact files section. As a result, the appspec.yml wasn't included in the zip and so the deployment step couldn't find it.
In your buildspec.yml, add:
artifacts:
files:
- appspec.yml
- ... other files to include in your build ...
I had some other errors in my deployment configuration too. Looking at the bottom of the log file helped discover them:
less /var/log/aws/codedeploy-agent/codedeploy-agent.log
At one point, my EC2 instance also hung when trying to run a deployment and stopping and restarting the codedeploy agent didn't help. I had to completely restart the EC2 instance.
These docs where helpful: https://docs.aws.amazon.com/codebuild/latest/userguide/build-spec-ref.html
Are you putting the appspec.yml file at root level of your folder bundle? If yes, how are you creating the bundle? If you are just creating a .zip then you need to make sure you are adding the files to the zip instead of a folder.
Adding onto Aura's answer which solved it for me. Thank you again Aura! For mac users:
To create a zip with all of the files, open up the folder you want to zip in finder, highlight all of files (use command A), right click and then select "Compress XYZ items".
The mistake you might be making is right clicking on the folder itself and clicking "Compress FolderName".
The problem with compressing the entire folder is that the "unpacked directory" ends up being a directory itself. Hence, when the CodeDeploy agent goes looking for the appspec.yml file, it will see something like this "FolderName/" rather than the contents of the FolderName (which should include an appspec.yml).
Hope this extra detail helps.
#It seems to have a successful deployment at some point of time.
It's looking for the most recent deployment and if it's not available above error will occur.
Go into /opt/codedeploy-agent/deployment-root/deployment-instructions/ and delete all the files in there.
#Then it won't look for this last deploy.
Not the most useful answer. But I had this problem as well as codebuild could not find the scripts defined in appspec.yml I spent a whole day and then at the end just started rebooted the ec2 and it was able to find the scripts. 😖
Issue can be fixed by:
Edit your aws codepipeline.
Edit the codedeploy configuration.
select "SourceArtifact" in input artifacts. (This will deploy all the source code to your desired server and location along with appspec.yml file.)

AWS Code Deploy Error on Before Install Cannot Solve

So I am attempting to setup CodeDeploy for my application and I keep getting an error during the BeforeInstall part of the deployment. Below is the error.
Error Code UnknownError
Script Name
Message No such file or directory - /opt/codedeploy-agent/deployment-root/06100f1b-5495-42d9-bd01-f33d59fb5deb/d-NL5K1THE8/deployment-archive/appspec.yml
Log Tail
I assumed this meant the YAML file was in the wrong place. However it is in the root directory of my revision. I have tried using a simple AppSpec file like so instead of a more complex one.
## YAML Template.
---
version: 0.0
os: linux
files:
- source: /
destination: /home/ubuntu/www
More or less since this is a first deployment I want it to add all files in the revision to the public directory on the web server.
I am tearing my hair out over this and I feel it is a simple issue. I have the IAM policies and roles correct and I have CodeDeploy setup and running on my instance I am trying to deploy to.
It seems to think you had a successful deploy at some point.
Go into /opt/codedeploy-agent/deployment-root/deployment-instructions/ and delete all the files in there. Then it won't look for this last deploy.
I just had this SAME problem and I figured it out! Make sure your AppSpec file has the right EXTENSION! I was using yaml and not yml, now everything works perfectly.
I made it work like this:
I had a couple of failed deployments for various reasons.
The thing is that CD keeps in the EC2 instance and in the path /opt/codedeploy-agent/deployment-root/​ a folder named by the ID of the failed deployment [a very long alphanumeric sting] .
Delete this folder and create a new deployment [from the aws UI console] and redeploy the application. This way the appspec.yml file that is in the wrong place will be deleted.
It should now succeed.
Extra Notice:
CD does not rewrite files [that have not been created by it's specific deployment]
CodeDeploy does not deploy in a folder that there is already code[files] as it does not want to interfere with different CD deployments and/or other CI/CD tools [like Jenkins].
It only deploys in a path that has already deploy code with the specific deployment.
You can empty the folder where your deployment want to happen and redeploy your code via CD.
When you login to the host, do you see the appspec.yml file in the directory there? If not are you positive it has been checked in with the rest of your deployed code?
Just encountered this issue too. In my case, the revision zip file extracts into a directory when deployed. Because of that /opt/codedeploy-agent/deployment-root/xxx/xxx/deployment-archive contains the parent directory of my revision files (instead of the actual revision files).
The key is to compress your revision without the parent directory. In mac terminal,
cd your-app-directory-containing-appspec
zip -r app.zip .

Deploy .war to AWS

I want to deploy war from Jenkins to Cloud.
Could you please let me know how to deploy war file from Jenkins on my local to AWS Bean Stalk ?
I tried using a Jenkins post-process plugin to copy the artifact to S3, but I get the following error:
ERROR: Failed to upload files java.io.IOException: put Destination [bucketName=https:, objectName=/s3-eu-west-1.amazonaws.com/bucketname/test.war]:
com.amazonaws.AmazonClientException: Unable to execute HTTP request: Connect to s3.amazonaws.com/s3.amazonaws.com/ timed out at hudson.plugins.s3.S3Profile.upload(S3Profile.java:85) at hudson.plugins.s3.S3BucketPublisher.perform(S3BucketPublisher.java:143)
Some work has been done on this.
http://purelyinstinctual.com/2013/03/18/automated-deployment-to-amazon-elastic-beanstalk-using-jenkins-on-ec2-part-2-guide/
Basically, this is just adding a post-build task to run the standard command line deployment scripts.
From the referenced page, assuming you have the post-build task plugin on Jenkins and the AWS command line tools installed:
STEP 1
In a Jenkins job configuration screen, add a “Post-build action” and choose the plugin “Publish artifacts to S3 bucket”, specify the Source (in our case, we use Maven so the source is target/.war and destination is your S3 bucket name)
STEP 2
Then, add a “Post-build task” (if you don’t have it, this is a plugin in Maven repo) to the same section above (“Post-build Actions”) and drag it below the “Publish artifacts to S3 bucket”. This is important that we want to make sure the war file is uploaded to S3 before proceeding with the scripts.
In the Post-build task portion, make sure you check the box “Run script only if all previous steps were successful”
In the script text area, put in the path of the script to automate the deployment (described in step 3 below). For us, we put something like this:
<path_to_script_file>/deploy.sh "$VERSION_NUMBER" "$VERSION_DESCRIPTION"
The $VERSION_NUMBER and $VERSION_DESCRIPTION are Jenkins’ build parameters and must be specified when a deployment is triggered. Both variables will be used for AEB deployment
STEP 3
The script
#!/bin/sh
export AWS_CREDENTIAL_FILE=<path_to_your aws.key file>
export PATH=$PATH:<path to bin file inside the "api" folder inside the AEB Command line tool (A)>
export PATH=$PATH:<path to root folder of s3cmd (B)>
//get the current time and append to the name of .war file that's being deployed.
//This will create a unique identifier for each .war file and allow us to rollback easily.
current_time=$(date +"%Y%m%d%H%M%S")
original_file="app.war"
new_file="app_$current_time.war"
//Rename the deployed war file with the new name.
s3cmd mv "s3://<your S3 bucket>/$original_file" "s3://<your S3 bucket>/$new_file"
//Create application version in AEB and link it with the renamed WAR file
elastic-beanstalk-create-application-version -a "Hoiio App" -l "$1" -d "$2" -s "<your S3 bucket>/$new_file"