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

Docker configs sync #602

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
15 changes: 15 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
.env

/tmp/*
/log/*.log

/vendor/bundle
.bundle

.bash_history
.byebug_hist
.pry_history

docker-compose.yml

.semaphore-cache
84 changes: 39 additions & 45 deletions .semaphore/semaphore.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,74 +11,68 @@ execution_time_limit:

auto_cancel:
queued:
when: 'true'
when: "true"

fail_fast:
stop:
when: 'true'
when: "true"

global_job_config:
env_vars:
- name: RAILS_ENV
value: 'test'
- name: DATABASE_URL
value: 'postgresql://postgres@localhost/test?encoding=utf8'
- name: BUNDLE_ARGS
value: '--deployment --without development staging production --jobs 4'

prologue:
commands:
# Setup dynamic environment variables b/c they do not support via env_vars yet
- export DOCKER_REPO="docker.pkg.github.com/fs/rails-base"
- export BUILDER_NAME="${DOCKER_REPO}/builder:${SEMAPHORE_GIT_BRANCH}"
- export IMAGE_NAME="${DOCKER_REPO}/final:${SEMAPHORE_GIT_BRANCH}"
- export RAILS_ENV="test"
- export RACK_ENV="test"
- export BUNDLE_WITHOUT="development staging production"
- export DATABASE_CLEANER_ALLOW_REMOTE_DATABASE_URL="true"
- export MAILER_SENDER_ADDRESS="noreply@example.com"

# Authenticate with DockerHub
- echo "${GITHUB_TOKEN}" | docker login https://docker.pkg.github.com -u "${GITHUB_USERNAME}" --password-stdin

- checkout
- cache restore
- cp .env.example .env

blocks:
- name: Setup
- name: Build
task:
secrets:
- name: semaphore-github-packages-secrets
jobs:
- name: Bundle
commands:
- bundle install ${BUNDLE_ARGS}
- cache store
- name: Docker build
commands:
- docker pull "${BUILDER_NAME}" || true
- docker pull "${IMAGE_NAME}" || true
- docker build -t "${BUILDER_NAME}" --target Builder --cache-from="${BUILDER_NAME}" --build-arg BUNDLE_WITHOUT="${BUNDLE_WITHOUT}" --build-arg BUNDLER_VERSION=2.1.4 .
- docker build -t "${IMAGE_NAME}" --target Final --cache-from="${BUILDER_NAME}" --cache-from="${IMAGE_NAME}" --build-arg BUNDLE_WITHOUT="${BUNDLE_WITHOUT}" --build-arg BUNDLER_VERSION=2.1.4 .
- docker push "${BUILDER_NAME}"
- docker push "${IMAGE_NAME}"

- name: Quality
- name: Run
task:
jobs:
- name: Quality
commands:
- bundle install ${BUNDLE_ARGS} --local
- bin/quality
secrets:
- name: github-docker-secrets

- name: Test
task:
prologue:
commands:
- nvm use
- sem-version ruby 2.5.7
- bundle install ${BUNDLE_ARGS} --local
- sem-service start postgres
- bin/rails db:setup
- bin/rails assets:precompile
- docker pull "${IMAGE_NAME}"
- cp docker-compose.linux.yml docker-compose.override.yml
- docker-compose up --detach

jobs:
- name: Unit
- name: Run RSpec
commands:
- bin/rspec --tag ~type:feature
- docker-compose exec app bin/rails db:create db:schema:load
- bin/tests

- name: Features
- name: Run Quality
commands:
- bin/rspec --tag type:feature

# - name: Jasmine
# commands:
# - bundle exec rails jasmine:ci
- bin/quality

promotions:
- name: Deploy to Heroku
pipeline_file: heroku.yml

# Continuous deployment from master branch
auto_promote_on:
- result: passed
branch:
- master
auto_promote:
when: "result = 'passed' and branch = 'master'"
63 changes: 63 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
######################
# Stage: Builder
FROM ruby:2.7.1-alpine as Builder

ARG BUNDLER_VERSION

RUN apk add --update --no-cache \
build-base \
postgresql-dev \
git \
nodejs \
npm \
imagemagick \
tzdata

# Remove bundle config if exist
RUN rm -f .bundle/config

RUN gem install bundler:$BUNDLER_VERSION

WORKDIR /app

# Install gems
ARG BUNDLE_WITHOUT
ENV BUNDLE_WITHOUT ${BUNDLE_WITHOUT}

RUN bundle config set without ${BUNDLE_WITHOUT}

COPY Gemfile* /app/
RUN bundle install -j4 --retry 3 \
# Remove unneeded files (cached *.gem, *.o, *.c)
&& rm -rf /usr/local/bundle/cache/*.gem \
&& find /usr/local/bundle/gems/ -name "*.c" -delete \
&& find /usr/local/bundle/gems/ -name "*.o" -delete

RUN npm install -g yarn && yarn install

# Add the Rails app
COPY . /app/

# Remove folders not needed in resulting image
ARG FOLDERS_TO_REMOVE
RUN rm -rf $FOLDERS_TO_REMOVE

###############################
# Stage Final
FROM ruby:2.7.1-alpine as Final

# Add Alpine packages
RUN apk add --update --no-cache \
postgresql-client \
imagemagick \
tzdata \
file \
git \
nodejs \
npm

# Copy app with gems from former build stage
COPY --from=Builder /usr/local/bundle/ /usr/local/bundle/
COPY --from=Builder /app/ /app/

WORKDIR /app
9 changes: 9 additions & 0 deletions bin/docker-entrypoint
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#!/bin/sh

set -e

if [ -f tmp/pids/server.pid ]; then
rm tmp/pids/server.pid
fi

bundle exec rails server -b 0.0.0.0
7 changes: 7 additions & 0 deletions bin/docker-sync
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#!/usr/bin/env sh

set -e

gem install docker-sync
docker-sync start
cp docker-compose.osx.yml docker-compose.override.yml
6 changes: 6 additions & 0 deletions docker-compose.linux.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
version: "3.4"

services:
app:
volumes:
- .:/app
10 changes: 10 additions & 0 deletions docker-compose.osx.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
version: "3.4"

services:
app:
volumes:
- app-files:/app:nocopy

volumes:
app-files:
external: true
50 changes: 50 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
version: "3.4"

x-app: &app_base
depends_on:
- db
image: ${IMAGE_NAME}
environment:
- DATABASE_URL=postgres://postgres:password@db
- RAILS_ENV
- RACK_ENV
- DATABASE_CLEANER_ALLOW_REMOTE_DATABASE_URL
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you please add this variable to .env.example? Something like this:

# Allow connect to remote database (in separate container)
DATABASE_CLEANER_ALLOW_REMOTE_DATABASE_URL=true

- AUTH_SECRET_TOKEN
- MAILER_SENDER_ADDRESS
- PASSWORD_RECOVERY_LINK_TEMPLATE
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess this variable isn't need in this project

Suggested change
- PASSWORD_RECOVERY_LINK_TEMPLATE

build:
context: .
args:
- BUNDLE_WITHOUT="${BUNDLE_WITHOUT}"
- BUNDLER_VERSION=2.1.4
- FOLDERS_TO_REMOVE=""
links:
- db
volumes:
- ruby-bundle:/usr/local/bundle

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe also use separate volume for node_modules folder? Seems like now container will use node_modules from the host machine? (because of .:/app volume). If so, I think it's no good because of different dependencies between diff machines (MacOS Host, Linux container)


services:
db:
image: postgres:12-alpine
environment:
- POSTGRES_PASSWORD=password
ports:
- "5432:5432"
volumes:
- db-data:/var/lib/postgresql/data
mailcatcher:
image: yappabe/mailcatcher
ports:
- "1025:1025"
- "1080:1080"
app:
<<: *app_base
depends_on:
- mailcatcher
ports:
- "3000:3000"
command: bin/docker-entrypoint

volumes:
ruby-bundle:
db-data:
6 changes: 6 additions & 0 deletions docker-sync.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
version: "2"
syncs:
app-files:
notify_terminal: true
src: './'
sync_excludes: ['.git', '.bundle']