This is a good way to set up a full stack production-like learning environment, at a very low cost or for free. Once you know how to do this stuff, you can learn how to host your own hardware, too—but there's not way to do that just yet (actually, that'd be a fun project—make a game that uses up-to-date data about options for configuring data centers and common issues and then have gamers try to solve those problems as they scale).
This guide is an amalgamation of various guides, picking and choosing specific things I wanted from them.
1. Log in to AWS: AWS Management Console
2. Launch an Instance:
— Navigate to EC2 under the “Services” tab.
— Click Launch Instance.
3. Select AMI: Choose Ubuntu Server (recommended for Rails deployments).
4. Choose Instance Type: Select `t2.small` for a small app (not in free tier) or a larger instance for higher resource needs. You'll need over 1GB ram for our production server hardening script.
5. Configure Instance:
— Keep the default settings but ensure to configure security groups to allow HTTP, HTTPS, and SSH access.
6. Add Storage: The default 8GB is fine for small applications, but for our production server hardening script we need a minimum of 20GB.
7. Launch: Click Review and Launch. You will need to create a key pair to securely access the instance.
— Make sure to download and keep your private key (`.pem` file) safe, as you’ll need it to SSH into the server.
Step 2: Connect to Your EC2 Instance
Once your EC2 instance is up and running, you’ll need to connect to it.
1. Open Terminal (or any SSH client).
2. SSH into the Instance
# You should change the permissions of the pem file for security reasons:
chmod 400 path_to_your_pem_file.pem
# I would move the file to the ssh foldermv path_to_your_pem_file.pem ~/.ssh ssh -i ~/.ssh/your_pem_file.pem ubuntu@your_instance_ip# Replace `your_pem_file.pem` with the name of your downloaded key and `your_instance_ip` with your EC2 instance’s public IP.
Step 3: Install Ruby, Rails, and Dependencies
With your EC2 instance connected, it’s time to install Ruby and Rails. Technically you don't have to do this, but it's nice to be able to just ssh in to the server and do stuff outside of containers. Plus, this gives you an idea of how you'd want to configure a container anyway.
# update the systemsudo apt-get updatesudo apt-get upgrade
# install gpg for checking the integrity of executablessudo apt-get install curl gpg
# Harden the installation
# Note: it’s good practice to always check scripts you find on the internet before you run them. Make sure they don’t do things you don’t want them to do. For example, ask Claude / ChatGPT to review and explain my script for you.
wget
# More on why to use this here.
https://gist.githubusercontent.com/rameerez/238927b78f9108a71a77aed34208de11/raw/ef147c61ef246b3420d1c335f92b795a681a9c20/kamal-production-server-setup.sh
chmod +x kamal-production-server-setup.sh
./kamal-production-server-setup.sh
# install RVM (ruby environment manager)
curl -sSL https://get.rvm.io | bash -s stable
# you may run into a signature verification error and have to run an additional command like
gpg --keyserver hkp://keyserver.ubuntu.com --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 7D2BAF1CF37B13E2069D6956105BD0E739499BDB
# if you had to do that, then run RVM install again
curl -sSL https://get.rvm.io | bash -s stable
# install rustc for yjit and jamelloc
# from: https://acavalin.com/p/rvm_install_ruby_with_jemalloc_yjit
sudo apt-get install rustc # needed by YJIT
sudo apt-get install libjemalloc-dev # needed by jemalloc
# install latest ruby version (3.3.7 at time of writing)
rvm install ruby-3.3.7 -C --with-jemalloc --enable-yjit# this may take awhile…it took me about 10 minutes
# jemalloc test 1MALLOC_CONF=stats_print:true rvm 3.3.7 do ruby -e "exit"
# jemalloc test 2ldd `which ruby` | grep jemalloc# => libjemalloc.so.2 => /lib/x86_64-linux-gnu/libjemalloc.so.2 (0x0000735e89a00000)
# YJIT testruby --yjit -v# => ruby 3.3.7 (2025-01-15 revision be31f993d7) +YJIT [x86_64-linux]
# Install Railsgem install rails
# If you’re going to use only importmaps referring to external javascript you don’t need to do this, but most people end up hosting some js packages on their server, so:
sudo apt-get install -y nodejssudo apt-get install -y yarn
# You’ll need a database, let’s use Postgres
sudo apt-get install postgresql postgresql-contrib libpq-dev
# create a user and password
sudo -u postgres psql
CREATE USER myuser WITH PASSWORD 'mypassword';ALTER ROLE myuser CREATEDB;\q
Now you’re ready to start a rails app and just play around or get started with Kamal and Docker. Versions of the above are useful for creating your own /run scripts like this
docker-rails-example.