docker-compose build app
docker-compose up
docker-compose run --rm app bundle # Gemfile change
docker compose exec app rake db:create
Thanks to @jfahrer for the Railsconf talk that taught me this
version: '3.7' | |
services: | |
app: | |
image: your_user_name_here/appname:v1 | |
build: | |
context: . | |
command: ["spring", "server"] | |
environment: | |
- POSTGRES_HOST=pg | |
- POSTGRES_USER=postgres | |
- POSTGRES_PASSWORD=secret | |
- RAILS_ENV | |
volumes: | |
- ./:/usr/src/app | |
- gems:/usr/local/bundle | |
- node-modules:/usr/src/app/node_modules | |
- ${HOME}/.irbrc:/root/.irbrc | |
- ${HOME}/.irb-history:/root/.irb-history | |
web: | |
image: your_user_name_here/appname:v1 | |
command: ["rails", "server", "-b", "0.0.0.0"] | |
environment: | |
- POSTGRES_HOST=pg | |
- POSTGRES_USER=postgres | |
- POSTGRES_PASSWORD=secret | |
- RAILS_ENV | |
volumes: | |
- ./:/usr/src/app | |
- gems:/usr/local/bundle | |
- node-modules:/usr/src/app/node_modules | |
ports: | |
- 3000:3000 | |
pg: | |
image: postgres:11.2-alpine | |
volumes: | |
- pg-data:/var/lib/postgresql/data | |
environment: | |
- POSTGRES_USER=postgres | |
- POSTGRES_PASSWORD=secret | |
webpacker: | |
image: your_user_name_here/appname:v1 | |
command: ./bin/webpack-dev-server | |
volumes: | |
- ./:/usr/src/app | |
- gems:/usr/local/bundle | |
- node-modules:/usr/src/app/node_modules | |
ports: | |
- 3035:3035 | |
volumes: | |
gems: | |
pg-data: | |
node-modules: |
FROM ruby:2.6.5-alpine | |
RUN apk add --update --no-cache bash build-base nodejs sqlite-dev tzdata postgresql-dev yarn | |
RUN gem install bundler:2.1.4 | |
WORKDIR /usr/src/app | |
COPY package.json yarn.lock ./ | |
RUN yarn install --check-files | |
COPY Gemfile* ./ | |
RUN bundle install | |
COPY . . | |
ENV PATH=./bin:$PATH | |
CMD ["rails", "console"] | |
# config/webpacker.yml | |
# Note: You must restart bin/webpack-dev-server for changes to take effect | |
default: &default | |
source_path: app/javascript | |
source_entry_path: packs | |
public_root_path: public | |
public_output_path: packs | |
cache_path: tmp/cache/webpacker | |
check_yarn_integrity: false | |
webpack_compile_output: false | |
# Additional paths webpack should lookup modules | |
# ['app/assets', 'engine/foo/app/assets'] | |
resolved_paths: [] | |
# Reload manifest.json on all requests so we reload latest compiled packs | |
cache_manifest: false | |
# Extract and emit a css file | |
extract_css: false | |
static_assets_extensions: | |
- .jpg | |
- .jpeg | |
- .png | |
- .gif | |
- .tiff | |
- .ico | |
- .svg | |
- .eot | |
- .otf | |
- .ttf | |
- .woff | |
- .woff2 | |
extensions: | |
- .mjs | |
- .js | |
- .sass | |
- .scss | |
- .css | |
- .module.sass | |
- .module.scss | |
- .module.css | |
- .png | |
- .svg | |
- .gif | |
- .jpeg | |
- .jpg | |
development: | |
<<: *default | |
compile: true | |
# Verifies that versions and hashed value of the package contents in the project's package.json | |
# check_yarn_integrity: true | |
# Reference: https://webpack.js.org/configuration/dev-server/ | |
dev_server: | |
https: false | |
host: webpacker | |
port: 3035 | |
public: localhost:3035 | |
hmr: true | |
# Inline should be set to true if using HMR | |
inline: true | |
overlay: true | |
compress: true | |
disable_host_check: true | |
use_local_ip: false | |
quiet: false | |
headers: | |
'Access-Control-Allow-Origin': '*' | |
watch_options: | |
ignored: '**/node_modules/**' | |
test: | |
<<: *default | |
compile: true | |
# Compile test packs to a separate directory | |
public_output_path: packs-test | |
production: | |
<<: *default | |
# Production depends on precompilation of packs prior to booting for performance. | |
compile: false | |
# Extract and emit a css file | |
extract_css: true | |
# Cache manifest.json for performance | |
cache_manifest: true |
Thanks for this! I'm running into a problem where the dev server is not behaving as expected:
My config/webpacker.yml
is exactly like yours, with host: webpacker
and public: localhost:3035
but still my browser tries to connect to webpacker:3035
. From my understanding, host:
tells Docker where the dev server is and public:
is supposed to be used by browsers because webpacker:3035
is reachable only from inside containers.
Not sure if this is a problem with Webpack or webpacker 🤔
@awendt, did you ever figure this out? I had similar issues, and it turned out i was setting some WEBPACKER_DEV_SERVER* env variables in my webpacker service (in docker-compose.yml). And according to webpacker readme these need to match env variables for the rails app.
You can use environment variables as options supported by webpack-dev-server in the form WEBPACKER_DEV_SERVER_. Please note that these environmental variables will always take precedence over the ones already set in the configuration file, and that the same environmental variables must be available to the rails server process.
I think having RUN bundle install
is somewhat incompatible with having the gems:/usr/local/bundle
volume in docker-compose. Basically, on running the container, it's bundle folder will immediately be replaces by the contents of /gems
. Of course, you still want the gems in the image for pushing, but in this case you might as well just copy them in COPY /gems /usr/local/bundle
The purpose of the volume is to persist the gems, so you only have to run bundle install
in case the Gemfile
changes (same with the node_modules
).
Dockerfile failed to build on line #9.
How should I provide that from host system.
COPY failed: file not found in build context or excluded by .dockerignore: stat package.json: file does not exist
Thanks! I had to change the
web
command to:command: bin/rails server -b 0.0.0.0
otherwise the Rails app was not available onhttp://localhost:3000
.