-
Notifications
You must be signed in to change notification settings - Fork 23
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
Solargraph with Docker #26
Comments
I don't know enough about docker to provide any specific advice. I can tell you that Solargraph needs to be able to resolve the gem paths in order to provide completion and documentation for them. It'll try to use your Gemfile to do so. |
Thank you for answer my issue. |
Thanks! Solargraph uses the runtime load paths to find gems. The extension starts the server process using your open folder as the current working directory, so if you have any files in the root that would affect the environment, such as a Gemfile or a .ruby-version file, it should use them automatically. You might encounter a problem if your container has its own gem cache or makes any other changes to the runtime environment. I'm not sure if anything special needs to be done to start the process using the environment defined by the container. It might require an enhancement; for example, there's currently no mechanism for explicitly setting load paths. One workaround might be to install the same gems the container uses to your system Ruby environment, where Solargraph should be able to detect them. I'm open to enhancements or features to improve Docker support if necessary. Any help you can provide is appreciated, whether it's bug reports, suggestions, or pull requests. |
Would love this feature |
Me too. This is what I'm looking for since I use docker. |
All you should be doing to develop with Docker is to mount your project directory, as a volume, into the Docker container. You edit your files locally. |
Isn't it necessary to mount the bundle directory as a volume and link it into my develop folder as well? Or needs Solargraph just access to the Gemfile? |
Docker support would be great, and more importantly support to work within a docker compose stack. I am working on a reference project and enhancements to vscode-ruby to provide a nice debugging experience when using docker compose and might look at how this can spill over to this extension next. Ideally I want to never have to install gems locally and have things like Solargraph work with the gems that have been installed inside the container (perhaps by starting the server inside a container and connecting to that instead), but even in the case of debugging I still need to install gems locally right now to provide the ability to step into gem sources without volume binds which I found in some environments was not ideal. I am not sure there will be an easy one size fits all solution but if anyone wants to get together and chat about it and share some ideas it would be great as going forward solving the Docker story is going to be beneficial and definitely something I want to help with. |
I've also been looking into docker with solargraph. From what I can tell (and please correct me if i'm wrong): Solargraph has a server (the gem) that can generates all of the information the solargraph vs extensions needs about your code. The communicates to vs by using event machine and exposing a connection over port 7658. What I tried doing is running the solargaph server in a separate docker container pointing to the source code of my ruby app on my machine along side my other dockers (web, db)
While this seems to start okay. I cant seem to communicate with solargraph on that port from my host. Within the solar container using wget I can a connection. But from the host nothing seems to reply on that port. Has anyone tried this, or had any luck doing something similar? |
This Dockerfile by Sourcegraph might be helpful: https://hub.docker.com/r/sourcegraph/codeintel-ruby/ |
@castwide Wish the Dockerfile was easy to find... |
I have dug a bit further into this and spun up the VS code extension and stepped through what is going on. From what I can tell my above docker setup should work file. But the VS extension itself would need to be changed to point to the port docker is exposing and to not start its own copy of solargraph. In the solargraph-utils project there is code the extension depends on that handles socket provisioning and starting of solargraph (SocketProvider.js). Below you can see it starts the solargraph gem on the local machine (command_1) with the port 0 option. Solargraph server then starts on the next available port. Once started the code parses out what port was allocated then returns that back to the solargraph extension.
To be able to connect the VS extension to a running docker instance this code would need to be changed to allow choosing a port and to be told not to start a local instance of solargraph (otherwise it throws an error). It is late here will explore further over the next couple days. |
Great find! If that's the case, it seems like having an option to specify the port within VS Code's settings (and have it auto select like it currently does if that option is empty) shouldn't be that difficult. |
The SocketProvider's primary purpose is to acquire an available port to avoid conflicts, e.g., if you're running multiple VS Code windows. If we add an option to specify the port, vscode-solargraph should be able to bypass the SocketProvider altogether. There are a couple other issues to consider, but overall I think this is feasible. |
Of course! I hadn't considered to possibility of multiple instances of VS. I thought it was just good house keeping on your part (Always making sure it uses a free port). I will have a hack at the code. To see if I hard code things it will work. If so then I can work with Fred to come up with a patch if that suits everyone? |
@RtypeStudios If you can work with me on a patch, I'm happy to merge it into the extension. You seem like a good subject matter expert where Docker is involved. Let me know if you have any problems in development. |
The (slightly misnamed)
I expect to support a |
@castwide Thanks! Sorry, I haven't got back to you about all this yet. I've been pulled off onto an urgent project. Will try and take a look this weekend. |
This feature is now in the master branch. The supported transports are socket, stdio, and external. The configuration to connect to an external server should look something like this:
This feature is still open to change. I'm not even sure if it's the best solution for Docker integration, although it seems like it does the job for the most part. One known issue: the server shuts down when the client disconnects. That probably shouldn't happen with external transports. |
@castwide Thank you for adding that in! I've just been giving it a try but haven't had much luck. Just to make sure I'm doing the right thing these are the steps I took:
I still get the cant contact server error. I added the following to the select client method to make sure my config is loaded. But it doesn't seem to be hit.
Any ideas what I'm doing wrong? Sorry debugging vs code extensions is new to me. Thanks heaps for adding the feature, really appreciate it! I'm sure I'm just doing something daft. |
@RtypeStudios 2 issues I see:
|
Version 0.18.0 is released with the |
So I run
in my vs code settings but I get |
@MilanJansenOGD Are there any more detailed error messages in the developer console (Help -> Toggle Developer Tools)? |
I've disabled all other extensions and tried again, nothing comes up in the dev tools console. If I run the check gem version command I get
Which I figure is just because either im not running solargraph locally on windows or that the connection isn't made. |
@castwide first of all, thank you for your work!
After completing those steps both hovers and go to definition seems to work fine for both local app and installed gems. The only "issue" is that for gems installed with bundler it sometimes takes ~5 seconds to process go to definition, not really sure if that's expected behaviour or maybe something wrong with my setup. UPDATE: UPDATE2: |
Hi @mvoropaiev |
Hello @sanjibukai FROM ruby:2.5-alpine
# set up required group, user and directory
ARG WORKER_UID=1000
ARG WORKER_GID=1000
ARG APP_DIR=/usr/src/app
RUN set -ex \
&& delgroup "dialout" \
&& addgroup -g "$WORKER_GID" -S 'worker' \
&& adduser -u "$WORKER_UID" -G 'worker' -S -s '/bin/false' -h "$APP_DIR" 'worker' \
&& mkdir -p "$APP_DIR" \
&& chown -R worker:worker "$APP_DIR"
WORKDIR $APP_DIR
ENV GEM_HOME $APP_DIR/vendor/bundle
ENV BUNDLE_PATH="$GEM_HOME" \
BUNDLE_SILENCE_ROOT_WARNING=1 \
BUNDLE_APP_CONFIG="$GEM_HOME"
# path recommendation: https://github.com/bundler/bundler/pull/6469#issuecomment-383235438
ENV PATH $GEM_HOME/bin:$BUNDLE_PATH/gems/bin:$PATH
# adjust permissions of a few directories for running "gem install" as an arbitrary user
RUN mkdir -p "$GEM_HOME" && chmod 777 "$GEM_HOME"
# (BUNDLE_PATH = GEM_HOME, no need to mkdir/chown both)
USER "worker"
# install required gems
COPY --chown=worker:worker Gemfile .
COPY --chown=worker:worker Gemfile.lock .
RUN set -ex \
&& bundle install
# copy application code
COPY --chown=worker:worker . .
# other build steps... this way, when building docker image normally, gems will end up in project directory inside and for local development i was using the following for docker-compose.yml # for skipping bundle install and migrations: skip_init=1 docker-compose up app
version: '2.1'
services:
app:
build:
context: .
args:
# id -u
WORKER_UID: 501
# id -g
WORKER_GID: 20
APP_DIR: $PWD
working_dir: $PWD
volumes:
- .:$PWD
environment:
SKIP_INIT: ${skip_init}
# other configuration options... this way it sets up project directory in container to be the same as your project directory locally and mounts it (as well as having correct file permissions due to worker user having the same ID as my local one) one thing left is to make entrypoint script do a #!/bin/sh
set -e
case $RAILS_ENV in
development)
bundle config --delete frozen
[ -z "$SKIP_INIT" ] && bundle install
;;
test)
bundle exec rake db:schema:load --trace
;;
staging | production)
mkdir -p ./public/assets
mv ./public/assets_tmp/* ./public/assets/
;;
*)
printf 'Unknown RAILS_ENV value "%s"\n' "${RAILS_ENV:-<none>}"
printf 'Valid values: development|test|staging|production\n'
exit 1
;;
esac
[ -z "$SKIP_INIT" ] && bundle exec rake db:migrate --trace
exec "$@" Hope that helps, sorry, don't have time to set up a sample project, but please let me know if you need some help! |
I use Docker Compose for my dev environment, and Solargraph running on the host machine with VS Code. I just do a |
@dogweather yeah, I think that's only way to go for now, at least on Mac OS, having two sets of gems is not that bad as poor performance 👍 |
@MilanJansenOGD I believe you got confused (as I did) between SOLARgraph and SOURCEgraph. 😄 no wonder the different port number, the error you received.. sigh |
The folks at microsoft are working on core support for development inside a docker container: https://code.visualstudio.com/docs/remote/containers I'm able to run solargraph inside my docker container this way, but I've found it to be unreliable (crashes, hangs at 100% CPU, etc). @castwide have you had a chance to try the extension with new the "Remote Development" feature? |
I've had some good success with the following approach. Here's what I'm able to get: I use a dedicated container to run solargraph and connect to it from VS Code using the Requirements:
Code: {
"solargraph.externalServer": {
"host": "localhost",
"port": 8091
},
"solargraph.transport": "external",
"solargraph.logLevel": "debug",
"solargraph.diagnostics": true,
"solargraph.hover": false
}
FROM ruby:2.6.3
# Update the version of RubyGems
RUN gem update --system 3.0.4 \
# Update the version of Bundler
&& gem install bundler -v 2.0.2 \
# Install gems
WORKDIR /tmp
COPY Gemfile Gemfile.lock ./
RUN bundle install -j 4
WORKDIR /home/ruby
# Install gem documentation
RUN bundle exec yard gems
version: "3.7"
services:
solargraph:
build: .
command: 'bundle exec solargraph socket --host=0.0.0.0 --port=7658'
working_dir: /my_code
volumes:
- ./:/my_code
- gem_documentation:/home/ruby/.yard
ports:
- target: 7658
published: 8091
|
@benjaminwood this gem was the first thing that came to mind when I read about the remote features for VSC. Also interested to hear about it. |
I'm looking into using remote features for Docker integration. There's a related issue for machine scope configurations: #126 |
Extension 0.21.0 supports remote setups. I've been using it to work on a Linux machine from Windows over SSH. |
Thanks @castwide can't wait to give it a try! |
I had to launch solargraph using |
Has anyone been able to get intellisense working for any of their own classes when running solargraph in a docker container? I'm not, but I'm guessing the cause of the problem is that locally the path to my files is |
@dhughes are you using the remote containers extension to run VS code in docker? https://code.visualstudio.com/docs/remote/containers If so, I wouldn't expect you to have the path issue you described. |
Hello all! EDIT: My bad, I had solargraph misconfigured for my specific container, adding these options solved problem: |
Hey, [WARN] /usr/local/bundle/gems/bundler-2.2.26/lib/bundler/source/git.rb:206:in `rescue in load_spec_files': LINK_TO_OUR_PRIVATE_GIT_REPO is not yet checked out. Run `bundle install` first. (Bundler::GitError)
from /usr/local/bundle/gems/bundler-2.2.26/lib/bundler/source/git.rb:202:in `load_spec_files'
from /usr/local/bundle/gems/bundler-2.2.26/lib/bundler/source/path.rb:107:in `local_specs'
from /usr/local/bundle/gems/bundler-2.2.26/lib/bundler/source/git.rb:170:in `specs'
from /usr/local/bundle/gems/bundler-2.2.26/lib/bundler/lazy_specification.rb:72:in `__materialize__'
from /usr/local/bundle/gems/bundler-2.2.26/lib/bundler/spec_set.rb:75:in `block in materialize'
from /usr/local/bundle/gems/bundler-2.2.26/lib/bundler/spec_set.rb:72:in `map!'
from /usr/local/bundle/gems/bundler-2.2.26/lib/bundler/spec_set.rb:72:in `materialize'
from /usr/local/bundle/gems/bundler-2.2.26/lib/bundler/definition.rb:477:in `materialize'
from /usr/local/bundle/gems/bundler-2.2.26/lib/bundler/definition.rb:228:in `specs_for'
from /usr/local/bundle/gems/bundler-2.2.26/lib/bundler/runtime.rb:18:in `setup'
from /usr/local/bundle/gems/bundler-2.2.26/lib/bundler.rb:149:in `setup'
from /usr/local/bundle/gems/bundler-2.2.26/lib/bundler/setup.rb:20:in `block in <top (required)>'
from /usr/local/bundle/gems/bundler-2.2.26/lib/bundler/ui/shell.rb:136:in `with_level'
from /usr/local/bundle/gems/bundler-2.2.26/lib/bundler/ui/shell.rb:88:in `silence'
from /usr/local/bundle/gems/bundler-2.2.26/lib/bundler/setup.rb:20:in `<top (required)>'
from /usr/lib/ruby/2.6.0/rubygems/core_ext/kernel_require.rb:54:in `require'
from /usr/lib/ruby/2.6.0/rubygems/core_ext/kernel_require.rb:54:in `require'
/usr/local/bundle/gems/bundler-2.2.26/lib/bundler/source/path.rb:209:in `load_spec_files': The path `/usr/local/bundle/bundler/gems/OUR_PRIVATE_REPO` does not exist. (Bundler::PathError)
from /usr/local/bundle/gems/bundler-2.2.26/lib/bundler/source/git.rb:203:in `load_spec_files'
from /usr/local/bundle/gems/bundler-2.2.26/lib/bundler/source/path.rb:107:in `local_specs'
from /usr/local/bundle/gems/bundler-2.2.26/lib/bundler/source/git.rb:170:in `specs'
from /usr/local/bundle/gems/bundler-2.2.26/lib/bundler/lazy_specification.rb:72:in `__materialize__'
from /usr/local/bundle/gems/bundler-2.2.26/lib/bundler/spec_set.rb:75:in `block in materialize'
from /usr/local/bundle/gems/bundler-2.2.26/lib/bundler/spec_set.rb:72:in `map!'
from /usr/local/bundle/gems/bundler-2.2.26/lib/bundler/spec_set.rb:72:in `materialize'
from /usr/local/bundle/gems/bundler-2.2.26/lib/bundler/definition.rb:477:in `materialize'
from /usr/local/bundle/gems/bundler-2.2.26/lib/bundler/definition.rb:228:in `specs_for'
from /usr/local/bundle/gems/bundler-2.2.26/lib/bundler/runtime.rb:18:in `setup'
from /usr/local/bundle/gems/bundler-2.2.26/lib/bundler.rb:149:in `setup'
from /usr/local/bundle/gems/bundler-2.2.26/lib/bundler/setup.rb:20:in `block in <top (required)>'
from /usr/local/bundle/gems/bundler-2.2.26/lib/bundler/ui/shell.rb:136:in `with_level'
from /usr/local/bundle/gems/bundler-2.2.26/lib/bundler/ui/shell.rb:88:in `silence'
from /usr/local/bundle/gems/bundler-2.2.26/lib/bundler/setup.rb:20:in `<top (required)>'
from /usr/lib/ruby/2.6.0/rubygems/core_ext/kernel_require.rb:54:in `require'
from /usr/lib/ruby/2.6.0/rubygems/core_ext/kernel_require.rb:54:in `require'
[Solargraph::BundleNotFoundError] Failed to load gems from bundle at .
No bundled gems are available in . Then I run Bundle complete! 56 Gemfile dependencies, 164 gems now installed.
Bundled gems are installed into `/usr/local/bundle` Moreover running /usr/local/bundle/ruby/2.6.0/bundler/gems/OUR_PRIVATE_REPO So it seems that "solargraph.transport": "external",
"solargraph.commandPath": "/usr/local/bundle/bin/solargraph",
"solargraph.bundlerPath": "/usr/local/bin/bundle",
"solargraph.externalServer": {
"host": "localhost",
"port": 7658
} Any ideas what is wrong here? |
You guys might want to dig into this extension for VSCode. Along with some more explanations on how to open a Folder from a container in vscode here Got the tip on a google search where this dude delivers some info around all this, didn't work exactly like it for me, but still some useful info there: |
I'm using docker in my rails app. How can I work with Solargraph and Docker? Is there any configuration to do?
The text was updated successfully, but these errors were encountered: