mirror of
https://github.com/openfoodfoundation/openfoodnetwork
synced 2026-01-24 20:36:49 +00:00
Merge pull request #3887 from pacodelaluna/add-docker-configuration-for-dev-setup
Add docker configuration for quick local setup
This commit is contained in:
4
.dockerignore
Normal file
4
.dockerignore
Normal file
@@ -0,0 +1,4 @@
|
||||
.git
|
||||
.gitignore
|
||||
log/*
|
||||
tmp/*
|
||||
47
DOCKER.md
Normal file
47
DOCKER.md
Normal file
@@ -0,0 +1,47 @@
|
||||
### Docker
|
||||
|
||||
It is possible to setup the Open Food Network app easily with Docker and Docker Compose.
|
||||
The objective is to spare configuration time, in order to help people testing the app and contribute to it.
|
||||
It can also be used as documentation. It is not perfect but it is used in many other projects and many devs are used to it nowadays.
|
||||
|
||||
### Install Docker
|
||||
|
||||
Please check the documentation here, https://docs.docker.com/install/ to install Docker.
|
||||
|
||||
For Docker Compose, information are here: https://docs.docker.com/compose/install/.
|
||||
|
||||
Better to have at least 2GB free on your computer in order to download images and create containers for Open Food Network app.
|
||||
|
||||
|
||||
### Use Docker with Open Food Network
|
||||
|
||||
Open a terminal with a shell.
|
||||
|
||||
Clone the repository:
|
||||
|
||||
```sh
|
||||
$ git clone git@github.com:openfoodfoundation/openfoodnetwork.git
|
||||
```
|
||||
|
||||
Go at the root of the app:
|
||||
|
||||
```sh
|
||||
$ cd openfoodnetwork
|
||||
```
|
||||
|
||||
Download the Docker images and build the containers:
|
||||
|
||||
```sh
|
||||
$ docker-compose build
|
||||
```
|
||||
|
||||
Run the app with all the required containers:
|
||||
|
||||
```sh
|
||||
$ docker-compose up
|
||||
```
|
||||
|
||||
This command will setup the database and seed it with sample data. The default admin user is 'ofn@example.com' with 'ofn123' password.
|
||||
Check the app in the browser at `http:://localhost:3000`.
|
||||
|
||||
You will then get the trace of the containers in the terminal. You can stop the containers using Ctrl-C in the terminal.
|
||||
31
Dockerfile
Normal file
31
Dockerfile
Normal file
@@ -0,0 +1,31 @@
|
||||
FROM ubuntu:18.04
|
||||
|
||||
# Install all the requirements
|
||||
RUN apt-get update && apt-get install -y curl git build-essential software-properties-common wget zlib1g-dev libssl1.0-dev libreadline-dev libyaml-dev libffi-dev libxml2-dev libxslt1-dev wait-for-it
|
||||
|
||||
# Setup ENV variables
|
||||
ENV PATH /usr/local/src/rbenv/shims:/usr/local/src/rbenv/bin:$PATH
|
||||
ENV RBENV_ROOT /usr/local/src/rbenv
|
||||
ENV RUBY_VERSION 2.1.5
|
||||
ENV CONFIGURE_OPTS --disable-install-doc
|
||||
|
||||
# Rbenv & Ruby part
|
||||
RUN git clone https://github.com/rbenv/rbenv.git ${RBENV_ROOT} && \
|
||||
git clone https://github.com/rbenv/ruby-build.git ${RBENV_ROOT}/plugins/ruby-build && \
|
||||
${RBENV_ROOT}/plugins/ruby-build/install.sh && \
|
||||
echo 'eval "$(rbenv init -)"' >> /etc/profile.d/rbenv.sh && \
|
||||
rbenv install $RUBY_VERSION && \
|
||||
rbenv global $RUBY_VERSION && \
|
||||
gem install bundler --version=1.17.2
|
||||
|
||||
# Postgres
|
||||
RUN sh -c "echo 'deb https://apt.postgresql.org/pub/repos/apt/ bionic-pgdg main' > /etc/apt/sources.list.d/pgdg.list" && \
|
||||
wget --quiet -O - https://apt.postgresql.org/pub/repos/apt/ACCC4CF8.asc | apt-key add - && \
|
||||
apt-get update && \
|
||||
apt-get install -yqq --no-install-recommends postgresql-client-9.5 libpq-dev
|
||||
|
||||
ENV BUNDLE_PATH /bundles
|
||||
|
||||
COPY . /usr/src/app/
|
||||
|
||||
WORKDIR /usr/src/app
|
||||
@@ -1,33 +1,19 @@
|
||||
development:
|
||||
default: &default
|
||||
adapter: postgresql
|
||||
encoding: unicode
|
||||
database: open_food_network_dev
|
||||
encoding: utf8
|
||||
pool: 5
|
||||
host: localhost
|
||||
timeout: 5000
|
||||
host: db
|
||||
port: 5432
|
||||
|
||||
development:
|
||||
<<: *default
|
||||
database: open_food_network_dev
|
||||
username: ofn
|
||||
password: f00d
|
||||
|
||||
test:
|
||||
adapter: postgresql
|
||||
encoding: unicode
|
||||
<<: *default
|
||||
database: open_food_network_test
|
||||
pool: 5
|
||||
host: localhost
|
||||
username: ofn
|
||||
password: f00d
|
||||
|
||||
production:
|
||||
adapter: postgresql
|
||||
encoding: unicode
|
||||
database: open_food_network_prod
|
||||
pool: 5
|
||||
username: ofn
|
||||
password: f00d
|
||||
|
||||
staging:
|
||||
adapter: postgresql
|
||||
encoding: unicode
|
||||
database: open_food_network_prod
|
||||
pool: 5
|
||||
username: ofn
|
||||
password: f00d
|
||||
|
||||
38
docker-compose.yml
Normal file
38
docker-compose.yml
Normal file
@@ -0,0 +1,38 @@
|
||||
version: '3'
|
||||
|
||||
services:
|
||||
db:
|
||||
image: postgres:9.5
|
||||
restart: always
|
||||
environment:
|
||||
POSTGRES_PASSWORD: f00d
|
||||
POSTGRES_USER: ofn
|
||||
volumes:
|
||||
- 'postgres:/var/lib/postgresql/data'
|
||||
web:
|
||||
tty: true
|
||||
stdin_open: true
|
||||
build: .
|
||||
ports:
|
||||
- 3000:3000
|
||||
volumes:
|
||||
- .:/usr/src/app
|
||||
- gems:/bundles
|
||||
- ./config/database.yml:/usr/src/app/config/database.yml
|
||||
- ./config/application.yml.example:/usr/src/app/config/application.yml
|
||||
depends_on:
|
||||
- db
|
||||
environment:
|
||||
ADMIN_EMAIL: ofn@example.com
|
||||
ADMIN_PASSWORD: ofn123
|
||||
command: >
|
||||
bash -c "(bundle check || bundle install) &&
|
||||
wait-for-it -t 30 db:5432 &&
|
||||
bundle exec rake db:reset db:test:prepare &&
|
||||
bundle exec rake ofn:sample_data || true &&
|
||||
rm -f tmp/pids/server.pid &&
|
||||
bundle exec rails s -p 3000 -b '0.0.0.0'"
|
||||
|
||||
volumes:
|
||||
gems:
|
||||
postgres:
|
||||
@@ -1,305 +0,0 @@
|
||||
namespace :ofn do
|
||||
namespace :dev do
|
||||
desc 'load sample data'
|
||||
task load_sample_data: :environment do
|
||||
require_relative '../../spec/factories'
|
||||
task_name = "openfoodnetwork:dev:load_sample_data"
|
||||
|
||||
country = Spree::Country.find_by_iso(ENV.fetch('DEFAULT_COUNTRY_CODE'))
|
||||
state = country.states.first
|
||||
|
||||
# -- Shipping / payment information
|
||||
unless Spree::Zone.find_by_name 'Australia'
|
||||
puts "[#{task_name}] Seeding shipping / payment information"
|
||||
|
||||
zone = FactoryBot.create(:zone, name: 'Australia', zone_members: [])
|
||||
Spree::ZoneMember.create(zone: zone, zoneable: country)
|
||||
address = FactoryBot.create(
|
||||
:address,
|
||||
address1: "15/1 Ballantyne Street",
|
||||
zipcode: "3153",
|
||||
city: "Thornbury",
|
||||
country: country,
|
||||
state: state
|
||||
)
|
||||
enterprise = FactoryBot.create(:enterprise, address: address)
|
||||
|
||||
FactoryBot.create(:shipping_method, zone: zone, distributors: [enterprise])
|
||||
end
|
||||
|
||||
# -- Taxonomies
|
||||
unless Spree::Taxonomy.find_by_name 'Products'
|
||||
puts "[#{task_name}] Seeding taxonomies"
|
||||
taxonomy = Spree::Taxonomy.find_by_name('Products') || FactoryBot.create(:taxonomy,
|
||||
name: 'Products')
|
||||
taxonomy_root = taxonomy.root
|
||||
|
||||
taxons = ['Vegetables', 'Fruit', 'Oils', 'Preserves and Sauces', 'Dairy', 'Meat and Fish']
|
||||
taxons.each do |taxon_name|
|
||||
FactoryBot.create(:taxon,
|
||||
name: taxon_name,
|
||||
parent_id: taxonomy_root.id,
|
||||
taxonomy_id: taxonomy.id)
|
||||
end
|
||||
end
|
||||
|
||||
# -- Addresses
|
||||
unless Spree::Address.find_by_zipcode "3160"
|
||||
puts "[#{task_name}] Seeding addresses"
|
||||
|
||||
FactoryBot.create(:address,
|
||||
address1: "25 Myrtle Street",
|
||||
zipcode: "3153",
|
||||
city: "Bayswater",
|
||||
country: country,
|
||||
state: state)
|
||||
FactoryBot.create(:address,
|
||||
address1: "6 Rollings Road",
|
||||
zipcode: "3156",
|
||||
city: "Upper Ferntree Gully",
|
||||
country: country,
|
||||
state: state)
|
||||
FactoryBot.create(:address,
|
||||
address1: "72 Lake Road",
|
||||
zipcode: "3130",
|
||||
city: "Blackburn",
|
||||
country: country,
|
||||
state: state)
|
||||
FactoryBot.create(:address,
|
||||
address1: "7 Verbena Street",
|
||||
zipcode: "3195",
|
||||
city: "Mordialloc",
|
||||
country: country,
|
||||
state: state)
|
||||
FactoryBot.create(:address,
|
||||
address1: "20 Galvin Street",
|
||||
zipcode: "3018",
|
||||
city: "Altona",
|
||||
country: country,
|
||||
state: state)
|
||||
FactoryBot.create(:address,
|
||||
address1: "59 Websters Road",
|
||||
zipcode: "3106",
|
||||
city: "Templestowe",
|
||||
country: country,
|
||||
state: state)
|
||||
FactoryBot.create(:address,
|
||||
address1: "17 Torresdale Drive",
|
||||
zipcode: "3155",
|
||||
city: "Boronia",
|
||||
country: country,
|
||||
state: state)
|
||||
FactoryBot.create(:address,
|
||||
address1: "21 Robina CRT",
|
||||
zipcode: "3764",
|
||||
city: "Kilmore",
|
||||
country: country,
|
||||
state: state)
|
||||
FactoryBot.create(:address,
|
||||
address1: "25 Kendall Street",
|
||||
zipcode: "3134",
|
||||
city: "Ringwood",
|
||||
country: country,
|
||||
state: state)
|
||||
FactoryBot.create(:address,
|
||||
address1: "2 Mines Road",
|
||||
zipcode: "3135",
|
||||
city: "Ringwood East",
|
||||
country: country,
|
||||
state: state)
|
||||
FactoryBot.create(:address,
|
||||
address1: "183 Millers Road",
|
||||
zipcode: "3025",
|
||||
city: "Altona North",
|
||||
country: country,
|
||||
state: state)
|
||||
FactoryBot.create(:address,
|
||||
address1: "310 Pascoe Vale Road",
|
||||
zipcode: "3040",
|
||||
city: "Essendon",
|
||||
country: country,
|
||||
state: state)
|
||||
FactoryBot.create(:address,
|
||||
address1: "6 Martin Street",
|
||||
zipcode: "3160",
|
||||
city: "Belgrave",
|
||||
country: country,
|
||||
state: state)
|
||||
end
|
||||
|
||||
# -- Enterprises
|
||||
if Enterprise.count < 2
|
||||
puts "[#{task_name}] Seeding enterprises"
|
||||
|
||||
3.times do
|
||||
FactoryBot.create(:supplier_enterprise,
|
||||
address: Spree::Address.find_by_zipcode("3160"))
|
||||
end
|
||||
|
||||
FactoryBot.create(:distributor_enterprise,
|
||||
name: "Green Grass",
|
||||
address: Spree::Address.find_by_zipcode("3153"))
|
||||
FactoryBot.create(:distributor_enterprise,
|
||||
name: "AusFarmers United",
|
||||
address: Spree::Address.find_by_zipcode("3156"))
|
||||
FactoryBot.create(:distributor_enterprise,
|
||||
name: "Blackburn FreeGrossers",
|
||||
address: Spree::Address.find_by_zipcode("3130"))
|
||||
FactoryBot.create(:distributor_enterprise,
|
||||
name: "MegaFoods",
|
||||
address: Spree::Address.find_by_zipcode("3195"))
|
||||
FactoryBot.create(:distributor_enterprise,
|
||||
name: "Eco Butchers",
|
||||
address: Spree::Address.find_by_zipcode("3018"))
|
||||
FactoryBot.create(:distributor_enterprise,
|
||||
name: "Western Wines",
|
||||
address: Spree::Address.find_by_zipcode("3106"))
|
||||
FactoryBot.create(:distributor_enterprise,
|
||||
name: "QuickFresh",
|
||||
address: Spree::Address.find_by_zipcode("3155"))
|
||||
FactoryBot.create(:distributor_enterprise,
|
||||
name: "Fooderers",
|
||||
address: Spree::Address.find_by_zipcode("3764"))
|
||||
FactoryBot.create(:distributor_enterprise,
|
||||
name: "Food Local",
|
||||
address: Spree::Address.find_by_zipcode("3134"))
|
||||
FactoryBot.create(:distributor_enterprise,
|
||||
name: "Green Food Trading Corporation",
|
||||
address: Spree::Address.find_by_zipcode("3135"))
|
||||
FactoryBot.create(:distributor_enterprise,
|
||||
name: "Better Food",
|
||||
address: Spree::Address.find_by_zipcode("3025"))
|
||||
FactoryBot.create(:distributor_enterprise,
|
||||
name: "Gippsland Poultry",
|
||||
address: Spree::Address.find_by_zipcode("3040"))
|
||||
end
|
||||
|
||||
# -- Enterprise users
|
||||
if Spree::User.count < 2
|
||||
puts "[#{task_name}] Seeding enterprise users"
|
||||
|
||||
pw = "spree123"
|
||||
|
||||
u = FactoryBot.create(:user,
|
||||
email: "sup@example.com",
|
||||
password: pw,
|
||||
password_confirmation: pw)
|
||||
u.enterprises << Enterprise.is_primary_producer.first
|
||||
u.enterprises << Enterprise.is_primary_producer.second
|
||||
|
||||
user_enterprises = u.enterprise_roles.map{ |er| er.enterprise.name }.join(", ")
|
||||
puts " Supplier User created: #{u.email}/#{pw} (" + user_enterprises + ")"
|
||||
|
||||
u = FactoryBot.create(:user,
|
||||
email: "dist@example.com",
|
||||
password: pw,
|
||||
password_confirmation: pw)
|
||||
u.enterprises << Enterprise.is_distributor.first
|
||||
u.enterprises << Enterprise.is_distributor.second
|
||||
user_enterprises = u.enterprise_roles.map{ |er| er.enterprise.name }.join(", ")
|
||||
puts " Distributor User created: #{u.email}/#{pw} (" + user_enterprises + ")"
|
||||
end
|
||||
|
||||
# -- Enterprise fees
|
||||
if EnterpriseFee.count < 2
|
||||
Enterprise.is_distributor.each do |distributor|
|
||||
FactoryBot.create(:enterprise_fee, enterprise: distributor)
|
||||
end
|
||||
end
|
||||
|
||||
# -- Enterprise Payment Methods
|
||||
if Spree::PaymentMethod.count < 2
|
||||
Enterprise.is_distributor.each do |distributor|
|
||||
FactoryBot.create(:payment_method,
|
||||
distributors: [distributor],
|
||||
name: "Cheque (#{distributor.name})",
|
||||
environment: 'development')
|
||||
end
|
||||
end
|
||||
|
||||
# -- Products
|
||||
if Spree::Product.count < 1
|
||||
puts "[#{task_name}] Seeding products"
|
||||
|
||||
FactoryBot.create(:product,
|
||||
name: 'Garlic',
|
||||
price: 20.00,
|
||||
supplier: Enterprise.is_primary_producer[0],
|
||||
taxons: [Spree::Taxon.find_by_name('Vegetables')])
|
||||
|
||||
FactoryBot.create(:product,
|
||||
name: 'Fuji Apple',
|
||||
price: 5.00,
|
||||
supplier: Enterprise.is_primary_producer[1],
|
||||
taxons: [Spree::Taxon.find_by_name('Fruit')])
|
||||
|
||||
FactoryBot.create(:product,
|
||||
name: 'Beef - 5kg Trays',
|
||||
price: 50.00,
|
||||
supplier: Enterprise.is_primary_producer[2],
|
||||
taxons: [Spree::Taxon.find_by_name('Meat and Fish')])
|
||||
|
||||
FactoryBot.create(:product,
|
||||
name: 'Carrots',
|
||||
price: 3.00,
|
||||
supplier: Enterprise.is_primary_producer[2],
|
||||
taxons: [Spree::Taxon.find_by_name('Meat and Fish')])
|
||||
|
||||
FactoryBot.create(:product,
|
||||
name: 'Potatoes',
|
||||
price: 2.00,
|
||||
supplier: Enterprise.is_primary_producer[2],
|
||||
taxons: [Spree::Taxon.find_by_name('Meat and Fish')])
|
||||
|
||||
FactoryBot.create(:product,
|
||||
name: 'Tomatoes',
|
||||
price: 2.00,
|
||||
supplier: Enterprise.is_primary_producer[2],
|
||||
taxons: [Spree::Taxon.find_by_name('Meat and Fish')])
|
||||
|
||||
FactoryBot.create(:product,
|
||||
name: 'Potatoes',
|
||||
price: 2.00,
|
||||
supplier: Enterprise.is_primary_producer[2],
|
||||
taxons: [Spree::Taxon.find_by_name('Meat and Fish')])
|
||||
end
|
||||
|
||||
enterprise2 = Enterprise.find_by_name('Enterprise 2')
|
||||
enterprise2.sells = 'any'
|
||||
enterprise2.shipping_methods << FactoryBot.create(:shipping_method,
|
||||
name: 'Pickup',
|
||||
zone: zone,
|
||||
require_ship_address: true,
|
||||
calculator_type: 'Calculator::Weight',
|
||||
distributors: [enterprise2])
|
||||
enterprise2.payment_methods << Spree::PaymentMethod.last
|
||||
enterprise2.save!
|
||||
|
||||
variants = Spree::Variant
|
||||
.joins(:product)
|
||||
.where('spree_products.supplier_id = ?', enterprise2.id)
|
||||
|
||||
CreateOrderCycle.new(enterprise2, variants).call
|
||||
|
||||
unless EnterpriseRole.where( user_id: Spree::User.first, enterprise_id: enterprise2 ).any?
|
||||
EnterpriseRole.create!(user: Spree::User.first, enterprise: enterprise2)
|
||||
end
|
||||
display_deprecation_warning
|
||||
end
|
||||
|
||||
def display_deprecation_warning
|
||||
behaviour = ActiveSupport::Deprecation.behavior = :stderr
|
||||
ActiveSupport::Deprecation.behavior = :stderr
|
||||
ActiveSupport::Deprecation.warn(<<WARNING)
|
||||
|
||||
|
||||
This task is going to be replaced by:
|
||||
|
||||
$ bundle exec rake ofn:sample_data
|
||||
|
||||
It contains more sample data.
|
||||
WARNING
|
||||
ActiveSupport::Deprecation.behavior = behaviour
|
||||
end
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user