Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Deploy using Dockerfile instead of buildpack #598

Merged
merged 1 commit into from
Mar 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
.env
9 changes: 7 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,13 @@ on:
workflow_dispatch:

jobs:
build:
runs-on: ubuntu-20.04
docker:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: ./bin/docker-test
ruby:
runs-on: ubuntu-latest
env:
BUNDLE_LOCAL: 1
steps:
Expand Down
4 changes: 4 additions & 0 deletions .github/workflows/deploy-fly.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,11 @@ jobs:
runs-on: ubuntu-latest
timeout-minutes: 30
steps:
- uses: actions/checkout@v4
- run: |
echo "RUBY_VERSION=$(cat .ruby-version)" >> $GITHUB_ENV
- uses: dentarg/fly@main
with:
build-args: "RUBY_VERSION=${{ env.RUBY_VERSION }}"
fly-token: ${{ secrets.FLY_API_TOKEN }}
github-token: ${{ secrets.GITHUB_TOKEN }}
58 changes: 58 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
ARG RUBY_VERSION
FROM registry.docker.com/library/ruby:$RUBY_VERSION-slim as base

# The app lives here
WORKDIR /app

# Install base packages
RUN apt-get update -qq && \
apt-get install --no-install-recommends -y \
curl \
postgresql-client

# Set production environment
ENV BUNDLE_DEPLOYMENT="1" \
BUNDLE_PATH="/usr/local/bundle" \
BUNDLE_CACHE_PATH="/usr/local/bundle/cache" \
BUNDLE_WITHOUT="development"

# Throw-away build stage to reduce size of final image
FROM base as build

# Install build packages
RUN apt-get install --no-install-recommends -y \
build-essential \
git \
libpq-dev \
pkg-config

# Install application gems
COPY Gemfile Gemfile.lock .ruby-version ./
COPY vendor/cache "${BUNDLE_CACHE_PATH}"
RUN bundle install --local

# Copy application code
COPY . .

# Final stage for app image
FROM base

ARG APPUSER=app
ARG APPDIR=/app

# Clean up installation packages to reduce image size
RUN 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 $APPDIR $APPDIR

# Run and own only the runtime files as a non-root user for security
RUN mkdir -p log tmp
RUN groupadd --system --gid 1000 $APPUSER
RUN useradd $APPUSER --uid 1000 --gid 1000 --create-home --shell /bin/bash
RUN chown -R $APPUSER:$APPUSER log tmp
USER 1000:1000

# Start the server by default, this can be overwritten at runtime
CMD bin/start
8 changes: 2 additions & 6 deletions Gemfile
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# frozen_string_literal: true

source 'https://rubygems.org/'
ruby File.read('.ruby-version').chomp
ruby file: '.ruby-version'

gem 'sequel'
gem 'pg'
Expand All @@ -25,11 +25,7 @@ gem 'warning'
gem 'rake'
gem 'rubocop', '~> 1.60.2', require: false
gem 'dyno_metadata'

group :development do
gem 'overman'
gem 'localhost'
end
gem 'localhost'

group :test do
gem 'climate_control'
Expand Down
4 changes: 2 additions & 2 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,6 @@ GEM
base64
faraday (>= 1, < 3)
sawyer (~> 0.9)
overman (0.87.3)
parallel (1.24.0)
parser (3.3.0.5)
ast (~> 2.4.1)
Expand Down Expand Up @@ -108,6 +107,7 @@ GEM
faraday (>= 0.17.3, < 3)
selma (0.2.2)
rb_sys (~> 0.9)
selma (0.2.2-aarch64-linux)
selma (0.2.2-arm64-darwin)
selma (0.2.2-x86_64-linux)
sentry-ruby (5.16.1)
Expand Down Expand Up @@ -147,6 +147,7 @@ GEM
zeitwerk (2.6.13)

PLATFORMS
aarch64-linux
arm64-darwin
ruby
x86_64-linux
Expand All @@ -164,7 +165,6 @@ DEPENDENCIES
m
minitest
octokit
overman
pg
puma
rack-flash3
Expand Down
2 changes: 1 addition & 1 deletion Procfile
Original file line number Diff line number Diff line change
@@ -1 +1 @@
web: bundle exec puma -C config/puma.rb
web: bundle exec puma --config config/puma.rb
11 changes: 4 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ These instructions assume you are using OS X.
Install prerequisites

brew install postgresql
gem install overman
bundle install

Ruby gems are vendored into `vendor/cache`, you should always check in the gems when changing gems. The caching is set up with [`bundle package --all`](https://bundler.io/man/bundle-package.1.html).
Expand All @@ -24,13 +25,9 @@ Make sure PostgreSQL is running

postgres

Get a copy of the production database

rake db:pull

### Start the app

In production, the script `bin/web_start` ([background](https://github.com/Starkast/wikimum/commit/acf57ec06ddb9ff3403acf56ababaa58f8cd3f43)) is used, but we avoid using that in the `Procfile` because the integration tests reads that command and needs to get the PID of Puma, not the script, in order to cleanly shutdown Puma.
In production, the script `bin/start` is used, but we avoid using that in the `Procfile` because the integration tests reads that command and needs to get the PID of Puma, not the script, in order to cleanly shutdown Puma.

overman start

Expand Down Expand Up @@ -59,7 +56,7 @@ MAINTENANCE_MODE=true

### Console

foreman run bundle exec racksh
overman run bundle exec racksh

### Tests

Expand Down Expand Up @@ -90,7 +87,7 @@ GitHub Actions scan the code using [Brakeman](https://github.com/presidentbeef/b
If you need to ignore a weakness reported, update `config/brakeman.ignore`. You can get the JSON needed by running Brakeman like this:

```bash
docker run -it --rm -v $(pwd):/app -w /app ruby:2.7.6 bash
docker run -it --rm -v $(pwd):/app -w /app ruby:$(cat .ruby-version) bash
gem install brakeman
brakeman --force --format json .
```
Expand Down
15 changes: 0 additions & 15 deletions Rakefile
Original file line number Diff line number Diff line change
Expand Up @@ -21,21 +21,6 @@ namespace(:test) do
end

namespace(:db) do
desc "Replace local database with production database"
task :pull do |t|
require "uri"
uri = URI.parse(ENV.fetch("DATABASE_URL", "postgres://localhost/wikimum"))
local_database = uri.path[1..-1]

trap("INT") { exit }

puts "Will remove local database '#{local_database}', press Enter to proceed, ^C to abort"
STDIN.gets

system "dropdb #{local_database}"
system "heroku pg:pull --app wikimum DATABASE_URL #{local_database}"
end

desc "Run migrations"
task :migrate, [:version] do |t, args|
require 'sequel'
Expand Down
8 changes: 8 additions & 0 deletions bin/docker-build
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#!/bin/bash

TAG=${TAG:-wikimum}

set -e
set -x

docker build . --build-arg RUBY_VERSION=$(cat .ruby-version) --tag $TAG "$@"
25 changes: 25 additions & 0 deletions bin/docker-reset-run
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#!/bin/bash

set -e
set -x

RUBY_VERSION=$(cat .ruby-version) docker compose up \
--build \
--always-recreate-deps \
--force-recreate \
--remove-orphans \
--renew-anon-volumes \
"$@"

# this script is useful if you run into some strange problem with the docker setup

# --always-recreate-deps Recreate dependent containers. Incompatible with --no-recreate.
# --force-recreate Recreate containers even if their configuration and image haven't changed.
# --remove-orphans Remove containers for services not defined in the Compose file.
#-V, --renew-anon-volumes Recreate anonymous volumes instead of retrieving data from the previous containers.

# these flags will make use of more disk space
# check and clean up with
#
# docker system df
# docker system prune
12 changes: 12 additions & 0 deletions bin/docker-run
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#!/bin/bash

set -e
set -x

RUBY_VERSION=$(cat .ruby-version) docker compose up \
--build \
"$@"

# useful but mutually exclusive flags
# --detach
# --exit-code-from app
24 changes: 24 additions & 0 deletions bin/docker-test
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#!/bin/bash

set -x

RUBY_VERSION=$(cat .ruby-version) docker compose up \
--build \
--detach \
--wait

curl \
--verbose \
--silent \
--output /dev/null \
--fail-with-body \
--retry 5 \
--retry-all-errors \
--retry-connrefused \
127.0.0.1:8080

result=$?

docker compose stop

exit $result
1 change: 1 addition & 0 deletions bin/db_migrate → bin/start
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@ set -e
set -u

bundle exec rake db:migrate
bundle exec puma --config config/puma.rb
6 changes: 0 additions & 6 deletions bin/web_start

This file was deleted.

1 change: 1 addition & 0 deletions default.env
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
SESSION_SECRET=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
32 changes: 32 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
version: "3.9"
services:
app:
build:
context: .
args:
- RUBY_VERSION
ports:
- "127.0.0.1:8080:3000"
env_file:
- ./default.env
environment:
DATABASE_URL: postgres://postgres:postgres@db/db
PORT: 3000
depends_on:
db:
condition: service_healthy
db:
image: postgres
restart: always
# set shared memory limit when using docker-compose
# https://github.com/docker-library/postgres/issues/416
shm_size: 128mb
environment:
POSTGRES_DB: db
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
healthcheck:
test: ["CMD-SHELL", "pg_isready --dbname=db --username=postgres"]
interval: 2s
retries: 10
start_period: 20s
7 changes: 3 additions & 4 deletions fly.toml
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
app = "wikimum"

[build]
builder = "heroku/buildpacks:20"

[processes]
web = "/bin/sh -c 'bin/db_migrate && bin/web_start'"
# Dockerfile controls this
# https://community.fly.io/t/multiple-process-dockerfile/13639
web = ""

[env]
PRIMARY_REGION = "ams"
Expand Down
Binary file removed vendor/cache/overman-0.87.3.gem
Binary file not shown.
Binary file added vendor/cache/selma-0.2.2-aarch64-linux.gem
Binary file not shown.