2015-02-26 1 views
2

J'utilise Fig et j'essaie d'utiliser un conteneur de volume de données pour partager des fichiers téléchargés entre un serveur Web Rails et un worker Resque exécuté dans un autre conteneur. Pour ce faire, le conteneur de volume de données définit un volume /rails/public/system destiné à être utilisé pour partager ces fichiers. Les processus Rails et Resque s'exécutent en tant qu'utilisateur rails dans leurs conteneurs respectifs, tous deux basés sur l'image markb/litdistco. Tous ensemble le fig.yml ressemble à ceci:Comment puis-je monter un volume à partir d'un conteneur de données tout en préservant le propriétaire et les autorisations?

redis: 
    image: redis:2.8.17 
    volumes_from: 
    - file 
web: 
    image: markb/litdistco 
    command: /usr/bin/start-server /opt/nginx/sbin/nginx 
    ports: 
    - 80:8000 
    - 443:4430 
    environment: 
    DATABASE_URL: 
    links: 
    - redis 
    volumes_from: 
    - file 
worker: 
    image: markb/litdistco 
    command: /usr/bin/start-server "bundle exec rake environment resque:work QUEUE=litdistco_offline RAILS_ENV=production" 
    environment: 
    DATABASE_URL: 
    links: 
    - redis 
    volumes_from: 
    - file 
file: 
    image: markb/litdistco 
    command: echo "datastore" 
    volumes: 
    - /var/redis 
    - /rails/log 
    - ./config/container/ssl:/etc/ssl 

Lorsque les web et worker conteneurs sont en cours d'exécution, je peux voir le répertoire /rails/public/system dans les deux, mais il appartient à l'utilisateur root dans les deux conteneurs et les autorisations sur le répertoire empêche l'utilisateur rails d'écrire dans ce répertoire. Pour référence, il y a deux fichiers Docker qui entrent dans la fabrication du conteneur markb/litdistco. La première définit une image de base que j'utilise pour le développement local (Dockerfile):

# This Dockerfile is based on the excellent blog post by SteveLTN: 
# 
# http://steveltn.me/blog/2014/03/15/deploy-rails-applications-using-docker/ 
# 
# KNOWN ISSUES: 
# 
# * Upgrading passenger or ruby breaks nginx directives with absolute paths 

# Start from Ubuntu base image 
FROM ubuntu:14.04 

MAINTAINER Mark Bennett <[email protected]> 

# Update package sources 
RUN apt-get -y update 

# Install basic packages 
RUN apt-get -y install build-essential libssl-dev curl 

# Install basics 
RUN apt-get -y install tmux vim 
RUN apt-get install -y libcurl4-gnutls-dev 

# Install libxml2 for nokogiri 
RUN apt-get install -y libxslt-dev libxml2-dev 

# Install mysql-client 
RUN apt-get -y install mysql-client libmysqlclient-dev 

# Add RVM key and install requirements 
RUN command curl -sSL https://rvm.io/mpapis.asc | gpg --import - 
RUN curl -sSL https://get.rvm.io | bash -s stable 
RUN /bin/bash -l -c "rvm requirements" 

# Create rails user which will run the app 
RUN useradd rails --home /rails --groups rvm 

# Create the rails users home and give them permissions 
RUN mkdir /rails 
RUN chown rails /rails 

RUN mkdir -p /rails/public/system 
RUN chown rails /rails/public/system 
# Add configuration files in repository to filesystem 
ADD config/container/start-server.sh /usr/bin/start-server 
RUN chown rails /usr/bin/start-server 
RUN chmod +x /usr/bin/start-server 

# Make a directory to contain nginx and give rails user permission 
RUN mkdir /opt/nginx 
RUN chown rails /opt/nginx 

# Switch to rails user that will run app 
USER rails 

# Install rvm, ruby, bundler 
WORKDIR /rails 
ADD ./.ruby-version /rails/.ruby-version 
RUN echo "gem: --no-ri --no-rdoc" > /rails/.gemrc 
RUN /bin/bash -l -c "rvm install `cat .ruby-version`" 
RUN /bin/bash -l -c "gem install bundler --no-ri --no-rdoc" 

# Install nginx 
RUN /bin/bash -l -c "gem install passenger --no-ri --no-rdoc" 
RUN /bin/bash -l -c "passenger-install-nginx-module" 
ADD config/container/nginx-sites.conf.TEMPLATE /opt/nginx/conf/nginx.conf.TEMPLATE 
ADD config/container/set-nginx-paths.sh /rails/set-nginx-paths.sh 
RUN /bin/bash -l -c "source /rails/set-nginx-paths.sh" 

# Copy the Gemfile and Gemfile.lock into the image. 
# Temporarily set the working directory to where they are. 
WORKDIR /tmp 
ADD Gemfile Gemfile 
ADD Gemfile.lock Gemfile.lock 

# bundle install 
RUN /bin/bash -l -c "bundle install" 

# Add rails project to project directory 
ADD ./ /rails 

# set WORKDIR 
WORKDIR /rails 

# Make sure rails has the right owner 
USER root 
RUN chown -R rails:rails /rails 

# Publish ports 
EXPOSE 3000 
EXPOSE 4430 
EXPOSE 8000 

Ceci est étiqueté comme l'image litdistco-base, puis-je utiliser config/containers/production/Dockerfile pour générer l'image que je balise comme markb/litdistco et exécuter la mise en scène et la production.

# Start from LitDistCo base image 
FROM litdistco-base 

MAINTAINER Mark Bennett <[email protected]> 

USER rails 

# Setup volumes used in production 
VOLUME ["/rails/log", "/rails/public/system"] 

# Build the application assets 
WORKDIR /rails 
RUN /bin/bash -l -c "touch /rails/log/production.log; chmod 0666 /rails/log/production.log" 
RUN /bin/bash -l -c "source /etc/profile.d/rvm.sh; bundle exec rake assets:precompile" 

Quelqu'un peut-être expliquer comment je peux obtenir le volume de conteneur de données à monter comme inscriptible par l'utilisateur rails. J'aimerais beaucoup éviter d'exécuter les processus Ruby en tant que root, même à l'intérieur d'un conteneur. Dans un contexte, je dois également mentionner que je développe les images dans Docker dans boot2docker sur Mac OS X, puis les exécute sur une instance de Google Compute Engine sur un hôte Ubuntu 14.04. Merci!

+0

J'ai aussi eu ce problème avec les volumes postgres. – Greg

Répondre

2

Je voudrais modifier votre image un peu. Écrivez un script shell qui enveloppe la commande/usr/bin/start-server dans votre fig.yml et placez-le dans votre conteneur.

Ensuite, vous pouvez choisir les rails dont vous avez besoin avant de démarrer votre serveur.

L'exécution du conteneur avec des rails utilisateur par défaut n'est pas vraiment nécessaire non plus, tant que vous démarrez le serveur en tant qu'utilisateur rails: sudo -u rails/usr/bin/start-server (ou quelque chose comme ça).

Personnellement, nous n'avons pas encore utilisé l'image litdistco-base, donc nous ne connaissons pas tous les détails sur son fonctionnement.

+0

Ce n'est pas exactement la réponse que j'aimerais, car je voudrais éviter que le conteneur accède à l'utilisateur root, mais cela résoudrait définitivement mon problème et permettrait à l'application de fonctionner correctement sans avoir besoin de déplacer mon serveur web et mon worker dans le même conteneur. –