This repository is a URL shortener demo. It uses:
- Rails 8
- PostgreSQL
- Sidekiq
- Redis
- Kamal for deployment
The easiest way to run the app locally is in the included devcontainer.
- Open the repository in VS Code.
- Choose
Dev Containers: Reopen in Container. - Wait for the container to build. The devcontainer runs
bin/setup --skip-serverafter creation, which installs gems and prepares the database. - Copy the sample environment file:
cp .example.env .env- Copy
.example.envto.envfor local development:
cp .example.env .envThen fill your own environment variables.
- Start the app:
bin/devbin/dev starts:
- the Rails web server on port
3000 - Tailwind in watch mode
- Sidekiq
The devcontainer forwards port 3000, so the app should be available at http://localhost:3000.
Copy .example.env to .env for local development:
cp .example.env .envThe sample file includes:
SECRET_KEY_BASE: Rails secret for cookies and encrypted dataDB_NAME: base PostgreSQL database nameDB_HOST: database host, which should staypostgresin the devcontainerDB_USERNAME: PostgreSQL usernameDB_PASSWORD: PostgreSQL passwordREDIS_URL: Redis connection string used by Sidekiq and the Rails cache, the hostname should stayredis
Because config/database.yml derives multiple databases from DB_NAME, Rails will create names like:
<DB_NAME><DB_NAME>_cache<DB_NAME>_queue<DB_NAME>_cable<DB_NAME>_test
Kamal reads secrets from .kamal/secrets. In this project, that file maps secret names to environment variables:
KAMAL_REGISTRY_PASSWORDSECRET_KEY_BASEDB_NAMEDB_USERNAMEDB_PASSWORD
deploy.sh.example is a template wrapper around Kamal. Copy it to deploy.sh, replace the placeholder values, and keep the real file out of version control in .gitignore.
cp deploy.sh.example deploy.sh
chmod +x deploy.shIt exports the environment variables Kamal needs. First commit your changes if any, then run one of two commands:
./deploy.sh setup: first-time server setup, it installs Docker on your server, pulls and boots the accessory containers (Redis and PostgreSQL)../deploy.sh deploy: build and deploy a new release after each change, any new changes must be committed first.
.example.env is only for local development. It is not used directly by Kamal deploys, but it documents the same application-level values you will also provide during deployment.
config/deploy.yml is the main Kamal configuration file.
service: names the deployed applicationimage: Docker image repository to build and pushasset_path: path where Rails assets are served from in the containerservers: defines the machines running the web process and the Sidekiq processproxy: enables HTTPS and tells Kamal which domain should route to the appregistry: configures the container registry credentials; the password comes fromKAMAL_REGISTRY_PASSWORDenv.clear: non-secret environment variables passed to the containersenv.secret: secret environment variables loaded through.kamal/secretsvolumes: persistent Docker volumes, here used for Active Storage filesbuilder: remote Docker build settings, including target architecture and Ruby version build argaccessories: supporting services deployed alongside the app, here PostgreSQL and Redisaliases: convenience commands for common Kamal tasks like logs, console, and migrations
Before deploying, update these placeholders in config/deploy.yml:
<dockerhub-username><server-ip-address-or-hostname><domain-name>
You should also make sure the following values are consistent across config/deploy.yml, .kamal/secrets, and your deployment script:
- Docker registry credentials
- database name and credentials
SECRET_KEY_BASE- app hostnames