Last active
March 4, 2025 08:23
-
-
Save lcorneliussen/a6384d8b9ea84d06b8a367f579f81ed0 to your computer and use it in GitHub Desktop.
BT docker setup
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
| .... | |
| deploy: | |
| name: 🚢 Deploy to Production | |
| needs: [minitest, standardrb, db_schema] | |
| runs-on: ubuntu-latest | |
| env: | |
| DOCKER_BUILDKIT: 1 | |
| RAILS_ENV: production | |
| RAILS_MASTER_KEY: ${{ secrets.RAILS_MASTER_KEY }} | |
| KAMAL_REGISTRY_PASSWORD: ${{ secrets.KAMAL_REGISTRY_PASSWORD }} | |
| POSTGRES_PASSWORD: ${{ secrets.POSTGRES_PASSWORD }} | |
| SECRET_KEY_BASE: ${{ secrets.SECRET_KEY_BASE }} | |
| REDIS_PASSWORD: ${{ secrets.REDIS_PASSWORD }} | |
| HONEYBADGER_API_KEY: ${{ secrets.HONEYBADGER_API_KEY }} | |
| POSTMARK_API_TOKEN: ${{ secrets.POSTMARK_API_TOKEN }} | |
| GOOGLE_MAPS_API_KEY: ${{ secrets.GOOGLE_MAPS_API_KEY }} | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: ruby/setup-ruby@v1 | |
| with: | |
| bundler-cache: true | |
| - name: Install Kamal | |
| run: gem install kamal | |
| - uses: webfactory/ssh-agent@v0.9.0 | |
| with: | |
| ssh-private-key: ${{ secrets.SSH_PRIVATE_KEY }} | |
| - name: Set up Docker Buildx for cache | |
| uses: docker/setup-buildx-action@v3 | |
| - name: Remove existing SECRETS line from .kamal/secrets | |
| run: sed -i '/^SECRETS=/d' .kamal/secrets | |
| - name: Update environment variables in .kamal/secrets | |
| run: sed -i 's/^\([A-Z_]*\)=.*/\1=$\1/' .kamal/secrets | |
| - name: Check Kamal version | |
| run: kamal version | |
| - name: Free up disk space | |
| run: kamal prune all | |
| - name: Login to Docker registry | |
| run: kamal registry login --verbose | |
| - name: Release deployment lock | |
| run: kamal lock release --verbose | |
| - name: Deploy application | |
| run: kamal redeploy --verbose |
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
| SECRETS=$(kamal secrets fetch --adapter 1password --account ,,,, --from MyApp/KamalSecrets KAMAL_REGISTRY_PASSWORD RAILS_MASTER_KEY POSTGRES_PASSWORD SECRET_KEY_BASE REDIS_PASSWORD HONEYBADGER_API_KEY POSTMARK_API_TOKEN GOOGLE_MAPS_API_KEY) | |
| KAMAL_REGISTRY_PASSWORD=$(kamal secrets extract KAMAL_REGISTRY_PASSWORD $SECRETS) | |
| RAILS_MASTER_KEY=$(kamal secrets extract RAILS_MASTER_KEY $SECRETS) | |
| POSTGRES_PASSWORD=$(kamal secrets extract POSTGRES_PASSWORD $SECRETS) | |
| SECRET_KEY_BASE=$(kamal secrets extract SECRET_KEY_BASE $SECRETS) | |
| REDIS_PASSWORD=$(kamal secrets extract REDIS_PASSWORD $SECRETS) | |
| HONEYBADGER_API_KEY=$(kamal secrets extract HONEYBADGER_API_KEY $SECRETS) | |
| POSTMARK_API_TOKEN=$(kamal secrets extract POSTMARK_API_TOKEN $SECRETS) | |
| GOOGLE_MAPS_API_KEY=$(kamal secrets extract GOOGLE_MAPS_API_KEY $SECRETS) |
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
| service: bt-app | |
| # Name of the container image. | |
| image: bt-app/bt-app | |
| # https://guillaumebriday.fr/how-to-deploy-rails-with-kamal-postgresql-sidekiq-and-backups-on-a-single-host | |
| # Deploy to these servers. | |
| servers: | |
| web: | |
| hosts: | |
| - <serverip> | |
| job: | |
| hosts: | |
| - <serverip> | |
| cmd: bundle exec sidekiq | |
| # Enable SSL auto certification via Let's Encrypt (and allow for multiple apps on one server). | |
| # Set ssl: false if using something like Cloudflare to terminate SSL (but keep host!). | |
| proxy: | |
| ssl: true | |
| host: <host> | |
| healthcheck: | |
| interval: 12 | |
| timeout: 5 | |
| # Credentials for your image host. | |
| registry: | |
| # Specify the registry server, if you're not using Docker Hub | |
| server: ghcr.io | |
| username: my-user | |
| # Always use an access token rather than real password (pulled from .kamal/secrets). | |
| password: | |
| - KAMAL_REGISTRY_PASSWORD | |
| # Configure builder setup. | |
| builder: | |
| arch: amd64 | |
| args: | |
| NODE_OPTIONS: "--max-old-space-size=4096" | |
| BUNDLE_BUILD__WDM: "--with-cflags=-Wno-implicit-function-declaration" | |
| cache: | |
| type: registry | |
| # Inject ENV variables into containers (secrets come from .kamal/secrets). | |
| env: | |
| clear: | |
| POSTGRES_HOST: 'bt-app-postgres17' | |
| POSTGRES_PORT: '5432' | |
| REDIS_HOST: 'bt-app-redis' | |
| RAILS_ENV: 'production' | |
| RAILS_SERVE_STATIC_FILES: 'true' | |
| RAILS_LOG_TO_STDOUT: 'true' | |
| APP_HOST: '<host>' | |
| DEVELOPER_EMAILS: '...' | |
| HIDE_THINGS: 'true' | |
| secret: | |
| - SECRET_KEY_BASE | |
| - REDIS_PASSWORD | |
| - POSTGRES_PASSWORD | |
| - HONEYBADGER_API_KEY | |
| - POSTMARK_API_TOKEN | |
| - GOOGLE_MAPS_API_KEY | |
| volumes: | |
| - "app_storage:/app/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: /app/public/assets | |
| # Configure rolling deploys by setting a wait time between batches of restarts. | |
| # | |
| # boot: | |
| # limit: 10 # Can also specify as a percentage of total hosts, such as "25%" | |
| # wait: 2 | |
| # Use accessory services (secrets come from .kamal/secrets). | |
| # | |
| accessories: | |
| postgres17: | |
| image: postgis/postgis:17-3.4 | |
| roles: | |
| - web | |
| - job | |
| env: | |
| clear: | |
| POSTGRES_USER: "..." | |
| POSTGRES_DB: "..." | |
| secret: | |
| - POSTGRES_PASSWORD | |
| port: 5433 | |
| files: | |
| - config/init.sql:/docker-entrypoint-initdb.d/setup.sql | |
| directories: | |
| - data:/var/lib/postgresql/data | |
| redis: | |
| image: redis:7.0 | |
| port: 6379 | |
| roles: | |
| - web | |
| - job | |
| cmd: "/bin/sh -c 'redis-server --requirepass $REDIS_PASSWORD'" | |
| volumes: | |
| - /var/lib/redis:/data | |
| env: | |
| secret: | |
| - REDIS_PASSWORD |
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
| name: bt-app | |
| services: | |
| db: | |
| image: postgis/postgis:17-3.4 | |
| restart: always | |
| volumes: | |
| - ./storage/db:/var/lib/postgresql/data | |
| environment: | |
| - POSTGRES_USER=localdev | |
| - POSTGRES_PASSWORD=localdev | |
| ports: | |
| - "5432:5432" | |
| healthcheck: | |
| test: ["CMD-SHELL", "pg_isready -U localdev"] | |
| interval: 1s | |
| timeout: 5s | |
| retries: 10 | |
| redis: | |
| image: redis:alpine | |
| restart: always | |
| ports: | |
| - "6379:6379" | |
| volumes: | |
| - ./storage/redis:/data | |
| healthcheck: | |
| test: ["CMD", "redis-cli", "ping"] | |
| interval: 1s | |
| timeout: 3s | |
| retries: 30 |
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
| # syntax = docker/dockerfile:1 | |
| # Make sure RUBY_VERSION matches the Ruby version in .ruby-version and Gemfile | |
| ARG RUBY_VERSION=3.4.1 | |
| FROM ruby:$RUBY_VERSION-slim AS base | |
| # Rails app lives here | |
| WORKDIR /rails | |
| # Set production environment | |
| ENV BUNDLE_DEPLOYMENT="1" \ | |
| BUNDLE_PATH="/usr/local/bundle" \ | |
| BUNDLE_WITHOUT="development:test" \ | |
| RAILS_ENV="production" | |
| # Update gems and bundler | |
| RUN gem update --system --no-document && \ | |
| gem install -N bundler | |
| # Install packages needed to install nodejs and charlock_holmes | |
| RUN apt-get update -qq && \ | |
| apt-get install --no-install-recommends -y curl libicu-dev && \ | |
| rm -rf /var/lib/apt/lists /var/cache/apt/archives | |
| # Install Node.js | |
| ARG NODE_VERSION=22.12.0 | |
| ENV PATH=/usr/local/node/bin:$PATH | |
| RUN curl -sL https://github.com/nodenv/node-build/archive/master.tar.gz | tar xz -C /tmp/ && \ | |
| /tmp/node-build-master/bin/node-build "${NODE_VERSION}" /usr/local/node && \ | |
| rm -rf /tmp/node-build-master | |
| # Throw-away build stage to reduce size of final image | |
| FROM base AS build | |
| # Install packages needed to build gems and node modules | |
| RUN apt-get update -qq && \ | |
| apt-get install --no-install-recommends -y build-essential libpq-dev libvips node-gyp pkg-config python-is-python3 git | |
| # Install yarn | |
| ARG YARN_VERSION=4.2.2 | |
| RUN corepack enable && \ | |
| corepack prepare yarn@$YARN_VERSION --activate | |
| # Build options | |
| ENV PATH="/usr/local/node/bin:$PATH" | |
| # Install application gems | |
| COPY Gemfile Gemfile.lock .ruby-version ./ | |
| RUN bundle install --jobs=1 | |
| RUN bundle exec bootsnap precompile --Gemfile | |
| RUN rm -rf ~/.bundle/ "${BUNDLE_PATH}"/ruby/*/cache "${BUNDLE_PATH}"/ruby/*/bundler/gems/*/.git | |
| # Install node modules | |
| COPY package.json yarn.lock ./ | |
| RUN yarn install --immutable | |
| # Copy application code | |
| COPY . . | |
| # Precompile bootsnap code for faster boot times | |
| RUN bundle exec bootsnap precompile app/ lib/ | |
| # Precompiling assets for production without requiring secret RAILS_MASTER_KEY | |
| RUN SECRET_KEY_BASE_DUMMY=1 ./bin/rails assets:precompile | |
| # Final stage for app image | |
| FROM base | |
| # Install packages needed for deployment | |
| RUN apt-get update -qq && \ | |
| apt-get install --no-install-recommends -y curl imagemagick libvips postgresql-client && \ | |
| rm -rf /var/lib/apt/lists /var/cache/apt/archives | |
| # Copy built artifacts: gems, application | |
| COPY --from=build "${BUNDLE_PATH}" "${BUNDLE_PATH}" | |
| COPY --from=build /rails /rails | |
| # Run and own only the runtime files as a non-root user for security | |
| RUN groupadd --system --gid 1000 rails && \ | |
| useradd rails --uid 1000 --gid 1000 --create-home --shell /bin/bash && \ | |
| mkdir -p /rails/storage && \ | |
| mkdir -p /rails/tmp/pids && \ | |
| chown -R 1000:1000 db log storage tmp | |
| USER 1000:1000 | |
| # Entrypoint prepares the database. | |
| ENTRYPOINT ["/rails/bin/docker-entrypoint"] | |
| # Start the server by default, this can be overwritten at runtime | |
| #ENV PORT=80 | |
| EXPOSE 80 | |
| CMD ["bundle", "exec", "thrust", "./bin/rails", "server"] |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment