Deploying your Django Application to Elastic Beanstalk - carloramferrer/Django-AWS GitHub Wiki
These are detailed steps on how to deploy your Django application on AWS S3 File Storage and Elastic Beanstalk
First, we need to setup our S3 File Storage to serve our static files and media files in AWS.
- Navigate to IAM Users
- Select Create New Users
- Enter a user name
- Ensure Prammatic Access is selected, hit Next.
- Select Create a Group
- Define a name for the group and search for built-in policy AmazonS3FullAccess, hit Create group
- Select Next: Review
- Select Download credentials and keep them safe.
- Open the credentials.csv file that was just downloaded/created
- Note the Access Key Id and Secret Access Key as they are needed for a future step. These will be referred to as <your_access_key_id> and <your_secret_access_key>
- Create a bucket and set a name for your bucket (usually app name)
- Select the region closest to your area: Southeast
- Click next until you finish and leave all as is
- Navigate to IAM Home
- Select user and click on the Permissions tab
- Click Add Permissions
- Click on Attach Existing Policies Directly
- Click Create Policy then select Create Your Own Policy
- Set Policy Name
- Set Policy Document. Make sure to change the S3 bucket names
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:ListAllMyBuckets"
],
"Resource": "arn:aws:s3:::*"
},
{
"Effect": "Allow",
"Action": [
"s3:ListBucket",
"s3:GetBucketLocation",
"s3:ListBucketMultipartUploads",
"s3:ListBucketVersions"
],
"Resource": "arn:aws:s3:::<your_bucket_name>"
},
{
"Effect": "Allow",
"Action": [
"s3:*Object*",
"s3:ListMultipartUploadParts",
"s3:AbortMultipartUpload"
],
"Resource": "arn:aws:s3:::<your_bucket_name>/*"
}
]
}
- Click on bucket
- Permissions > Cors Configuration
- Paste:
<CORSConfiguration>
<CORSRule>
<AllowedOrigin>*</AllowedOrigin>
<AllowedMethod>GET</AllowedMethod>
<MaxAgeSeconds>3000</MaxAgeSeconds>
<AllowedHeader>Authorization</AllowedHeader>
</CORSRule>
</CORSConfiguration>
- Install Django Storages:
python -m pip install boto boto3 django-storages - Update INSTALLED APPS in settings.py:
INSTALLED_APPS = [
...
'storages',
...
]
- Migrate:
python manage.py migrate - Create and go to aws folder in same directory as settings.py
- Create three files in the 'aws' folder: 'init.py', 'utils.py', 'conf.py '
- In utils.py add:
from storages.backends.s3boto3 import S3Boto3Storage
StaticRootS3BotoStorage = lambda: S3Boto3Storage(location='static')
MediaRootS3BotoStorage = lambda: S3Boto3Storage(location='media')
- In conf.py add:
import datetime
AWS_ACCESS_KEY_ID = "<your_access_key_id>"
AWS_SECRET_ACCESS_KEY = "<your_secret_access_key>"
AWS_FILE_EXPIRE = 200
AWS_PRELOAD_METADATA = True
AWS_QUERYSTRING_AUTH = True
AWS_DEFAULT_ACL = 'private'
DEFAULT_FILE_STORAGE = '<your-project>.aws.utils.MediaRootS3BotoStorage'
STATICFILES_STORAGE = '<your-project>.aws.utils.StaticRootS3BotoStorage'
AWS_STORAGE_BUCKET_NAME = '<your_bucket_name>'
S3DIRECT_REGION = 'ap-southeast-1'
S3_URL = '//%s.s3.amazonaws.com/' % AWS_STORAGE_BUCKET_NAME
MEDIA_URL = '//%s.s3.amazonaws.com/media/' % AWS_STORAGE_BUCKET_NAME
MEDIA_ROOT = MEDIA_URL
STATIC_URL = S3_URL + 'static/'
ADMIN_MEDIA_PREFIX = STATIC_URL + 'admin/'
two_months = datetime.timedelta(days=61)
date_two_months_later = datetime.date.today() + two_months
expires = date_two_months_later.strftime("%A, %d %B %Y 20:00:00 GMT")
AWS_HEADERS = {
'Expires': expires,
'Cache-Control': 'max-age=%d' % (int(two_months.total_seconds()), ),
}
- In setttings.py add:
from <your-project>.aws.conf import *
- Run:
python manage.py collectstatic
After this, you can check your application
Next, we host our application to AWS Elastic Beanstalk. Elastic Beanstalk is a service to deploy, manage and scale applications in different languages. With this, we do not have to worry about scaling our infrastructure based on the demand and traffic of our application. Hence, it reduces infrastructure management complexities without affecting our choice and control of which service and technologies to use.
- Create a file for all modules used
python -m pip freeze > requirements.txtDo not include the following modules and comment these out: pywin32, pypiwin32. These are only for windows environment - Create a directory called .ebextensions under the same directory/root of your project folder
- Add a configuration file called django.config and paste the following:
container_commands:
01_migrate:
command: "python manage.py migrate"
leader_only: true
02_collectstatic:
command: "python manage.py collectstatic --noinput"
option_settings:
aws:elasticbeanstalk:container:python:
WSGIPath: <project-name>/wsgi.py
if you have an SSL certificate included add the following as well:
files:
"/etc/httpd/conf.d/ssl_rewrite.conf":
mode: "000644"
owner: root
group: root
content: |
RewriteEngine On
<If "-n '%{HTTP:X-Forwarded-Proto}' && %{HTTP:X-Forwarded-Proto} != 'https'">
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R,L]
</If>
- Add another configuration file called packages.config and paste the following:
packages:
yum:
postgresql93-devel: []
You can view the full documentation of Justin Mitchel here.
- Install your eb command line (eb cli)
python -m pip install awsebcli
eb --version
- Initialize eb cli.
eb init
- Provide your access keys to be able to manage your AWS resources
You have not yet set up your credentials or your credentials are incorrect.
You must provide your credentials.
(aws-access-id): AKIAJOUAASEXAMPLE
(aws-secret-key): 5ZRIrtTM4ciIAvd4EXAMPLEDtm+PiPSzpoK
-
Set your application name, platform and SSH key pair. You can use the default 'eb' name for you application. Next, choose which platform you're using. In our case, choose Python 3.6. Lastly, use the default option for your key pair. If you want to change your settings, you can use
eb init -i. More documentation for configurations are included in the AWS Documentation. -
Create your environment with your project name
eb createThis command will create your environment with the name you've specified. -
Check your environment status
eb statusand copy the CNAME of your environment. -
Copy the CNAME and add this to ALLOWED_HOSTS in your settings.py
ALLOWED_HOSTS = [..., 'project-name.elasticbeanstalk.com']
- Stage and commit your changes for deployment.
git add .andgit commit -m "for deployment" - Deploy your latest commits using
eb deploy. Make sure you've already commited your latest changes to your master branch. 10.. Check if your app is already running in your environmenteb open. You can also track your environment status in your Elastic Beanstalk Console in AWS.
- Change your database settings in settings.py
# Database
# https://docs.djangoproject.com/en/2.2/ref/settings/#databases
if 'RDS_DB_NAME' in os.environ:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql_psycopg2',
'NAME': os.environ['RDS_DB_NAME'],
'USER': os.environ['RDS_USERNAME'],
'PASSWORD': os.environ['RDS_PASSWORD'],
'HOST': os.environ['RDS_HOSTNAME'],
'PORT': os.environ['RDS_PORT'],
}
}
else:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
}
}
In case you do not have psycopg2 installed, install it and include it in your requirements.txt.
python -m pip install psycopg2
python -m pip freeze > requirements.txt
- In settings.py, change
DEBUG = TruetoDEBUG = False. - Stage and commit your changes for deployment.
git add .andgit commit -m "deploying with postgresql" - Run the command
eb console - In the menu, select Configurations > Databases > Modify
- Pick a number from 5 to 1024 to select the storage capacity of your database.
- Create a username and password then Click Apply