Improve Docker installation (#152)

This commit is contained in:
Riccardo Graziosi
2022-09-15 17:15:12 +02:00
committed by GitHub
parent 6198d814d8
commit fd3665cce6
37 changed files with 218 additions and 333 deletions

4
.dockerignore Normal file
View File

@@ -0,0 +1,4 @@
**/node_modules
.git
public/packs
public/packs-test

View File

@@ -1,13 +0,0 @@
# This is an example configuration for the .env file
# You need to create the .env file yourself
# For more information check out this page:
# https://github.com/riggraz/astuto/wiki/Required-environment-variables
BASE_URL=http://feedback.yoursitename.com
ENVIRONMENT=production
SECRET_KEY_BASE=secretkeybasehere
POSTGRES_USER=yourusernamehere
POSTGRES_PASSWORD=yourpasswordhere
EMAIL_CONFIRMATION=false

View File

@@ -29,7 +29,15 @@ Locales are stored in YAML files under `config/locales`. Translations are splitt
## Coding and testing
First of all, you need to follow [the installation instructions](https://github.com/riggraz/astuto#installation) to have a working local instance of Astuto.
### Installation instructions for contributors
In order to contribute to Astuto, you need to run Astuto on your computer in development mode. In order to do so, please follow these instructions:
1. Clone this repository
2. Edit `docker-compose.yml` if you want to change the value of some environment variables. Note that this `docker-compose.yml` is already configured to run Astuto in development mode (`target: dev`).
3. Run `docker-compose build`
4. Run `docker-compose up`
5. You should now have a running instance of Astuto at `localhost:3000`. A default user account has been created with credentials email: `admin@example.com`, password: `password`.
### Technologies

93
Dockerfile Normal file
View File

@@ -0,0 +1,93 @@
###
### Build stage ###
###
FROM ruby:2.6.6 AS builder
RUN curl -sL https://deb.nodesource.com/setup_14.x | bash -
RUN apt-get update -qq && apt-get install -y nodejs postgresql-client
RUN npm install -g yarn
RUN gem install bundler -v 2.3
ENV APP_ROOT /astuto
WORKDIR ${APP_ROOT}
# Build as development by default,
# unless --build-arg ENVIRONMENT=production is specificed
ARG ENVIRONMENT
ENV NODE_ENV=${ENVIRONMENT:-development}
ENV RAILS_ENV=${ENVIRONMENT:-development}
# Config bundler
RUN if [ "$ENVIRONMENT" = "production" ]; then bundle config set deployment true --local; fi
RUN if [ "$ENVIRONMENT" = "production" ]; then bundle config set without development test --local; fi
# yarn is already configured by NODE_ENV
# Copy Gemfile and install gems
COPY Gemfile Gemfile.lock ${APP_ROOT}/
RUN bundle install
# Copy package.json and install packages
COPY package.json yarn.lock ${APP_ROOT}/
RUN yarn install --check-files
# Copy all files
COPY . ${APP_ROOT}/
# Compile assets if production
# SECRET_KEY_BASE=1 is a workaround (see https://github.com/rails/rails/issues/32947)
RUN if [ "$ENVIRONMENT" = "production" ]; then RAILS_ENV=development bundle exec rake webpacker:compile; fi
###
### Dev stage ###
###
FROM builder AS dev
# Install Foreman to launch multiple processes from Procfile
RUN gem install foreman
ENTRYPOINT ["./docker-entrypoint-dev.sh"]
EXPOSE 3000
###
### Prod stage ###
###
FROM ruby:2.6.6-slim AS prod
RUN apt-get update -qq && \
apt-get install -yq \
postgresql-client \
nodejs && \
apt-get clean && \
rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* && \
truncate -s 0 /var/log/*log
RUN gem install bundler -v 2.3
ENV APP_ROOT /astuto
WORKDIR ${APP_ROOT}
# Copy gems, packages and compiled assets
COPY --from=builder ${APP_ROOT}/vendor/bundle/ ${APP_ROOT}/vendor/bundle/
COPY --from=builder ${APP_ROOT}/node_modules/ ${APP_ROOT}/node_modules/
COPY --from=builder ${APP_ROOT}/public/ ${APP_ROOT}/public/
# Copy application code
COPY --from=builder ${APP_ROOT}/app/ ${APP_ROOT}/app/
COPY --from=builder ${APP_ROOT}/bin/ ${APP_ROOT}/bin/
COPY --from=builder ${APP_ROOT}/config/ ${APP_ROOT}/config/
COPY --from=builder ${APP_ROOT}/db/ ${APP_ROOT}/db/
# Copy scripts and configuration files
COPY --from=builder ${APP_ROOT}/docker-entrypoint.sh ${APP_ROOT}/
COPY --from=builder ${APP_ROOT}/docker-entrypoint-prod.sh ${APP_ROOT}/
COPY --from=builder ${APP_ROOT}/Gemfile ${APP_ROOT}/
COPY --from=builder ${APP_ROOT}/Gemfile.lock ${APP_ROOT}/
COPY --from=builder ${APP_ROOT}/.ruby-version ${APP_ROOT}/
COPY --from=builder ${APP_ROOT}/config.ru ${APP_ROOT}/
COPY --from=builder ${APP_ROOT}/Rakefile ${APP_ROOT}/
COPY --from=builder /usr/local/bundle/config /usr/local/bundle/config
ENTRYPOINT ["./docker-entrypoint-prod.sh"]
EXPOSE 3000

23
Gemfile
View File

@@ -2,22 +2,21 @@ source 'https://rubygems.org'
git_source(:github) { |repo| "https://github.com/#{repo}.git" }
ruby '2.6.6'
gem 'rake', '12.3.3'
gem 'rails', '6.0.5'
gem 'pg', '>= 0.18', '< 2.0'
gem 'pg', '1.3.5'
gem 'puma', '~> 4.3'
gem 'sass-rails', '~> 5'
gem 'puma', '4.3.12'
gem 'webpacker', '4.3.0'
gem 'turbolinks', '~> 5'
gem 'turbolinks', '5.2.1'
gem 'jbuilder', '~> 2.7'
gem 'jbuilder', '2.11.5'
gem 'bootsnap', '>= 1.4.2', require: false
gem 'bootsnap', '1.12.0', require: false
# HTTP requests
gem 'httparty', '0.18.0'
@@ -29,13 +28,13 @@ gem 'devise', '4.7.3'
gem 'pundit', '2.2.0'
# I18n (forward locales to JS)
gem 'i18n-js'
gem 'i18n-js', '3.9.2'
# React
gem 'react-rails', '~> 2.6.0'
gem 'react-rails', '2.6.2'
# Pagination
gem 'kaminari', '~> 1.2.1'
gem 'kaminari', '1.2.2'
group :development, :test do
gem 'byebug', platforms: [:mri, :mingw, :x64_mingw]
@@ -46,7 +45,6 @@ end
group :development do
gem 'web-console', '>= 3.3.0'
gem 'listen', '>= 3.0.5', '< 3.2'
gem 'spring'
gem 'spring-watcher-listen', '~> 2.0.0'
end
@@ -59,5 +57,8 @@ group :test do
gem 'webdrivers'
end
# If not bundled, webpack compilation in production fails
gem 'listen', '>= 3.0.5', '< 3.2'
# Windows does not include zoneinfo files, so bundle the tzinfo-data gem
gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]

View File

@@ -183,7 +183,7 @@ GEM
method_source
rake (>= 0.8.7)
thor (>= 0.20.3, < 2.0)
rake (13.0.6)
rake (12.3.3)
rb-fsevent (0.11.1)
rb-inotify (0.10.1)
ffi (~> 1.0)
@@ -217,17 +217,6 @@ GEM
rspec-support (3.8.3)
ruby_dep (1.5.0)
rubyzip (2.3.2)
sass (3.7.4)
sass-listen (~> 4.0.0)
sass-listen (4.0.0)
rb-fsevent (~> 0.9, >= 0.9.4)
rb-inotify (~> 0.9, >= 0.9.7)
sass-rails (5.1.0)
railties (>= 5.2.0)
sass (~> 3.1)
sprockets (>= 2.8, < 4.0)
sprockets-rails (>= 2.0, < 4.0)
tilt (>= 1.1, < 3)
selenium-webdriver (4.1.0)
childprocess (>= 0.5, < 5.0)
rexml (~> 3.2, >= 3.2.5)
@@ -277,27 +266,27 @@ PLATFORMS
ruby
DEPENDENCIES
bootsnap (>= 1.4.2)
bootsnap (= 1.12.0)
byebug
capybara (>= 2.15)
devise (= 4.7.3)
factory_bot_rails (~> 5.0.2)
httparty (= 0.18.0)
i18n-js
jbuilder (~> 2.7)
kaminari (~> 1.2.1)
i18n-js (= 3.9.2)
jbuilder (= 2.11.5)
kaminari (= 1.2.2)
listen (>= 3.0.5, < 3.2)
pg (>= 0.18, < 2.0)
puma (~> 4.3)
pg (= 1.3.5)
puma (= 4.3.12)
pundit (= 2.2.0)
rails (= 6.0.5)
react-rails (~> 2.6.0)
rake (= 12.3.3)
react-rails (= 2.6.2)
rspec-rails (~> 3.8.2)
sass-rails (~> 5)
selenium-webdriver
spring
spring-watcher-listen (~> 2.0.0)
turbolinks (~> 5)
turbolinks (= 5.2.1)
tzinfo-data
web-console (>= 3.3.0)
webdrivers
@@ -307,4 +296,4 @@ RUBY VERSION
ruby 2.6.6p146
BUNDLED WITH
1.17.2
2.3.0

View File

@@ -29,24 +29,45 @@ Astuto is a free, open source, self-hosted customer feedback tool. It helps you
## Installation
**Note**: it is strongly suggested to run Astuto on Linux or macOS. As of today, Windows is likely to [cause problems](https://github.com/riggraz/astuto/wiki/Common-problems#standard_init_linuxgo211-exec-user-process-caused-no-such-file-or-directory). If you want to try anyway, follow along with the [Windows users installation guide](https://github.com/riggraz/astuto/wiki/Installation-for-Windows-users).
### DockerHub image (fastest, for production)
### Manual (for development)
1. Create an empty folder
2. Inside that folder, create a `docker-compose.yml` file with the following content:
```
version: '3.4'
services:
db:
image: postgres:14.5
environment:
POSTGRES_USER: yourpostgresusername
POSTGRES_PASSWORD: yourpostgrespassword
volumes:
- dbdata:/var/lib/postgresql/data
web:
image: riggraz/astuto:latest
environment:
POSTGRES_USER: yourpostgresusername
POSTGRES_PASSWORD: yourpostgrespassword
BASE_URL: http://yourwebsite.com
SECRET_KEY_BASE: yoursecretkeybase
ports:
- "3000:3000"
depends_on:
- db
volumes:
dbdata:
```
3. Edit the environment variables to fit your needs
4. Run `docker-compose pull`
5. Run `docker-compose up`
6. You should now have a running instance of Astuto on port 3000. A default user account has been created with credentials email: `admin@example.com`, password: `password`.
1. Clone this repository.
2. In Astuto's root directory, create a file named `.env` and fill it with the required environment variables (see `.env-example` for an example and check [this wiki page](https://github.com/riggraz/astuto/wiki/Required-environment-variables) for an explanation of the variables).
3. Run `script/docker-update-and-run.sh`.
4. You should now have a running instance of Astuto at `localhost:3000`. A default user account has been created with credentials email: `admin@example.com`, password: `password`.
### GitHub repository (for development)
### Using DockerHub image (fastest)
**Note**: this installation method is suggested for developers and contributors. If you just want to deploy your Astuto instance or try it out, we recommend to follow the above DockerHub installation instructions.
Coming soon!
## Post-installation notes
* **If you run into any problems take a look at the [common problems page](https://github.com/riggraz/astuto/wiki/Common-problems)**.
* When you want to launch Astuto you have to run `script/docker-run.sh`. If you installed new gems, packages or updated the database schema, you first need to run `script/docker-update.sh` and then `script/docker-run.sh`. You can run them together with `script/docker-update-and-run.sh`.
* If you changed some environment variables in `.env` you have to restart the instance for these changes to take effect.
See [contributing guidelines](https://github.com/riggraz/astuto/blob/main/CONTRIBUTING.md).
## Contributing

View File

@@ -1,3 +0,0 @@
// Place all the styles related to the likes controller here.
// They will automatically be included in application.css.
// You can use Sass (SCSS) here: http://sass-lang.com/

View File

@@ -11,7 +11,6 @@
<%= render 'layouts/set_js_locale' %>
<%= stylesheet_pack_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
<%= javascript_pack_tag 'application', 'data-turbolinks-track': 'reload' %>
<%= favicon_link_tag asset_pack_path('media/images/favicon.png') %>

View File

@@ -1,9 +1,4 @@
#!/usr/bin/env ruby
begin
load File.expand_path('../spring', __FILE__)
rescue LoadError => e
raise unless e.message.include?('spring')
end
APP_PATH = File.expand_path('../config/application', __dir__)
require_relative '../config/boot'
require 'rails/commands'

View File

@@ -1,9 +1,4 @@
#!/usr/bin/env ruby
begin
load File.expand_path('../spring', __FILE__)
rescue LoadError => e
raise unless e.message.include?('spring')
end
require_relative '../config/boot'
require 'rake'
Rake.application.run

View File

@@ -1,34 +0,0 @@
#!/bin/bash
# Exit immediately if a command exits with a non-zero status.
set -e
# Check if .env file is present
if [ ! -f .env ]; then
echo "A .env file must be present. Please create a .env file in the root directory."
exit 1
fi
# Array of environment variables that must be present
env_vars=(
"ENVIRONMENT" \
"POSTGRES_USER" \
"POSTGRES_PASSWORD" \
"EMAIL_CONFIRMATION" \
)
# Check each one
n_of_errors=0
for each in "${env_vars[@]}"; do
if ! [[ -v $each ]]; then
echo "$each is not set in .env file"
n_of_errors=$((n_of_errors+1))
fi
done
if [ $n_of_errors -gt 0 ]; then
echo "You need to set these ${n_of_errors} variables in your .env file."
echo "See .env-example for a configuration example."
echo "Check out https://github.com/riggraz/astuto/wiki/Required-environment-variables"
exit 2
fi

View File

@@ -1,19 +1,3 @@
# 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 macOS with MacPorts:
# gem install pg -- --with-pg-config=/opt/local/lib/postgresql84/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'
#
default: &default
adapter: postgresql
encoding: unicode
@@ -24,64 +8,12 @@ default: &default
development:
<<: *default
database: <%= ENV['POSTGRES_USER'] %>
# The specified database role being used to connect to postgres.
# To create additional roles in postgres see `$ createuser --help`.
# When left blank, postgres will use the default role. This is
# the same name as the operating system user that initialized the database.
#username: app
# The password associated with the postgres role (username).
#password:
# Connect on a TCP socket. Omitted by default since the client uses a
# domain socket that doesn't need configuration. Windows does not have
# domain sockets, so uncomment these lines.
#host: localhost
# 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: <%= ENV['POSTGRES_USER'] %>_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 as a unix environment variable when you boot
# the app. Read https://guides.rubyonrails.org/configuring.html#configuring-a-database
# for a full rundown on how to provide these environment variables in a
# production deployment.
#
# On Heroku and other platform providers, you may have a full connection URL
# available as an environment variable. For example:
#
# DATABASE_URL="postgres://myuser:mypass@localhost/somedatabase"
#
# You can use this database configuration with:
#
# production:
# url: <%= ENV['DATABASE_URL'] %>
#
production:
<<: *default
database: <%= ENV['POSTGRES_USER'] %>

View File

@@ -11,7 +11,7 @@ default: &default
# Additional paths webpack should lookup modules
# ['app/assets', 'engine/foo/app/assets']
resolved_paths: ['app/assets']
resolved_paths: []
# Reload manifest.json on all requests so we reload latest compiled packs
cache_manifest: false
@@ -54,7 +54,7 @@ default: &default
development:
<<: *default
compile: true
compile: false
# Verifies that correct packages and versions are installed by inspecting package.json, yarn.lock, and node_modules
check_yarn_integrity: false
@@ -81,7 +81,7 @@ development:
test:
<<: *default
compile: true
compile: false
# Compile test packs to a separate directory
public_output_path: packs-test

View File

@@ -1,25 +1,22 @@
version: '3'
version: '3.4'
services:
db:
image: postgres
image: postgres:14.5
environment:
- POSTGRES_USER
- POSTGRES_PASSWORD
POSTGRES_USER: astuto
POSTGRES_PASSWORD: dbpass
volumes:
- dbdata:/var/lib/postgresql/data
web:
build:
context: .
dockerfile: ./docker/app/Dockerfile
dockerfile: Dockerfile
target: dev
environment:
- UPDATE=0
- BASE_URL
- ENVIRONMENT
- SECRET_KEY_BASE
- POSTGRES_USER
- POSTGRES_PASSWORD
- EMAIL_CONFIRMATION
- MULTI_TENANCY
POSTGRES_USER: astuto
POSTGRES_PASSWORD: dbpass
BASE_URL: http://localhost:3000
SECRET_KEY_BASE: secretkeybasehere
volumes:
- .:/astuto
ports:

11
docker-entrypoint-dev.sh Executable file
View File

@@ -0,0 +1,11 @@
#!/bin/sh
set -e
sh docker-entrypoint.sh
# Needed to avoid "webpack-dev-server not found" error
yarn install --check-files
# Launch Rails server and webpack-dev-server using Foreman
foreman start -p 3000

8
docker-entrypoint-prod.sh Executable file
View File

@@ -0,0 +1,8 @@
#!/bin/sh
set -e
sh docker-entrypoint.sh
# Launch Rails server in production
bundle exec rails server -e production

View File

@@ -1,53 +1,29 @@
#!/bin/bash
#!/bin/sh
# This file serves 3 use cases:
# 1: if the env variable UPDATE is 1, db is prepared
# 2: if a command was supplied, it is executed
# 3: otherwise, check env variable ENVIRONMENT and launch server
# Exit immediately if a command exits with a non-zero status.
# Exit immediately if a command exits with a non-zero status
set -e
# Check environment variables
/bin/bash ./check-env.sh
# Remove a potentially pre-existing server.pid for Rails.
# Remove a potentially pre-existing server.pid for Rails
rm -f $APP_ROOT/tmp/pids/server.pid
# Use case 1
if [ "$UPDATE" = 1 ]; then
# Create database, load schema, run migrations and seed data in an idempotent way.
echo "Preparing database..."
db_version=$(bundle exec rake db:version)
echo "$db_version"
if [ "$db_version" = "Current version: 0" ]; then
bundle exec rake db:create
bundle exec rake db:schema:load
bundle exec rake db:migrate
bundle exec rake db:seed
else
bundle exec rake db:migrate
fi
echo "Database prepared."
# Prepare database
echo "Preparing database..."
exit 0
# Wait for database
until bundle exec rake db:version; do
>&2 echo "Waiting for postgres to initialize..."
sleep 1
done
# Update or create database
db_version=$(bundle exec rake db:version)
echo "$db_version"
if [ "$db_version" = "Current version: 0" ]; then
bundle exec rake db:create
bundle exec rake db:schema:load
bundle exec rake db:migrate
bundle exec rake db:seed
else
bundle exec rake db:migrate
fi
# Use case 2
if [ ! $# -eq 0 ]; then
exec "$@"
exit 0
fi
# Use case 3
echo "Environment is: $ENVIRONMENT"
export RAILS_ENV="$ENVIRONMENT"
export NODE_ENV="$ENVIRONMENT"
if [ $ENVIRONMENT == "development" ]; then
# Launch Rails server and webpack-dev-server using Foreman
foreman start -p 3000
else # production
# Compile assets and launch server
rails assets:precompile
rails server -e production
fi
echo "Database prepared."

View File

@@ -1,35 +0,0 @@
FROM ruby:2.6.6
RUN curl -sL https://deb.nodesource.com/setup_14.x | bash -
RUN apt-get update -qq && apt-get install -y nodejs postgresql-client
RUN npm install -g yarn
# Install Chrome (only needed for Capybara tests)
# Uncomment following lines if you need to run integration tests
# RUN wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb
# RUN dpkg -i /google-chrome-stable_current_amd64.deb; apt-get -fy install
# RUN rm /google-chrome-stable_current_amd64.deb
ENV APP_ROOT /astuto
RUN mkdir ${APP_ROOT}
WORKDIR ${APP_ROOT}
# Launch processes in Procfile
RUN gem install foreman
# Copy Gemfile and install gems
COPY Gemfile Gemfile.lock ${APP_ROOT}/
RUN bundle install
# Copy package.json and install packages
COPY package.json yarn.lock ${APP_ROOT}/
RUN yarn install --check-files
COPY . ${APP_ROOT}
# Add a script to be executed every time the container starts.
ENTRYPOINT ["./docker-entrypoint.sh"]
EXPOSE 3000
# No default CMD is provided in Dockerfile

View File

View File

View File

@@ -1,8 +0,0 @@
#!/bin/bash
# Exit immediately if a command exits with a non-zero status.
set -e
echo "Starting Astuto..."
docker compose up "$@"

View File

@@ -1,7 +0,0 @@
#!/bin/bash
# Exit immediately if a command exits with a non-zero status.
set -e
/bin/bash script/docker-update.sh
/bin/bash script/docker-run.sh

View File

@@ -1,15 +0,0 @@
#!/bin/bash
# Exit immediately if a command exits with a non-zero status.
set -e
echo "Starting update..."
echo "-> Docker image will be rebuilt if necessary"
echo "-> Database schema will be updated if necessary"
echo "-> Webpack will compile assets"
docker compose build
docker compose run --rm web yarn install # needed to avoid yarn integrity check fail
docker compose run --rm -e UPDATE=1 web
echo "Update completed."

View File

View File

@@ -1,5 +0,0 @@
require "test_helper"
class ApplicationSystemTestCase < ActionDispatch::SystemTestCase
driven_by :selenium, using: :chrome, screen_size: [1400, 1400]
end

View File

@@ -1,11 +0,0 @@
require "test_helper"
class ApplicationCable::ConnectionTest < ActionCable::Connection::TestCase
# test "connects with cookies" do
# cookies.signed[:user_id] = 42
#
# connect
#
# assert_equal connection.user_id, "42"
# end
end

View File

0
test/fixtures/.keep vendored
View File

View File

View File

View File

View File

View File

View File

View File

@@ -1,13 +0,0 @@
ENV['RAILS_ENV'] ||= 'test'
require_relative '../config/environment'
require 'rails/test_help'
class ActiveSupport::TestCase
# Run tests in parallel with specified workers
parallelize(workers: :number_of_processors)
# Setup all fixtures in test/fixtures/*.yml for all tests in alphabetical order.
fixtures :all
# Add more helper methods to be used by all tests here...
end

0
vendor/.keep vendored
View File