Last active
May 17, 2025 13:01
-
-
Save mickzijdel/2c5d1ab56b80f9b5a5ac1f0f7e634f4a to your computer and use it in GitHub Desktop.
Example files for https://mickzijdel.com/blog/2025-05-17-how-to-set-up-a-postgres-database-accessory-container-with-kamal-2-in-ruby-on-rails
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # Existing content.. | |
| # Ignore master key for decrypting credentials and more. | |
| /config/master.key | |
| /config/credentials/* |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # config/database.yml | |
| # PostgreSQL. Versions 9.3 and up are supported. | |
| # | |
| # Install the pg driver: | |
| # gem install pg | |
| # On macOS with Homebrew: | |
| # gem install pg -- --with-pg-config=/usr/local/bin/pg_config | |
| # On Windows: | |
| # gem install pg | |
| # Choose the win32 build. | |
| # Install PostgreSQL and put its /bin directory on your path. | |
| # | |
| # Configure Using Gemfile | |
| # gem "pg" | |
| # | |
| # Warning: This is different from the default, even though it does not affect production. | |
| # I prefer storing my development database credentials in the Rails credentials, but use whatever method you prefer. | |
| default: &default | |
| adapter: postgresql | |
| encoding: unicode | |
| # For details on connection pooling, see Rails configuration guide | |
| # https://guides.rubyonrails.org/configuring.html#database-pooling | |
| pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %> | |
| username: <%= Rails.application.credentials.dig(:database, :username) %> | |
| password: <%= Rails.application.credentials.dig(:database, :password) %> | |
| host: localhost | |
| development: | |
| <<: *default | |
| database: <your-service-name>_development | |
| # The TCP port the server listens on. Defaults to 5432. | |
| # If your server runs on a different port number, change accordingly. | |
| #port: 5432 | |
| # Schema search path. The server defaults to $user,public | |
| #schema_search_path: myapp,sharedapp,public | |
| # Minimum log levels, in increasing order: | |
| # debug5, debug4, debug3, debug2, debug1, | |
| # log, notice, warning, error, fatal, and panic | |
| # Defaults to warning. | |
| #min_messages: notice | |
| # Warning: The database defined as "test" will be erased and | |
| # re-generated from your development database when you run "rake". | |
| # Do not set this db to the same as development or production. | |
| test: | |
| <<: *default | |
| database: <your-service-name>_test | |
| # As with config/credentials.yml, you never want to store sensitive information, | |
| # like your database password, in your source code. If your source code is | |
| # ever seen by anyone, they now have access to your database. | |
| # | |
| # Instead, provide the password or a full connection URL as an environment | |
| # variable when you boot the app. For example: | |
| # | |
| # DATABASE_URL="postgres://myuser:mypass@localhost/somedatabase" | |
| # | |
| # If the connection URL is provided in the special DATABASE_URL environment | |
| # variable, Rails will automatically merge its configuration values on top of | |
| # the values provided in this file. Alternatively, you can specify a connection | |
| # URL environment variable explicitly: | |
| # | |
| # production: | |
| # url: <%= ENV["MY_APP_DATABASE_URL"] %> | |
| # | |
| # Read https://guides.rubyonrails.org/configuring.html#configuring-a-database | |
| # for a full overview on how database connection configuration can be specified. | |
| # | |
| production: | |
| primary: &primary_production | |
| <<: *default | |
| username: <%= ENV["POSTGRES_USER"] %> | |
| database: <%= ENV["POSTGRES_DB"] %> | |
| password: <%= ENV["POSTGRES_PASSWORD"] %> | |
| host: <%= ENV["DB_HOST"] %> | |
| port: 5432 | |
| cache: | |
| <<: *primary_production | |
| database: <%= ENV["POSTGRES_DB"] %>_cache | |
| migrations_paths: db/cache_migrate | |
| queue: | |
| <<: *primary_production | |
| database: <%= ENV["POSTGRES_DB"] %>_queue | |
| migrations_paths: db/queue_migrate | |
| cable: | |
| <<: *primary_production | |
| database: <%= ENV["POSTGRES_DB"] %>_cable | |
| migrations_paths: db/cable_migrate |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # config/deploy.yml | |
| # Name of your application. Used to uniquely configure containers. | |
| service: <your-service-name> | |
| # Name of the container image. | |
| # <your-user> is your Docker Hub username or the username for your private registry. | |
| image: <your-user>/<your-service-name> | |
| # Deploy to these servers. | |
| servers: | |
| web: | |
| - <your-server-ip> | |
| # job: | |
| # hosts: | |
| # - 192.168.0.1 | |
| # cmd: bin/jobs | |
| # Enable SSL auto certification via Let's Encrypt and allow for multiple apps on a single web server. | |
| # Remove this section when using multiple web servers and ensure you terminate SSL at your load balancer. | |
| # | |
| # Note: If using Cloudflare, set encryption mode in SSL/TLS setting to "Full" to enable CF-to-app encryption. | |
| proxy: | |
| ssl: true | |
| host: app.example.com | |
| # Credentials for your image host. | |
| registry: | |
| # Specify the registry server, if you're not using Docker Hub | |
| # server: registry.digitalocean.com / ghcr.io / ... | |
| username: <your-user> | |
| # Always use an access token rather than real password when possible. | |
| password: | |
| - KAMAL_REGISTRY_PASSWORD | |
| # Inject ENV variables into containers (secrets come from .kamal/secrets). | |
| env: | |
| secret: | |
| - RAILS_MASTER_KEY | |
| - POSTGRES_PASSWORD | |
| clear: | |
| # Run the Solid Queue Supervisor inside the web server's Puma process to do jobs. | |
| # When you start using multiple servers, you should split out job processing to a dedicated machine. | |
| SOLID_QUEUE_IN_PUMA: true | |
| DB_HOST: <your-service-name>-postgres | |
| POSTGRES_USER: <your-service-name> | |
| POSTGRES_DB: <your-service-name>_production | |
| # Set number of processes dedicated to Solid Queue (default: 1) | |
| # JOB_CONCURRENCY: 3 | |
| # Set number of cores available to the application on each server (default: 1). | |
| # WEB_CONCURRENCY: 2 | |
| # Log everything from Rails | |
| # RAILS_LOG_LEVEL: debug | |
| # Aliases are triggered with "bin/kamal <alias>". You can overwrite arguments on invocation: | |
| # "bin/kamal logs -r job" will tail logs from the first server in the job section. | |
| aliases: | |
| console: app exec --interactive --reuse "bin/rails console" | |
| shell: app exec --interactive --reuse "bash" | |
| logs: app logs -f | |
| dbc: app exec --interactive --reuse "bin/rails dbconsole" | |
| # Use a persistent storage volume for sqlite database files and local Active Storage files. | |
| # Recommended to change this to a mounted volume path that is backed up off server. | |
| volumes: | |
| - "<your-service-name>_storage:/rails/storage" | |
| # Bridge fingerprinted assets, like JS and CSS, between versions to avoid | |
| # hitting 404 on in-flight requests. Combines all files from new and old | |
| # version inside the asset_path. | |
| asset_path: /rails/public/assets | |
| # Configure the image builder. | |
| builder: | |
| arch: amd64 | |
| # # Build image via remote server (useful for faster amd64 builds on arm64 computers) | |
| # remote: ssh://docker@docker-builder-server | |
| # | |
| # # Pass arguments and secrets to the Docker build process | |
| # args: | |
| # RUBY_VERSION: ruby-3.4.1 | |
| # secrets: | |
| # - GITHUB_TOKEN | |
| # - RAILS_MASTER_KEY | |
| # Use a different ssh user than root | |
| ssh: | |
| user: deploy | |
| # Use accessory services (secrets come from .kamal/secrets). | |
| accessories: | |
| postgres: | |
| image: postgres:15 | |
| host: <your-server-ip> | |
| # If you define a port here, that port will be accessible from the host machine. | |
| # This means that you cannot use the same port for multiple services/accessories. | |
| # This will cause issues if you have multiple services with a postgres accessory, | |
| # and you will need to modify which port each accessory uses by modifying the number before the :. | |
| # You can still access the database using `<your-service-name>-psotgres` as the hostname and `5432` as the port | |
| # regardless of which port you expose here. | |
| # Warning: If you remove the `127.0.0.1` part, this port is exposed to the world. | |
| # port: "127.0.0.1:5432:5432" | |
| env: | |
| clear: | |
| # Make sure this perfectly matches the POSTGRES_USER value defined above in the env section. | |
| POSTGRES_USER: <your-service-name> | |
| secret: | |
| - POSTGRES_PASSWORD | |
| files: | |
| - db/production_setup.sql:/docker-entrypoint-initdb.d/setup.sql | |
| directories: | |
| - data:/var/lib/postgresql/data | |
| # redis: | |
| # image: redis:7.0 | |
| # host: 192.168.0.2 | |
| # port: 6379 | |
| # directories: | |
| # - data:/data |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # Add this before rails assets:precompile at roughly line 48 (in Rails 8.0.2) | |
| # Adjust binfiles to be executable on Linux | |
| RUN chmod +x bin/* && \ | |
| sed -i "s/\r$//g" bin/* && \ | |
| sed -i 's/ruby\.exe$/ruby/' bin/* | |
| # EXISTING: | |
| # Precompiling assets for production without requiring secret RAILS_MASTER_KEY | |
| RUN SECRET_KEY_BASE_DUMMY=1 ./bin/rails assets:precompile |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| -- db/production_setup.sql | |
| CREATE DATABASE <your-service-name>_production; | |
| CREATE DATABASE <your-service-name>_production_cache; | |
| CREATE DATABASE <your-service-name>_production_queue; | |
| CREATE DATABASE <your-service-name>_production_cable; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # .kamal/secrets | |
| # Secrets defined here are available for reference under registry/password, env/secret, builder/secrets, | |
| # and accessories/*/env/secret in config/deploy.yml. All secrets should be pulled from either | |
| # password manager, ENV, or a file. DO NOT ENTER RAW CREDENTIALS HERE! This file needs to be safe for git. | |
| # Example of extracting secrets from 1password (or another compatible pw manager) | |
| # SECRETS=$(kamal secrets fetch --adapter 1password --account your-account --from Vault/Item KAMAL_REGISTRY_PASSWORD RAILS_MASTER_KEY) | |
| # KAMAL_REGISTRY_PASSWORD=$(kamal secrets extract KAMAL_REGISTRY_PASSWORD ${SECRETS}) | |
| # RAILS_MASTER_KEY=$(kamal secrets extract RAILS_MASTER_KEY ${SECRETS}) | |
| # Use a GITHUB_TOKEN if private repositories are needed for the image | |
| # GITHUB_TOKEN=$(gh config get -h github.com oauth_token) | |
| # Grab the registry password from ENV | |
| KAMAL_REGISTRY_PASSWORD=$KAMAL_REGISTRY_PASSWORD | |
| # or if you followed my file-based setup: | |
| # KAMAL_REGISTRY_PASSWORD=$(cat config/credentials/kamal_registry_password.key) | |
| # Improve security by using a password manager. Never check config/master.key into git! | |
| RAILS_MASTER_KEY=$(cat config/master.key) | |
| POSTGRES_PASSWORD=$(cat config/credentials/postgres.key) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment