Rails-server noch ausgeführt wird in einem neuen geöffnet docker-container
Möchte ich für die Bereitstellung meiner rails-Projekt mit Docker. Also ich benutze Docker-Komponieren. Aber ich bekomme eine seltsame Fehlermeldung. Bei Ausführung von docker-Komponieren bis(diese enthält db-container mit postgresql, redis-und web-container mit Schienen), habe ich eine
web_1 | => Booting Puma
rails server -h
web_1 | => Rails 4.2.4 application starting in production on http://0.0.0.0:3000
web_1 | => Runfor more startup options
web_1 | => Ctrl-C to shutdown server
web_1 | A server is already running. Check /usr/src/app/tmp/pids/server.pid.
web_1 | Exiting
Also ich kann nicht verstehen, warum ich diese Nachricht erhalten, weil jedes mal, wenn ich laufen docker-Komponieren, neue Container zu starten, nicht das Vorherige. Auch wenn Sie wollen, löschen Sie diese server.pid
ich bin nicht in der Lage, das zu tun, da diese container nicht ausgeführt wird.
meine docker-Komponieren.yml-Datei
web:
dockerfile: Dockerfile-rails
build: .
command: bundle exec rails s -p 3000 -b '0.0.0.0'
ports:
- "80:3000"
links:
- redis
- db
environment:
- REDISTOGO_URL=redis://user@redis:6379/
redis:
image: redis
db:
dockerfile: Dockerfile-db
build: .
env_file: .env_db
Dockerfile-Schienen
FROM rails:onbuild
ENV RAILS_ENV=production
Ich glaube nicht, dass ich brauche, um alle meine Dockerfiles
UPD: ich habe es behoben, indem ich mich: habe ich einfach gelöscht alle meine Behälter und lief in die docker-compose up
wieder
- in der Konsole kill-server wie
sudo killall -9 ruby
und versuchen Sie es erneut - ich glaube nicht, das ist die Lösung, denn es ist ein Fehler innerhalb des Containers, nicht außerhalb
Du musst angemeldet sein, um einen Kommentar abzugeben.
Verwenden Sie eine onbuild Bild, so dass Sie Ihre Arbeits-Verzeichnis ist gemountet in den container Bild. Das ist sehr gut für die Entwicklung, da Ihre app wird in Echtzeit aktualisiert, wenn Sie Bearbeiten von code und Ihr host-system aktualisiert wird, zum Beispiel wenn Sie eine migration durchführen.
Dies bedeutet auch, dass Ihr host-system tmp-Verzeichnis geschrieben werden mit der pid-Datei jedes mal, wenn ein server läuft, ist und bleibt es, wenn der server nicht ordnungsgemäß heruntergefahren.
Nur führen Sie diesen Befehl von Ihrem host-system:
Kann dies eine echte Schmerzen, wenn Sie zum Beispiel mit Vorarbeiter unter docker-verfassen, da Sie einfach durch drücken von Strg+c wird nicht entfernen Sie die pid-Datei.
server.pid
Datei in meinemtmp/pids
Verzeichnisrm /myapp/tmp/pids/server.pid
vor der Ausführung Vorarbeiter starten.docker-compose run web /bin/bash
und entfernen Sie dann die pid.docker-compose rm web
, da gibt es nichts persistent im containerUnable to find image 'web:latest' locally
da hatte ich es entfernt.docker-compose up
?docker-compose up
starten Sie den rails-serverWar ich etwas verblüfft von dem gleichen problem ein bisschen, bis ich herausfand, was wirklich Los war. Die wirkliche Antwort ist weiter unten... zuerst möchten Sie vielleicht versuchen Sie so etwas wie den folgenden Befehl in Ihrem docker-Komponieren.yml-Datei:
(Ich bin mit Alpine und busybox, um die Dinge winzig, also kein bash! Aber die -c arbeiten mit der bash zu), wird die Datei löschen, wenn es vorhanden ist, so dass Sie nicht bekommen, stecken mit dem problem, dass der container hält Austritt und dort zu sitzen, nicht in der Lage, um Befehle auszuführen.
Leider ist das KEINE gute Lösung, weil Sie hinzufügen eine zusätzliche Schicht von /bin/sh vor den server und verhindert, dass die server immer der stop-Befehl. Das Ergebnis ist, dass die docker stop Befehle nicht geben, ein ordnungsgemäßes beenden und das problem wird immer wieder passieren.
Könnten Sie führen Sie einfach den rm-Befehl mit docker-Komponieren bis zu entfernen Sie die Datei und ändern Sie dann den Befehl an den server zurück und tragen auf.
Aber die wirkliche Antwort ist das erstellen einer einfachen docker-entry.sh Datei, und stellen Sie sicher, dass Sie nennen es die Verwendung der exec-form Entrypoint-Dokumentation so, dass die Signale (wie z.B. stop) bekommen für den server-Prozess.
HINWEIS: wir verwenden exec auf die Letzte Zeile, um sicherzustellen, dass die Schienen so ausgeführt wird, wie pid 1 (d.h. keine extra Schale) und bekommen somit die Signale zu stoppen. Und dann im Dockerfile (oder verfassen.yml-Datei) fügen Sie den entrypoint und Befehl
Wieder verwenden, MÜSSEN Sie die [] - format, so dass es exec würde statt der "ausführen als" sh -c ""
chmod +x docker-entrypoint.sh
so lösen Sie einen permission denied-Fehler.&&
ist ein hack. Wenn es das ist, was Sie wollen, können Sie ersetzen die&&
mit einem;
. Aber eine bessere Lösung ist das ändern der if-Anweisung in der vorgeschlagenendocker-entrypoint.sh
. Bedenken Sie jedoch, dass jede Lösung wird es unmöglich machen, starten Sie den container, wenn es ordnungsgemäß heruntergefahren wurde, da dass entfernen der PID-Datei, was zu einer Fehlermeldung, die Sie wünschen.chmod +x docker-entrypoint.sh
, aber dieses lokal, vor dem Gebäude der Bild! Ich Verschwendete eine Stunde oder mehr versucht, führen Sie diesen Befehl in meine Dockerfile -, die nicht schwer ?Was ich getan habe, Ist, gehen Sie auf die bash-shell von docker:
docker-compose run web /bin/bash
dann entfernen Sie die folgende Datei
rm tmp/pids/server.pid
Hoffe, dass es hilft!
für meine Arbeit:
und gehen Sie dann Ordner für Ordner mit dem Befehl cd (ich benutze win 7 toolbox)
also im Endeffekt benutze ich in der bash :
rm tmp/pids/server.pid
Dies ist eine angepasste version von Brendon Whateleys ? Antwort für
Docker Compose-Lösung
1. Erstellen docker-entrypoint.sh
2. Passen Sie Ihre docker-Komponieren.yml
Beachten Sie, dass Sie haben, um den Pfad zu dem Sie montiert Ihre app, sprich:
/myapp
2.5 Wenn Sie Begegnung ein Fehler der Zugriffsrechte
Befehl in Ihrem terminal vor läuft
docker-compose up
oder bauen Sie Ihr Bild. Dank sajadghawami.3. Genießen, nie mehr server entfernen.pid manuell wieder
?
Für diejenigen, die problem haben, wenn es keine
tmp/pids/server.pid
tatsächlich existiert:(Docker version 1.11.2, bauen b9f10c9)
Lösung, die für mich gearbeitet hat ist das hinzufügen der genauen Befehl
docker-compose.yml
zum Beispiel:Dass dieser Befehl, der in der Tat kann einfach duplizieren Dockerfile das CMD - Problem mit veralteten
.pid
werden nicht angezeigt.Andere option, wenn Sie müssen, verwenden Sie Dockerfile die CMD, ausführen mit die option
--build
zum Wiederaufbau Bild:Obwohl es dauert Zeit, also erste Lösung ist bequemer
Wenn Sie abenteuerlustig fühlen Sie sich frei, um die Suche für die server.pid in die codebase und prüfen, wo die pid wird immer geschrieben. So können Sie prüfen, ob Sie nicht erlauben, es zu schreiben, behebt das root problem für Sie. Weil anscheinend der pid-Erstellung hilft verhindern Sie die Ausführung von doppelten Leistungen in zwei verschiedene docker-Containern. Aber das sollte sich gekümmert werden im Andockfenster, wie es ist. Wenn aus irgendeinem Grund, Sie nicht, werden die port-Kollision Methodik sollte auf jeden Fall aufpassen und Sie warnen. Hinweis: ich habe nicht versucht, diesen Ansatz als noch so bewegt, dass das system im Allgemeinen:)
Alternativ hätte man die Kommandos im Makefile. Wo die Aufgabe ist diese:
Aufgabe:
docker-verfassen-stop service_name
docker-verfassen rm service_name
rm -f ./tmp/pids/server.pid (oder relativen Pfadnamen Ihre pid-Datei)
docker-Komponieren bis service_name
Dann vrooom
make task
im terminal und drücken Sie die EINGABETASTE.Die oben genannten task-Befehle setzen Voraus, dass der service, den Sie ausführen möchten, sind in einer Datei namens docker-Komponieren.yml
Wenn der name ein anderer ist, dann den Befehl
docker-verfassen-stop service_name --> Andockfenster-Komponieren -f your-Komponieren-mit dem Namen.yml stop service_name
so weiter und so Fort.
====================
Kam wieder zu aktualisieren. So, ich habe versucht mit auskommentieren meine write_pid Methode Funktionalität. Grundsätzlich halten die Methode-definition, aber nicht alles tun. Es funktioniert gut so weit. Es schreibt nicht die pid überhaupt. Wenn Sie Ihre Dienste im Andockfenster, ich glaube, das ist völlig sicher.
In Ihrem docker-Komponieren.yml-Datei, unter der Anwendung container selbst, können Sie entweder:
oder
der Grund für entweder ";" oder "&&" ist, dass letztere senden wird ein exit-signal, wenn rm nicht finden die Datei, zwingen Sie Ihren container vorzeitig zu beenden. die Vorherige wird auch weiterhin ausgeführt.
warum ist dies verursacht in den ersten Platz? die rationale ist, dass wenn der server (puma/Dünn/was auch immer) nicht sauber verlassen werden, hinterlässt es eine pid in der host-Maschine verursacht eine exit-Fehler.