Deployment Guide
Pre-Requisites
Section titled “Pre-Requisites”-
An Amazon Web Services account. Right now, instructions are only built for hosting on Amazon Web Services.
-
An AWS EC2 Server with the following specifications or similar:
- T3.large (2 vCPU; 8GB Memory)
- Ubuntu 24.04
- 100 GB Storage
- Open Ports
- 80
- 443
- 22 (restricted to machines with SSH access)
Main Install
Section titled “Main Install”- SSH on your machine and perform an update
sudo apt-get update- Set up Docker’s apt repository (source: Docker Docs)
sudo apt-get updatesudo apt-get install ca-certificates curlsudo install -m 0755 -d /etc/apt/keyringssudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.ascsudo chmod a+r /etc/apt/keyrings/docker.asc
echo \ "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \ $(. /etc/os-release && echo "${UBUNTU_CODENAME:-$VERSION_CODENAME}") stable" | \ sudo tee /etc/apt/sources.list.d/docker.list > /dev/nullsudo apt-get update- Install the latest Docker packages (source: Docker Docs)
sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin- Add your user to the docker group so that it can run docker commands without sudo
sudo usermod -aG docker ${USER}(Exit and SSH into your machine again so this change takes effect)- Verify that the installation is successful by running the hello-world image (source: Docker Docs)
sudo docker run hello-world- Clone the OnMicro repo
git clone https://github.com/onmicroai/micro_ai.git- Prepare your env file by collecting ALL of the following environment variables.
- Set these variables on your own
| Variable Name | Description | Sample Value |
|---|---|---|
| PRODUCTION | Set to True for a hosted environment. False for a local environment. | True |
| DEBUG | Set to True for a local development environment. Otherwise, False | False |
| DOMAIN | Your full site name | https://my-site.ai |
| COOKIES_DOMAIN | Your site name without prefix | my-site.ai |
| CORS_ALLOWED_ORIGINS | http://localhost:3000,http://localhost:8000,http://localhost, https://my-site.ai | |
| CSRF_TRUSTED_ORIGINS | http://localhost:3000,http://localhost:8000,http://localhost, https://my-site.ai |
- Generate secure credentials for your database. The Docker process will create a database with these credentials the first time you run it.
| Variable Name | Description | Sample Value |
|---|---|---|
| DATABASE_NAME | The name of your database. The first time you run the install, the docker process will spin up a database with this name. | my_db |
| DATABASE_USER | The master user for your database. The first time you run the install, the docker process will spin up a database with access for this username. Use a secure username, not the default. | insecure_user |
| DATABASE_PASSWORD | The password for your database’s master user. The first time you run the install, the docker process will spin up a database with this password. Use a secure password, not the default. | insecure_password_123 |
| DATABASE_URL | The full database URL in this format: postgresql://[DATABASE_USER]:[DATABASE_PASSWORD]@db:5432/[DATABASE_NAME] We do use the separate DB Name, User, and Password for some docker health checks, whereas Django uses the full DATABASE_URL. Future task to eliminate this redundancy | postgresql://insecure_user:insecure_password_123@db:5432/my_db |
- Set AWS SES (Email) credentials based on the Obtain AWS SES Email Credentials steps
| Variable Name | Description | Sample Value |
|---|---|---|
| EMAIL_HOST | The SMTP Host address provided by AWS SES | email-smtp.us-east-1.amazonaws.com |
| EMAIL_PORT | The Port provided by AWS SES. Usually 587 | 587 |
| EMAIL_USE_TLS | This should be True | True |
| EMAIL_HOST_USER | The IAM User ID with access to send emails via SES | [A long string] |
| EMAIL_HOST_PASSWORD | The IAM Password for your User | [A long string] |
| DEFAULT_FROM_EMAIL | The email address that site emails should be sent from. Ensure they are an approved email or domain in SES. | no-reply@my-site.ai |
- Set the AI API keys for services you plan to use. (Instructions are not provided on how to obtain these credentials. Refer to their websites)
| Variable Name | Description | Sample Value |
|---|---|---|
| OPENAI_API_KEY | Your OpenAI API key | |
| OPENAI_TTS_API_KEY | An OpenAI API key used specifically for Text-to-Speech, since TTS costs are more variable it is helpful to track with a separate key. Can be the same value as OPENAI_API_KEY | |
| GOOGLE_API_KEY | A Google Gemini API key | |
| ANTHROPIC_API_KEY | An Anthropic Claude API key | |
| PERPLEXITY_API_KEY | A Perplexity API key | |
| DEEPSEEK_API_KEY | A DeepSeek API key | |
| DEFAULT_AI_MODEL | The default AI Model to use when no model is specified |
- Set AWS S3 credentials (for image and file uploads) based on the Obtain S3 Storage Credentials steps.
| Variable Name | Description | Sample Value |
|---|---|---|
| AWS_ACCESS_KEY_ID | The access ID for the AWS IAM user who has access to your bucket | AKIAJXMKFUYBDZ3LM7J |
| AWS_SECRET_ACCESS_KEY | The secret key for the AWS IAM user who has access to your bucket | [long password] |
| AWS_STORAGE_BUCKET_NAME | The name you gave your storage bucket | mysite-uploads |
| AWS_S3_REGION_NAME | The aws region of your bucket. You can find this in your bucket URL or the bucket properties in AWS console | us-east-1 |
| AWS_ACCOUNT_ID | Your AWS account ID (no spaces) | 533212345678 |
- Set Cloudfront Distribution (for serving images and files) based on the Obtain Cloud Distribution Credentials steps
| Variable Name | Description | Sample Value |
|---|---|---|
| CLOUDFRONT_DOMAIN | The URL without a prefix for the cloudfront distribution that will serve assets | d2h8gk38j5ve7k.cloudfront.net |
- Bring up the Docker network that connects the services
docker network create --subnet=172.25.0.0/16 micronet- Make a copy of the appropriate nginx configuration file for your environment
cd /home/ubuntu/micro_ai/nginxcp -rf nginx.prod.conf nginx.conf-
Edit nginx.conf and change any references to old domain names (staging.onmicro.ai; onmicro.ai) to your domain name(s)
-
Build and bring up your containers in production mode
cd /home/ubuntu/micro_aidocker compose -f docker-compose.prod.yml up --build- At this point, you should have five running, healthy containers:
![][image1]
- The first time you run the nginx container, you must get letsencrypt certificates. Follow these steps.
- Make a backup of nginx.conf (e.g. nginx.conf.bck)
- In nginx.conf, remove both 443 blocks, leaving just the 80 block. Your conf file will look something like this:
server { listen 80; server_name [site-name] [site-name];
location /.well-known/acme-challenge/ { root /var/www/certbot; }
location / { return 301 https://$host$request_uri; }}
#Everything below here has been deleted- Build and run the nginx container
docker compose -f docker-compose-nginx.yaml up --build -d- When the nginx container is up and running, run the command in test (staging) mode to request certificates.
docker run --rm \-v "/home/ubuntu/micro_ai/nginx/certbot/conf:/etc/letsencrypt" \-v "/home/ubuntu/micro_ai/nginx/certbot/www:/var/www/certbot" \certbot/certbot certonly \--webroot -w /var/www/certbot \--email [your email] \-d [site name] -d [additional site names, if applicable] \--agree-tos --no-eff-email \--staging- If the test is successful, remove the —staging flag and replace it with —force-renewal to run the command live
docker run --rm \-v "/home/ubuntu/micro_ai/nginx/certbot/conf:/etc/letsencrypt" \-v "/home/ubuntu/micro_ai/nginx/certbot/www:/var/www/certbot" \certbot/certbot certonly \--webroot -w /var/www/certbot \--email [your email] \-d [site name] -d [additional site names, if applicable] \--agree-tos --no-eff-email \--force-renewal- You should now see a series of certificates at /home/ubuntu/micro_ai/nginx/certbot/conf/live/[site-name]. Take note of that site-name.
- Overwrite your temporary nginx.conf with your nginx.conf.bck (the one with 443 blocks).
- Review your nginx.conf file to confirm that your 443 blocks reference the directory with the correct site-name. For example, if your directory is called /home/ubuntu/micro_ai/nginx/certbot/conf/live/my-site.ai then your certificate lines should look like this:
ssl_certificate /etc/letsencrypt/live/my-site.ai/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/my-site.ai/privkey.pem;Obtain AWS SES Email Credentials
Section titled “Obtain AWS SES Email Credentials”AWS SES is the service used to send emails. You will need to set up a host and credentials to send emails from the application via SES.
To get AWS SES credentials for your application, you’ll need to verify your domain, create an SMTP user, and note the correct regional endpoint.
1. Verify Your Domain in SES
Section titled “1. Verify Your Domain in SES”First, you must prove you own the domain you want to send emails from.
- Navigate to the Amazon SES service in your AWS Console.
- In the left menu under Configuration, click Identities.
- Click Create identity, choose Domain, and enter your domain name (e.g.,
example.com).- Alternatively, you may choose Email Address. This is a quicker, simpler verification process but you only get to send from one email address with less deliverability reliability.
- Follow the instructions to add the provided CNAME records to your domain’s DNS settings. It may take some time for AWS to detect these changes and mark the domain as “Verified.”
2. Create SMTP Credentials
Section titled “2. Create SMTP Credentials”Next, create the specific user credentials for sending email via the SMTP protocol.
- In the SES menu, go to SMTP Settings
- From the settings page cllick Create SMTP credentials.
- Follow the wizard for creating new IAM user credentials. An IAM user will be created for you. Click Show user SMTP security credentials to view the SMTP Username (
EMAIL_HOST_USER) and SMTP Password (EMAIL_HOST_PASSWORD). - Important: Copy and save the password immediately. This is the only time it will be displayed.
3. Identify Your Host and Port
Section titled “3. Identify Your Host and Port”Finally, gather the endpoint information for your chosen AWS region.
- In the SES menu click SMTP settings.
- Note the Endpoint name for your region. This is your
EMAIL_HOST. For example,email-smtp.us-east-1.amazonaws.com. - The Port for TLS connections is 587.
4. Choose your From Email
Section titled “4. Choose your From Email”- Your DEFAULT_FROM_EMAIL value can be any email address you want within a verified domain.
- If you only verified a single Email Address in your AWS SES Identities, then you must use that address.
Summary of Credentials
Section titled “Summary of Credentials”EMAIL_HOST: The Endpoint name from the SMTP settings page (e.g.,email-smtp.us-east-1.amazonaws.com).EMAIL_PORT:587EMAIL_HOST_USER: The SMTP Username you created.EMAIL_HOST_PASSWORD: The SMTP Password you created.DEFAULT_FROM_EMAIL: An Email address from an approved domain in your AWS SES Identities.
Obtain S3 Storage Credentials
Section titled “Obtain S3 Storage Credentials”- In AWS, create a bucket that will store your static files.
- Give it a name
- E.g. “onmicro-dev”
- Modify the CORS policy to allow any URLs you expect to use:
- Give it a name
[ { "AllowedHeaders": [ "*" ], "AllowedMethods": [ "GET", "POST", "PUT", "DELETE", "HEAD" ], "AllowedOrigins": [ "http://localhost", "http://localhost:3000", "https://onmicro.ai", "https://dev.onmicro.ai" ], "ExposeHeaders": [ "ETag" ], "MaxAgeSeconds": 3000 }]- In AWS, create an IAM user that has access to your bucket.
- This the policy that I use:
{ "Version": "2012-10-17", "Statement": [ { "Sid": "VisualEditor0", "Effect": "Allow", "Action": [ "s3:PutObject", "s3:GetObject", "s3:ListBucket", "s3:DeleteObject" ], "Resource": [ "arn:aws:s3:::[bucket-name]", "arn:aws:s3:::[bucket-name]/*" ] } ]}-
Capture your IAM user’s AWS Access Key and Secret Access Key for use later
-
Summary of Credentials
AWS_ACCESS_KEY_ID: The access key ID from your IAM user credentials.AWS_SECRET_ACCESS_KEY: The secret access key from your IAM user credentials.AWS_STORAGE_BUCKET_NAME: The name of your S3 bucket.AWS_S3_REGION_NAME: The AWS region where your S3 bucket is located (e.g.,us-east-1).AWS_ACCOUNT_ID: Your 12-digit AWS account ID.
Obtain Cloud Distribution Credentials
Section titled “Obtain Cloud Distribution Credentials”- Create a CloudFront Distribution
- In the AWS Console, navigate to CloudFront and create a new distribution.
- Under Origin, set:
- Origin Type: S3 bucket
- Origin Domain: Select your S3 bucket
- Origin Access: Choose Origin Access Control Settings (OAC) and create a new OAC.
- Bucket Policy: Allow CloudFront to access your bucket by updating its permissions when prompted.
- Under Default Cache Behavior, set:
- Viewer Protocol Policy: Redirect HTTP to HTTPS.
- Allowed HTTP Methods: GET, HEAD (for static asset retrieval).
- Cache Policy: Use an appropriate caching policy (e.g., CachingOptimized).
- Click Create Distribution and wait for deployment.
- Update Your S3 Bucket Policy
- If you do it correctly, you’ll be given the correct policy code when you create the Cloudfront distribution. But it looks like this:
{ "Version": "2012-10-17", "Statement": [ { "Sid": "AllowCloudFrontServicePrincipalReadOnly", "Effect": "Allow", "Principal": { "Service": "cloudfront.amazonaws.com" }, "Action": "s3:GetObject", "Resource": "arn:aws:s3:::[bucket-name]/*", "Condition": { "StringEquals": { "AWS:SourceArn": "arn:aws:cloudfront::[AWS_ACCOUNT_ID]:distribution/[CLOUDFRONT_DISTRIBUTION_ID]" } } } ]}-
Replace [bucket-name], [AWS_ACCOUNT_ID], and [CLOUDFRONT_DISTRIBUTION_ID] with your actual values.
-
Once deployed, retrieve and save your Distribution domain name (e.g.a1b2cd34e5fg6h.cloudfront.net)
-
Summary of Credentials
CLOUDFRONT_DOMAIN: The URL without a prefix for the cloudfront distribution that will serve assets