Hetzner에서 Kamal과 함께 Rails 8을 배포하기 위한 전체 가이드
hackernews
|
|
📰 뉴스
#hetzner
#kamal
#rails 8
#solid stack
#tip
#배포
원문 출처: hackernews · Genesis Park에서 요약 및 분석
요약
이 가이드는 Hetzner 전용 서버에 Kamal을 사용하여 Solid 스택을 채택한 Rails 8 애플리케이션을 배포하는 과정을 단계별로 설명합니다. 기사는 서버 주문, Ubuntu 24.04 설치, 그리고 SSH와 HTTP/HTTPS 트래픽을 위한 방화벽 설정 방법을 다룹니다. 또한 Docker 설치 및 보안 강화를 자동화하기 위해 Ansible 플레이북을 활용하고, Ruby 3.4 기반의 프로덕션 Dockerfile을 구성하는 방법을 제시합니다. 이를 통해 백그라운드 작업과 모니터링이 포함된 안정적인 운영 환경을 구축할 수 있습니다.
본문
This is a complete, end-to-end guide to deploying a Rails 8 application with the Solid stack using Kamal on a Hetzner dedicated server. We will go from ordering a server to running your app in production with background jobs, backups, and monitoring. Assumptions: You have a Rails 8 application ready to deploy. Your app uses SQLite with the Solid stack (Solid Queue, Solid Cache, Solid Cable) â the default for new Rails 8 apps. Server requirements: A dedicated server or VPS with at least 2 GB of RAM. We will use Hetzner, but these instructions work with any provider (DigitalOcean, Vultr, OVH, etc.) â you just need a server running Ubuntu with SSH access. Getting a Server on Hetzner Hetzner offers auction servers starting around 36 EUR/month. These are dedicated hardware â not shared VPS â with plenty of CPU, RAM, and storage. For a Rails app running the Solid stack, this is more than enough. When ordering your server, make sure to add your SSH public key so you can log in immediately once it is provisioned. Once your server is ready, log into Hetzner Robot and select your server. Click the Linux tab. We will reinstall the OS with a clean Ubuntu 24.04 LTS base. Select it from the list, choose your SSH public key, and click Activate Linux Installation. The installation does not start automatically â you need to SSH into the server and reboot it: ssh [email protected] reboot The server will reinstall Ubuntu and come back online in a few minutes. Setting Up the Hetzner Firewall While we wait for the OS installation to complete, let us configure the firewall. In Hetzner Robot, go to your server and click the Firewall tab. Add the following incoming rules: | # | Name | Version | Protocol | Source IP | Dest IP | Dest Port | TCP Flags | Action | |---|---|---|---|---|---|---|---|---| | 1 | Outgoing TCP | ipv4 | tcp | 0.0.0.0/0 | 0.0.0.0/0 | 32768-65535 | ack | accept | | 2 | ssh | ipv4 | tcp | Â | Â | 22 | syn/ack | accept | | 3 | http | ipv4 | tcp | Â | Â | 80 | syn/ack | accept | | 4 | https | ipv4 | tcp | Â | Â | 443 | syn/ack | accept | Leave everything else blank and click Save. The first rule allows outgoing TCP responses (needed for your server to respond to requests). The remaining three open SSH, HTTP, and HTTPS. Setting Up Ansible With the server ready, we need to install Docker, configure the firewall (on the OS level), harden SSH, and set up a few other things. You could do this manually, but Ansible makes it repeatable and documented. First, install Ansible on your local machine: # macOS brew install ansible # Ubuntu/Debian sudo apt install ansible We will use kamal-ansible-manager, an excellent Ansible playbook by Guillaume Briday that automates server provisioning specifically for Kamal deployments. It is idempotent â safe to run multiple times â and handles everything your server needs. Clone it into your project: git clone https://github.com/guillaumebriday/kamal-ansible-manager config/ansible cd config/ansible Set up the inventory file with your server IP: cp hosts.ini.example hosts.ini Edit hosts.ini : [webservers:vars] ansible_become_method=su ansible_user=root [webservers] 203.0.113.10 Install the Ansible requirements (community roles for swap, firewall, etc.): ansible-galaxy install -r requirements.yml Now run the playbook: ANSIBLE_HOST_KEY_CHECKING=False ansible-playbook -i hosts.ini playbook.yml This will take a few minutes. Here is what the playbook does: - Docker â Installs Docker CE from the official Docker repository. Kamal needs Docker to build and run containers. - Fail2ban â Intrusion prevention that automatically bans IPs after repeated failed SSH login attempts. - UFW (Uncomplicated Firewall) â Configures OS-level firewall rules: deny all incoming traffic except ports 22, 80, and 443. This is a second layer of defense on top of the Hetzner firewall. - NTP â Time synchronization so your serverâs clock stays accurate. Important for SSL certificates and log timestamps. - Swap â Creates a swap file. Useful for smaller servers to prevent out-of-memory kills during deployment builds. - SSH hardening â Disables password authentication, disables root login (key-only access), and turns off unnecessary SSH features. - Unattended upgrades â Automatically installs security updates. Wait for the playbook to complete. Your server is now ready for Kamal. The Production Dockerfile Kamal deploys Docker images, so you need a Dockerfile. Rails 8 generates an excellent one by default with rails new . Here is what it looks like: # syntax=docker/dockerfile:1 # check=error=true ARG RUBY_VERSION=3.4.8 FROM docker.io/library/ruby:$RUBY_VERSION-slim AS base WORKDIR /rails RUN apt-get update -qq && \ apt-get install --no-install-recommends -y curl libjemalloc2 libvips sqlite3 && \ ln -s /usr/lib/$(uname -m)-linux-gnu/libjemalloc.so.2 /usr/local/lib/libjemalloc.so && \ rm -rf /var/lib/apt/lists /var/cache/apt/archives ENV RAILS_ENV="production" \ BUNDLE_DEPLOYMENT="1" \ BUNDLE_PATH="/usr/local/bundle" \ BUNDLE_WI
Genesis Park 편집팀이 AI를 활용하여 작성한 분석입니다. 원문은 출처 링크를 통해 확인할 수 있습니다.
공유