One place for hosting & domains

      Docker

      How To Remotely Access GUI Applications Using Docker and Caddy on Ubuntu 18.04


      The author selected the Free and Open Source Fund to receive a donation as part of the Write for DOnations program.

      Introduction

      Even with the growing popularity of cloud services, the need for running native applications still exists.

      By using noVNC and TigerVNC, you can run native applications inside a Docker container and access them remotely using a web browser. Additionally, you can run your application on a server with more system resources than you might have available locally, which can provide increased flexibility when running large applications.

      In this tutorial, you’ll containerize Mozilla Thunderbird, an email client, using Docker. Afterward, you’ll secure it and provide remote access using the Caddy web server.

      When you’re finished, you’ll be able to access Thunderbird from any device using just a web browser. Optionally, you’ll also be able to locally access the files from it using WebDAV. You’ll also have a fully self-contained Docker image that you can run anywhere.

      Prerequisites

      Before you begin this guide, you’ll need the following:

      Step 1 — Creating the supervisord Configuration

      Now that your server is running and Docker is installed, you are ready to begin configuring your application’s container. Since your container consists of multiple components, you need to use a process manager to launch and monitor them. Here, you’ll be using supervisord. supervisord is a process manager written in Python that is often used to orchestrate complex containers.

      First, create and enter a directory called thunderbird for your container:

      • mkdir ~/thunderbird
      • cd ~/thunderbird

      Now create and open a file called supervisord.conf using nano or your preferred editor:

      Now add this first block of code into supervisord.conf, which will define the global options for supervisord:

      ~/thunderbird/supervisord.conf

      [supervisord]
      nodaemon=true
      pidfile=/tmp/supervisord.pid
      logfile=/dev/fd/1
      logfile_maxbytes=0
      

      In this block, you are configuring supervisord itself. You need to set nodaemon to true because it will be running inside of a Docker container as the entrypoint. Therefore, you want it to remain running in the foreground. You also are setting pidfile to a path accessible by a non-root user (more on this later), and logfile to stdout so you can see the logs.

      Next, add another small block of code to supervisord.conf. This block starts TigerVNC, which is a combined VNC/X11 server:

      ~/thunderbird/supervisord.conf

      ...
      [program:x11]
      priority=0
      command=/usr/bin/Xtigervnc -desktop "Thunderbird" -localhost -rfbport 5900 -SecurityTypes None -AlwaysShared -AcceptKeyEvents -AcceptPointerEvents -AcceptSetDesktopSize -SendCutText -AcceptCutText :0
      autorestart=true
      stdout_logfile=/dev/fd/1
      stdout_logfile_maxbytes=0
      redirect_stderr=true
      

      In this block, you are setting up the X11 server. X11 is a display server protocol, which is what allows GUI applications to run. Note that in the future it will be replaced with Wayland, but remote access is still in development.

      For this container, you are using TigerVNC and its built-in VNC server. This has a number of advantages over using a separate X11 and VNC server:

      • Faster response time, as the GUI drawing is done directly to the VNC server rather than being done to an intermediary framebuffer (the memory which stores the contents of the screen).
      • Automatic screen resizing, which allows the remote application to automatically resize to fit the client (in this case, your web browser window).

      If you wish, you can change the argument for the -desktop option from Thunderbird to something else of your choosing. The server will display your choice as the title of the webpage used to access your application.

      Now, let’s add a third block of code to supervisord.conf to start easy-novnc:

      ~/thunderbird/supervisord.conf

      ...
      [program:easy-novnc]
      priority=0
      command=/usr/local/bin/easy-novnc --addr :8080 --host localhost --port 5900 --no-url-password --novnc-params "resize=remote"
      autorestart=true
      stdout_logfile=/dev/fd/1
      stdout_logfile_maxbytes=0
      redirect_stderr=true
      

      In this block, you are setting up easy-novnc, a standalone server which provides a wrapper around noVNC. This server performs two roles. First, it provides a simple connection page which allows you to configure options for the connection, and allows you to set default ones. Second, it proxies VNC over WebSocket, which allows it to be accessed through an ordinary web browser.

      Usually, resizing is done on the client side (i.e. image scaling), but you are using the resize=remote option to take full advantage of TigerVNC’s remote resolution adjustments. This also provides lower latency on slower devices, such as lower-end Chromebooks:

      Note: This tutorial uses easy-novnc. If you wish, you can use websockify and a separate web server instead. The advantage of easy-novnc is that the memory usage and startup time is significantly lower and that it’s self-contained. easy-novnc also provides a cleaner connection page than the default noVNC one and allows setting default options that are helpful for this setup (such as resize=remote).

      Now add the following block to your configuration to start OpenBox, the window manager:

      ~/thunderbird/supervisord.conf

      ...
      [program:openbox]
      priority=1
      command=/usr/bin/openbox
      environment=DISPLAY=:0
      autorestart=true
      stdout_logfile=/dev/fd/1
      stdout_logfile_maxbytes=0
      redirect_stderr=true
      

      In this block, you are setting up OpenBox, a lightweight X11 window manager. You could skip this step, but without it, you wouldn’t have title bars or be able to resize windows.

      Finally, let’s add the last block to supervisord.conf, which will start the main application:

      ~/thunderbird/supervisord.conf

      ...
      [program:app]
      priority=1
      environment=DISPLAY=:0
      command=/usr/bin/thunderbird
      autorestart=true
      stdout_logfile=/dev/fd/1
      stdout_logfile_maxbytes=0
      redirect_stderr=true
      

      In this final block, you are setting priority to 1 to ensure that Thunderbird launches after TigerVNC, or it would encounter a race-condition and randomly fail to start. We also set autorestart=true to automatically reopen the application if it mistakenly closes. The DISPLAY environment variable tells the application to display on the VNC server you set up earlier.

      Here is what your completed supervisord.conf will look like:

      ~/thunderbird/supervisord.conf

      [supervisord]
      nodaemon=true
      pidfile=/tmp/supervisord.pid
      logfile=/dev/fd/1
      logfile_maxbytes=0
      
      [program:x11]
      priority=0
      command=/usr/bin/Xtigervnc -desktop "Thunderbird" -localhost -rfbport 5900 -SecurityTypes None -AlwaysShared -AcceptKeyEvents -AcceptPointerEvents -AcceptSetDesktopSize -SendCutText -AcceptCutText :0
      autorestart=true
      stdout_logfile=/dev/fd/1
      stdout_logfile_maxbytes=0
      redirect_stderr=true
      
      [program:easy-novnc]
      priority=0
      command=/usr/local/bin/easy-novnc --addr :8080 --host localhost --port 5900 --no-url-password --novnc-params "resize=remote"
      autorestart=true
      stdout_logfile=/dev/fd/1
      stdout_logfile_maxbytes=0
      redirect_stderr=true
      
      [program:openbox]
      priority=1
      command=/usr/bin/openbox
      environment=DISPLAY=:0
      autorestart=true
      stdout_logfile=/dev/fd/1
      stdout_logfile_maxbytes=0
      redirect_stderr=true
      
      [program:app]
      priority=1
      environment=DISPLAY=:0
      command=/usr/bin/thunderbird
      autorestart=true
      stdout_logfile=/dev/fd/1
      stdout_logfile_maxbytes=0
      redirect_stderr=true
      

      If you want to containerize a different application, replace /usr/bin/thunderbird with the path to your application’s executable. Otherwise, you are now ready to configure your GUI’s main menu.

      Now that your process manager is configured, let’s set up the OpenBox menu. This menu allows us to launch applications inside the container. We will also include a terminal and process monitor for debugging if required.

      Inside your application’s directory, use nano or your favorite text editor to create and open a new file called menu.xml:

      • nano ~/thunderbird/menu.xml

      Now add the following code to menu.xml:

      ~/thunderbird/menu.xml

      <?xml version="1.0" encoding="utf-8"?>
      <openbox_menu xmlns="http://openbox.org/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://openbox.org/ file:///usr/share/openbox/menu.xsd">
          <menu id="root-menu" label="Openbox 3">
              <item label="Thunderbird">
                  <action name="Execute">
                      <execute>/usr/bin/thunderbird</execute>
                  </action>
              </item>
              <item label="Terminal">
                  <action name="Execute">
                      <execute>/usr/bin/x-terminal-emulator</execute>
                  </action>
              </item>
              <item label="Htop">
                  <action name="Execute">
                      <execute>/usr/bin/x-terminal-emulator -e htop</execute>
                  </action>
              </item>
          </menu>
      </openbox_menu>
      

      This XML file contains the menu items that will appear when you right-click on the desktop. Each item consists of a label and an action.

      If you want to containerize a different application, replace /usr/bin/thunderbird with the path to your application’s executable and change the label of the item.

      Step 3 — Creating the Dockerfile

      Now that OpenBox is configured, you’ll be creating the Dockerfile, which ties everything together.

      Create a Dockerfile in your container’s directory:

      • nano ~/thunderbird/Dockerfile

      To begin, let’s add some code to build easy-novnc:

      ~/thunderbird/Dockerfile

      FROM golang:1.14-buster AS easy-novnc-build
      WORKDIR /src
      RUN go mod init build && 
          go get github.com/geek1011/easy-novnc@v1.1.0 && 
          go build -o /bin/easy-novnc github.com/geek1011/easy-novnc
      

      In the first stage, you are building easy-novnc. This is done in a separate stage for simplicity and to save space — you don’t need the entire Go toolchain in your final image. Note the @v1.1.0 in the build command. This ensures that the result is deterministic, which is important because Docker caches the result of each step. If you had not specified an explicit version, Docker would reference the latest version of easy-novnc at the time the image was first built. In addition, you want to ensure that you download a specific version of easy-novnc, in case breaking changes are made to the CLI interface.

      Now let’s create the second stage, which will become the final image. Here you will be using Debian 10 (buster) as the base image. Note that since this is running in a container, it will work regardless of the distribution you are running on your server.

      Next, add the following block to your Dockerfile:

      ~/thunderbird/Dockerfile

      ...
      FROM debian:buster
      RUN apt-get update -y && 
          apt-get install -y --no-install-recommends openbox tigervnc-standalone-server supervisor gosu && 
          rm -rf /var/lib/apt/lists && 
          mkdir -p /usr/share/desktop-directories
      

      In this instruction, you are installing Debian 10 as your base image and then installing the bare minimum required to run GUI applications in your container. Note that you run apt-get update as part of the same instruction to prevent caching issues from Docker. To save space, you are also removing the package lists downloaded afterward (the cached packages themselves are removed by default). You are also creating /usr/share/desktop-directories because some applications depend on the directory existing.

      Let’s add another small block of code:

      ~/thunderbird/Dockerfile

      ...
      RUN apt-get update -y && 
          apt-get install -y --no-install-recommends lxterminal nano wget openssh-client rsync ca-certificates xdg-utils htop tar xzip gzip bzip2 zip unzip && 
          rm -rf /var/lib/apt/lists
      

      In this instruction, you are installing some useful general-purpose utilities and packages. Of particular interest here are xdg-utils (which provides the base commands used by desktop applications on Linux) and ca-certificates (which installs the root certificates to allow us to access HTTPS sites).

      Now, we can add the instructions for the main application:

      ~/thunderbird/Dockerfile

      ...
      RUN apt-get update -y && 
          apt-get install -y --no-install-recommends thunderbird && 
          rm -rf /var/lib/apt/lists
      

      As before, here we are installing the application. If you are containerizing a different application, you can replace these commands with the ones required to install your specific app. Some applications will require a bit more work to run inside Docker. For example, if you are installing an app that uses Chrome, Chromium, or QtWebEngine, you’ll need to use the command line argument --no-sandbox because it won’t be supported within Docker.

      Next, let’s start adding the instructions to add the last few files to the container:

      ~/thunderbird/Dockerfile

      ...
      COPY --from=easy-novnc-build /bin/easy-novnc /usr/local/bin/
      COPY menu.xml /etc/xdg/openbox/
      COPY supervisord.conf /etc/
      EXPOSE 8080
      

      Here you are adding the configuration files you created earlier to the image and copying the easy-novnc binary from the first stage.

      This next code block creates the data directory and adds a dedicated user for your app. This is important because some applications refuse to run as root. It’s also good practice not to run applications as root, even in a container.

      ~/thunderbird/Dockerfile

      ...
      RUN groupadd --gid 1000 app && 
          useradd --home-dir /data --shell /bin/bash --uid 1000 --gid 1000 app && 
          mkdir -p /data
      VOLUME /data
      

      To ensure a consistent UID/GID for the files, you are explicitly setting both to 1000. You are also mounting a volume on the data directory to ensure it persists between restarts.

      Finally, let’s add the instructions to launch everything:

      ~/thunderbird/Dockerfile

      ...
      CMD ["sh", "-c", "chown app:app /data /dev/stdout && exec gosu app supervisord"]
      

      By setting the default command to supervisord, the manager will launch the processes required to run your application. In this case, you are using CMD rather than ENTRYPOINT. In most cases, it wouldn’t make a difference, but using CMD is better-suited for this purpose for a few reasons. First, supervisord doesn’t take any arguments that would be relevant to us, and if you provide arguments to the container, they replace CMD and are appended to ENTRYPOINT. Second, using CMD allows us to provide an entirely different command (which will be executed by /bin/sh -c) when passing arguments to the container, which makes debugging easier.

      And lastly, you need to run chown as root before starting supervisord to prevent permission issues on the data volume and to allow the child processes to open stdout. This also means you need to use gosu instead of the USER instruction to switch the user.

      Here is what your completed Dockerfile will look like:

      ~/thunderbird/Dockerfile

      FROM golang:1.14-buster AS easy-novnc-build
      WORKDIR /src
      RUN go mod init build && 
          go get github.com/geek1011/easy-novnc@v1.1.0 && 
          go build -o /bin/easy-novnc github.com/geek1011/easy-novnc
      
      FROM debian:buster
      
      RUN apt-get update -y && 
          apt-get install -y --no-install-recommends openbox tigervnc-standalone-server supervisor gosu && 
          rm -rf /var/lib/apt/lists && 
          mkdir -p /usr/share/desktop-directories
      
      RUN apt-get update -y && 
          apt-get install -y --no-install-recommends lxterminal nano wget openssh-client rsync ca-certificates xdg-utils htop tar xzip gzip bzip2 zip unzip && 
          rm -rf /var/lib/apt/lists
      
      RUN apt-get update -y && 
          apt-get install -y --no-install-recommends thunderbird && 
          rm -rf /var/lib/apt/lists
      
      COPY --from=easy-novnc-build /bin/easy-novnc /usr/local/bin/
      COPY menu.xml /etc/xdg/openbox/
      COPY supervisord.conf /etc/
      EXPOSE 8080
      
      RUN groupadd --gid 1000 app && 
          useradd --home-dir /data --shell /bin/bash --uid 1000 --gid 1000 app && 
          mkdir -p /data
      VOLUME /data
      
      CMD ["sh", "-c", "chown app:app /data /dev/stdout && exec gosu app supervisord"]
      

      Save and close your Dockerfile. Now we are ready to build and run our container, and then access Thunderbird — a GUI application.

      Step 4 — Building and Running the Container

      The next step is to build your container and set it to run at startup. You’ll also set up a volume to preserve the application data between restarts and updates.

      First build your container. Make sure to run these commands in the ~/thunderbird directory:

      • docker build -t thunderbird .

      Now create a new network that will be shared between the app’s containers:

      • docker network create thunderbird-net

      Then create a volume to store the application data:

      • docker volume create thunderbird-data

      Finally, run it and set it to restart automatically:

      • docker run --detach --restart=always --volume=thunderbird-data:/data --net=thunderbird-net --name=thunderbird-app thunderbird

      Note that if you want, you can replace the thunderbird-app after the --name option with a different name. Whatever you have chosen, your application is now containerized and running. Now let’s use the Caddy web server to secure it and remotely connect to it.

      Step 5 — Setting up Caddy

      In this step, you’ll set up the Caddy web server to provide authentication and, optionally, remote file access over WebDAV. For simplicity, and to allow you to use it with your existing reverse proxy, you’ll run it in another container.

      Create a new directory and then move inside it:

      Now create a new Dockerfile using nano or your preferred editor:

      Then add the following directives:

      ~/caddy/Dockerfile

      FROM golang:1.14-buster AS caddy-build
      WORKDIR /src
      RUN echo 'module caddy' > go.mod && 
          echo 'require github.com/caddyserver/caddy/v2 v2.0.0' >> go.mod && 
          echo 'require github.com/mholt/caddy-webdav v0.0.0-20200523051447-bc5d19941ac3' >> go.mod
      RUN echo 'package main' > caddy.go && 
          echo 'import caddycmd "github.com/caddyserver/caddy/v2/cmd"' >> caddy.go && 
          echo 'import _ "github.com/caddyserver/caddy/v2/modules/standard"' >> caddy.go && 
          echo 'import _ "github.com/mholt/caddy-webdav"' >> caddy.go && 
          echo 'func main() { caddycmd.Main() }' >> caddy.go
      RUN go build -o /bin/caddy .
      
      FROM debian:buster
      
      RUN apt-get update -y && 
          apt-get install -y --no-install-recommends gosu && 
          rm -rf /var/lib/apt/lists
      
      COPY --from=caddy-build /bin/caddy /usr/local/bin/
      COPY Caddyfile /etc/
      EXPOSE 8080
      
      RUN groupadd --gid 1000 app && 
          useradd --home-dir /data --shell /bin/bash --uid 1000 --gid 1000 app && 
          mkdir -p /data
      VOLUME /data
      
      WORKDIR /data
      CMD ["sh", "-c", "chown app:app /data && exec gosu app /usr/local/bin/caddy run -adapter caddyfile -config /etc/Caddyfile"]
      

      This Dockerfile builds Caddy with the WebDAV plugin enabled, and then launches it on port 8080 with the Caddyfile at /etc/Caddyfile. Save and close the file.

      Next you will configure the Caddy web server. Create a file named Caddyfile in the directory you just created:

      Now add the following code block to your Caddyfile:

      ~/caddy/Caddyfile

      {
          order webdav last
      }
      :8080 {
          log
          root * /data
          reverse_proxy thunderbird-app:8080
      
          handle /files/* {
              uri strip_prefix /files
              file_server browse
          }
          redir /files /files/
      
          handle /webdav/* {
              uri strip_prefix /webdav
              webdav
          }
          redir /webdav /webdav/
      
          basicauth /* {
              {env.APP_USERNAME} {env.APP_PASSWORD_HASH}
          }
      }
      

      This Caddyfile proxies the root directory to the thunderbird-app container you created in Step 4 (Docker resolves it into the correct IP). It will also serve a read-only web-based file browser on /files and run a WebDAV server on /webdav which you can mount locally to access your files. The username and password are read from the environment variables APP_USERNAME and APP_PASSWORD_HASH.

      Now build the container:

      • docker build -t thunderbird-caddy .

      Caddy v.2 requires you to hash your desired password. Run the following command and remember to replace mypass with a strong password of your choosing:

      • docker run --rm -it thunderbird-caddy caddy hash-password -plaintext 'mypass'

      This command will output a string of characters. Copy this to your clipboard in preparation of running the next command.

      Now you are ready to run the container. Make sure to replace myuser with a username of your choosing, and replace mypass-hash with the output of the command you ran in the previous step. You can also change the port (8080 here) to access your server on a different port:

      • docker run --detach --restart=always --volume=thunderbird-data:/data --net=thunderbird-net --name=thunderbird-web --env=APP_USERNAME="myuser" --env=APP_PASSWORD_HASH="mypass-hash" --publish=8080:8080 thunderbird-caddy

      We are now ready to access and test our application.

      Step 6 — Testing and Managing the Application

      Let’s access your application and ensure that it’s working.

      First, open http://your_server_ip:8080 in a web browser,
      log in with the credentials you chose earlier, and click Connect.

      NoVNC connect page

      You should now be able to interact with the application, and it should automatically resize to fit your browser window.

      Thunderbird main menu

      If you right-click on the black desktop, you should see a menu that allows you to access a terminal. If you middle-click, you should see a list of windows.

      NoVNC right click

      Now open http://your_server_ip:8080/files/ in a web browser. You should be able to access your files.

      NoVNC file access webdav

      Optionally, you can try mounting http://your_server_ip:8080/webdav/ in a WebDAV client. You should be able to access and modify your files directly. If you use the Map network drive option in Windows Explorer, you will either need to use a reverse proxy to add HTTPS or set HKLMSYSTEMCurrentControlSetServicesWebClientParametersBasicAuthLevel to DWORD:2.

      In either case, your native GUI application is now ready for remote use.

      Conclusion

      You have now successfully set up a Docker container for Thunderbird and then, using Caddy, you’ve configured access to it through a web browser. Should you ever need to upgrade your app, stop the containers, run docker rm thunderbird-app thunderbird-web, re-build the images, and then re-run the docker run commands from the previous steps above. Your data will still be preserved since it is stored in a volume.

      If you want to learn more about basic Docker commands, you can read this tutorial or this cheatsheet. For longer-term use, you may also want to consider enabling HTTPS (this requires a domain) for additional security.

      Additionally, if you’re deploying more than one application, you may want to use Docker Compose or Kubernetes instead of starting each container manually. And remember, this tutorial can serve as a base for running any other Linux application on your server, including:

      • Wine, a compatibility layer for running Windows applications on Linux.
      • GIMP, an open-source image editor.
      • Cutter, an open-source reverse engineering platform.

      This last option demonstrates the great potential of containerizing and remotely accessing GUI applications. With this setup, you can now use a server with considerably more computing power than you might have locally to run resource-intensive tools like Cutter.



      Source link

      So installieren Sie Drupal mit Docker Compose


      Der Autor hat die United Nations Foundation dazu ausgewählt, im Rahmen des Programms Write for DOnations eine Spende zu erhalten.

      Die ursprüngliche WordPress-Version dieses Tutorials wurde von Kathleen Juell verfasst.

      Einführung

      Drupal ist ein Content-Management-System (CMS), das in PHP geschrieben und unter der Open-Source-Lizenz GNU General Public License vergeben wird. Menschen und Organisationen in der ganzen Welt verwenden Drupal, um öffentliche Websites, persönliche Blogs, Unternehmen und mehr zu betreiben. Was Drupal von anderen CMS-Frameworks abhebt, ist seine wachsende Community und eine Reihe von Funktionen, die sichere Prozesse, zuverlässige Leistung, Modularität und Flexibilität zur Anpassung umfassen.

      Drupal erfordert die Installation des LAMP-Stacks (Linux, Apache, MySQL und PHP) oder des LEMP-Stacks (Linux, Nginx, MySQL und PHP), aber das Installieren einzelner Komponenten ist eine zeitaufwendige Aufgabe. Wir können Tools wie Docker und Docker Compose verwenden, um den Prozess der Installation von Drupal zu vereinfachen. Dieses Tutorial verwendet Docker-Images zur Installation einzelner Komponenten in den Docker-Containern. Mit der Verwendung von Docker Compose können wir mehrere Container für die Datenbank, die Anwendung und für die Vernetzung/Kommunikation zwischen ihnen definieren und verwalten.

      In diesem Tutorial installieren wir Drupal mit Docker Compose, damit wir die Containerisierung nutzen und unsere Drupal-Website auf Servern bereitstellen können. Wir führen Container für eine MySQL-Datenbank, einen Nginx-Webserver und Drupal aus. Außerdem sichern wir unsere Installation, indem wir TLS/SSL Zertifikate mit Let’s Encrypt für die Domäne erlangen, die wir mit unserer Website verknüpfen möchten. Schließlich richten wir einen cron-Job ein, um unsere Zertifikate zu erneuern, damit unsere Domäne sicher bleibt.

      Voraussetzungen

      Um diesem Tutorial zu folgen, benötigen Sie:

      • Einen Server, auf dem Ubuntu 18.04 ausgeführt wird, zusammen mit einem non-root user mit sudo-Privilegien und einer aktiven Firewall. Eine Anleitung für das Setup finden Sie im Leitfaden für die Ersteinrichtung des Servers.
      • Docker, gemäß Schritt 1 und 2 unter So installieren und verwenden Sie Docker unter Ubuntu 18.04 auf Ihrem Server installiert. Dieses Tutorial wurde unter der Version 19.03.8 getestet.
      • Docker Compose, gemäß Schritt 1 unter So installieren Sie Compose unter Ubuntu 18.04 auf Ihrem Server installiert. Dieses Tutorial wurde unter der Version 1.21.2 getestet.
      • Einen registrierten Domänennamen. Dieses Tutorial verwendet in allen Bereichen your_domain. Einen Domänennamen können Sie kostenlos bei Freenom erhalten oder Sie nutzen eine Domänenregistrierungsstelle Ihrer Wahl.
      • Die beiden folgenden DNS-Einträge für Ihren Server eingerichtet. Falls Sie ein DigitalOcean-Konto nutzen, können Sie in der Einführung in DigitalOcean-DNS im Einzelnen nachlesen, wie Sie diese hinzufügen:
        • Einen A-Eintrag mit your_domain, der auf die öffentliche IP-Adresse Ihres Servers verweist.
        • Einen A-Eintrag mit www.your_domain, der auf die öffentliche IP-Adresse Ihres Servers verweist.

      Schritt 1 — Definieren der Webserver-Konfiguration

      Bevor wir Container ausführen, müssen wir die Konfiguration für unseren Nginx-Webserver definieren. Unsere Konfigurationsdatei enthält einige Drupal-spezifische Location-Blocks, zusammen mit einem Location-Block zur Weiterleitung von Verifizierungsanforderungen von Let’s Encrypt an den Certbot-Client für automatisierte Zertifikatserneuerungen.

      Zuerst erstellen wir ein Projektverzeichnis für unser Drupal-Setup namens drupal:

      Rufen Sie das neu erstellte Verzeichnis auf:

      Nun können wir ein Verzeichnis für unsere Konfigurationsdatei erstellen:

      Öffnen Sie die Datei mit nano oder Ihrem bevorzugten Texteditor:

      • nano nginx-conf/nginx.conf

      In dieser Datei fügen wir einen Serverblock mit Anweisungen für unseren Servernamen und die Dokumenten-root hinzu sowie Location-Blocks, um die Anforderung des Certbot-Clients nach Zertifikaten, PHP-Verarbeitung und statischen Asset-Anforderungen zu leiten.

      Fügen Sie den folgenden Code in die Datei ein. Achten Sie darauf, your_domain durch Ihren eigenen Domänennamen zu ersetzen:

      ~/drupal/nginx-conf/nginx.conf

      server {
          listen 80;
          listen [::]:80;
      
          server_name your_domain www.your_domain;
      
          index index.php index.html index.htm;
      
          root /var/www/html;
      
          location ~ /.well-known/acme-challenge {
              allow all;
              root /var/www/html;
          }
      
          location / {
              try_files $uri $uri/ /index.php$is_args$args;
          }
      
          rewrite ^/core/authorize.php/core/authorize.php(.*)$ /core/authorize.php$1;
      
          location ~ .php$ {
              try_files $uri =404;
              fastcgi_split_path_info ^(.+.php)(/.+)$;
              fastcgi_pass drupal:9000;
              fastcgi_index index.php;
              include fastcgi_params;
              fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
              fastcgi_param PATH_INFO $fastcgi_path_info;
          }
      
          location ~ /.ht {
              deny all;
          }
      
          location = /favicon.ico {
              log_not_found off; access_log off;
          }
          location = /robots.txt {
              log_not_found off; access_log off; allow all;
          }
          location ~* .(css|gif|ico|jpeg|jpg|js|png)$ {
              expires max;
              log_not_found off;
          }
      }
      

      Unser Serverblock enthält folgende Informationen:

      Anweisungen:

      • listen: Diese weist Nginx an, an Port 80 zu lauschen, sodass wir das Webroot-Plugin von Certbot für unsere Zertifikatsanforderungen nutzen können. Beachten Sie, dass wir noch nicht Port 443 einschließen – wir aktualisieren unsere Konfiguration, um SSL einzuschließen, sobald wir erfolgreich unsere Zertifikate erlangt haben.

      • server_name: Damit definieren Sie den Servernamen und den Serverblock, der für Anfragen an den Server verwendet werden sollte. Achten Sie darauf, your_domain in dieser Zeile durch Ihren eigenen Domänennamen zu ersetzen.

      • index: Die Anweisung index definiert die Dateien, die als Indizes bei der Verarbeitung von Anfragen an unseren Server dienen. Wir haben hier die Standardreihenfolge der Priorität geändert und index.php vor index.html geschoben, damit Nginx Dateien namens index.php wenn möglich priorisiert.

      • root: Unsere root-Anweisung benennt das root-Verzeichnis für Anfragen an unseren Server. Dieses Verzeichnis, /var/www/html, wird als Bereitstellungspunkt in der Erstellungszeit durch Anweisungen in unserer Drupal Dockerfile erstellt. Diese Dockerfile-Anweisungen stellen auch sicher, dass die Dateien aus der Drupal-Version auf diesem Volume bereitgestellt werden.

      • rewrite: Wenn die angegebene reguläre Expression (^/core/authorize.php/core/authorize.php(.*)$) mit einer URI-Anfrage übereinstimmt, wird die URI wie in der Ersatzzeichenfolge (/core/authorize.php$1) angegeben geändert.

      Location-Blocks:

      • location ~ /.well-known/acme-challenge: Dieser Location-Block verwaltet Anfragen an das Verzeichnis .well-known, in dem Certbot eine temporäre Datei ablegt, um zu validieren, dass das DNS für unsere Domäne auf unserem Server aufgelöst wird. Mit dieser Konfiguration können wir das Webroot-Plugin von Certbot verwenden, um Zertifikate für unsere Domäne zu erlangen.

      • location /: In diesem Location-Block verwenden wir eine try_files-Anweisung, um nach Dateien zu suchen, die individuellen URI-Anfragen entsprechen. Anstatt jedoch einen 404 Not Found-Status auszugeben, übergeben wir die Steuerung an die Datei index.php von Drupal mit den Anforderungsargumenten.

      • location ~ .php$: Dieser Location-Block verwaltet die PHP-Verarbeitung und überträgt diese Anfragen an unseren drupal-Container. Da unser Drupal-Docker-Image auf dem php:fpm-Image basiert, schließen wir auch Konfigurationsoptionen ein, die in diesem Block für das FastCGI-Protokoll spezifisch sind. Nginx erfordert einen unabhängigen PHP-Prozessor für PHP-Anfragen: In unserem Fall werden diese Anfragen vom php-fpm-Prozessor verwaltet, der im php:fpm-Image enthalten ist. Außerdem enthält dieser Location-Block FastCGI-spezifische Anweisungen, Variablen und Optionen, die Anfragen an die in unserem Drupal-Container ausgeführte Drupal-Anwendung überträgt, den bevorzugten Index für die analysierte Anfrage-URI festlegt und URI-Anfragen analysiert.

      • location ~ /.ht: Dieser Block verwaltet .htaccess-Dateien, da Nginx diese nicht bedient. Die Anweisung deny_all stellt sicher, dass .htaccess-Dateien nie für Benutzer bereitgestellt werden.

      • location = /favicon.ico, location = /robots.txt: Diese Blocks stellen sicher, dass Anfragen an /favicon.ico und /robots.txt nicht protokolliert werden.

      • location ~* . (css|gif|ico|jpeg|jpg|js|png)$: Dieser Block schaltet die Protokollierung für statische Asset-Anfragen ab und stellt sicher, dass diese Assets in hohem Maße zwischenspeicherbar sind, da ihre Bereitstellung in der Regel aufwendig ist.

      Weitere Informationen zu FastCGI-Proxying finden Sie in Verstehen und Implementieren von FastCGI-Proxying in Nginx. Informationen zu Server- und Location-Blocks finden Sie in Verstehen von Nginx-Server- und Location-Block-Auswahlalgorithmen.

      Wenn die Bearbeitung abgeschlossen wurde, speichern und schließen Sie die Datei.

      Nach Einrichtung der Nginx-Konfiguration können Sie Umgebungsvariablen erstellen, die zur Laufzeit an Ihre Anwendungs- und Datenbankcontainer übergeben werden.

      Schritt 2 — Definieren der Umgebungsvariablen

      Unsere Drupal-Anwendung benötigt eine Datenbank (MySQL, PostgresSQL, etc.) zum Speichern von Informationen im Zusammenhang mit der Website. Der Drupal-Container benötigt Zugriff auf bestimmte Umgebungsvariablen zur Laufzeit, um Zugriff auf den Datenbank-Container (MySQL) zu ermöglichen. Diese Variablen enthalten sensible Informationen wie die Zugangsdaten der Datenbank, sodass wir sie nicht direkt in der Docker-Compose-Datei offenlegen können – der Hauptdatei, die Informationen darüber enthält, wie unsere Container ausgeführt werden.

      Es wird immer empfohlen, die sensiblen Werte in der .env-Datei festzulegen und ihre Zirkulation zu beschränken. Dadurch werden diese Werte nicht in unsere Projekt-Repositorys kopiert und öffentlich verfügbar gemacht.

      Erstellen und öffnen Sie im Haupt-Projektverzeichnis ~/drupal eine Datei namens .env:

      Fügen Sie die folgenden Variablen in die .env-Datei ein und ersetzen Sie dabei die hervorgehobenen Abschnitte mit den Zugangsdaten, die Sie verwenden möchten:

      ~/drupal/.env

      MYSQL_ROOT_PASSWORD=root_password
      MYSQL_DATABASE=drupal
      MYSQL_USER=drupal_database_user
      MYSQL_PASSWORD=drupal_database_password
      

      Wir haben nun das Passwort für das MySQL-root-Administratorkonto sowie unseren bevorzugten Benutzernamen und das Passwort für unsere Anwendungsdatenbank hinzugefügt.

      Unsere .env-Datei enthält sensible Informationen. Es wird daher immer empfohlen, sie in die .gitignore– und .dockerignore-Dateien des Projekts einzufügen, damit sie nicht in unseren Git-Repositorys und Docker-Images hinzugefügt werden.

      Wenn Sie mit Git zur Versionskontrolle arbeiten möchten, initialisieren Sie Ihr aktuelles Arbeitsverzeichnis als ein Repository mit git init:

      Öffnen Sie die .gitignore-Datei:

      Fügen Sie Folgendes hinzu:

      ~/drupal/.gitignore

      .env
      

      Speichern und schließen Sie die Datei.

      Öffnen Sie in ähnlicher Weise die .dockerignore-Datei:

      Fügen Sie Folgendes hinzu:

      ~/drupal/.dockerignore

      .env
      .git
      

      Speichern und schließen Sie die Datei.

      Wir haben nun die Maßnahmen zur Sicherung unserer Zugangsdaten als Umgebungsvariablen ergriffen. Im nächsten Schritt definieren wir unsere Dienste in einer docker-compose.yml-Datei.

      Schritt 3 — Definieren der Dienste mit Docker Compose

      Docker Compose ist ein Tool zum Definieren und Ausführen von Docker-Anwendungen mit mehreren Containern. Wir definieren eine YAML-Datei, um die Dienste unserer Anwendung zu konfigurieren. Ein Dienst oder service in Docker Compose ist ein Container, der ausgeführt wird. Compose ermöglicht uns, diese Dienste zusammen mit geteilten Volumes und Netzwerken zu verknüpfen.

      Wir erstellen verschiedene Container für die Drupal-Anwendung, die Datenbank und den Webserver. Außerdem erstellen wir einen Container, der Certbot ausführt, um Zertifikate für unseren Webserver zu erlangen.

      Erstellen Sie eine docker-compose.yml-Datei:

      Fügen Sie den folgenden Code hinzu, um die Compose-Dateiversion und den mysql-Datenbankdienst zu definieren:

      ~/drupal/docker-compose.yml

      version: "3"
      
      services:
        mysql:
          image: mysql:8.0
          container_name: mysql
          command: --default-authentication-plugin=mysql_native_password
          restart: unless-stopped
          env_file: .env
          volumes:
            - db-data:/var/lib/mysql
          networks:
            - internal
      

      Wir behandeln diese nacheinander mit allen Konfigurationsoptionen des mysql-Dienstes:

      • image: Hiermit wird das Image festgelegt, das wir zum Erstellen des Containers verwenden/pullen. Es wird immer empfohlen, das Image mit dem richtigen Versions-Tag unter Ausschluss des latest-Tags zu verwenden, um zukünftige Konflikte zu vermeiden. Lesen Sie dazu mehr in Best Practices für Dockerfiles in der Docker-Dokumentation.

      • container_name: Hiermit wird der Name des Containers definiert.

      • command: Diese Option wird verwendet, um den Standardbefehl (CMD-Instruktion) im Image zu überschreiben. MySQL hat verschiedene Authentifizierungs-Plugins unterstützt, aber mysql_native_password ist die traditionelle Methode zur Authentifizierung. Da PHP und damit Drupal nicht die neuere MySQL-Authentifizierung unterstützen, müssen wir das --default-authentication-plugin=mysql_native_password als standardmäßigen Authentifizierungsmechanismus festlegen.

      • restart: Diese Option wird verwendet, um die Neustartregel des Containers festzulegen. Die Regel unless-stopped startet einen Container neu, bis er manuell gestoppt wird.

      • env_file: Hiermit werden die Umgebungsvariablen aus einer Datei hinzugefügt. In unserem Fall werden die Umgebungsvariablen aus der im vorherigen Schritt definierten .env-Datei gelesen.

      • volumes: Hiermit werden Host-Pfade oder benannte Volumes, die als Suboptionen eines Dienstes angegeben sind, bereitgestellt. Wir stellen ein benanntes Volume namens db-data im Verzeichnis /var/lib/mysql des Containers bereit, in der MySQL standardmäßig seine Datendateien schreibt.

      • networks: Hiermit wird das internal-Netzwerk, an das sich unser Anwendungsdienst anschließt, definiert. Wir definieren die Netzwerke am Ende der Datei.

      Wir haben unsere mysql-Dienstdefiniton definiert. Nun fügen wir die Definition des drupal-Anwendungsdienstes am Ende der Datei hinzu:

      ~/drupal/docker-compose.yml

      ...
        drupal:
          image: drupal:8.7.8-fpm-alpine
          container_name: drupal
          depends_on:
            - mysql
          restart: unless-stopped
          networks:
            - internal
            - external
          volumes:
            - drupal-data:/var/www/html
      

      In dieser Dienstdefinition benennen wir unseren Container und definieren eine Neustartregel, wie wir es beim mysql-Dienst getan haben. Außerdem fügen wir einige Optionen hinzu, die für diesen Container spezifisch sind:

      • image: Hier verwenden wir Drupal-Image 8.7.8-fpm-alpine. Dieses Image verfügt über den php-fpm-Prozessor, den unser Nginx-Webserver zur Verwaltung der PHP-Verarbeitung benötigt. Darüber hinaus verwenden wir das aus dem Alpine-Linux-Projekt erlangte alpine-Image, das die Größe des Gesamtimages reduziert und in den Best Practices für Dockerfiles empfohlen wird. Drupal verfügt über weitere Versionen von Images, die Sie auf Dockerhub finden können.

      • depends_on: Diese Option wird verwendet, um Abhängigkeit zwischen Diensten auszudrücken. Das Definieren des mysql-Dienstes als Abhängigkeit unseres drupal-Containers stellt sicher, dass unser drupal-Container nach dem mysql-Container erstellt wird und ermöglicht einen reibungslosen Start unserer Anwendung.

      • networks: Hier haben wir diesen Container zusammen mit dem internal-Netzwerk dem external-Netzwerk hinzugefügt. Dadurch wird sichergestellt, dass unser mysql-Dienst nur über das internal-Netzwerk aus dem drupal-Container zugänglich ist, während dieser Container über das external-Netzwerk für andere Container weiterhin zugänglich bleibt.

      • volumes: Wir stellen ein benanntes Volume namens drupal-data im Bereitstellungspunkt /var/www/html bereit, der vom Drupal-Image erstellt wurde. Wenn wir ein benanntes Volume auf diese Weise verwenden, können wir unseren Anwendungscode mit anderen Containern teilen.

      Als Nächstes fügen wir die Nginx-Dienstdefinition nach der drupal-Dienstdefinition hinzu:

      ~/drupal/docker-compose.yml

      ...
        webserver:
          image: nginx:1.17.4-alpine
          container_name: webserver
          depends_on:
            - drupal
          restart: unless-stopped
          ports:
            - 80:80
          volumes:
            - drupal-data:/var/www/html
            - ./nginx-conf:/etc/nginx/conf.d
            - certbot-etc:/etc/letsencrypt
          networks:
            - external
      

      Auch hier benennen wir unseren Container und machen ihn in der Reihenfolge des Starts vom Drupal-Container abhängig. Außerdem verwenden wir ein alpine-Image – das Nginx-Image 1.17.4-alpine.

      Diese Dienstdefinition enthält auch die folgenden Optionen:

      • ports: Hiermit wird Port 80 zur Verfügung gestellt, um die Konfigurationsoptionen zu aktivieren, die wir in unserer Datei nginx.conf in Schritt 1 definiert haben.

      • volumes: Hier definieren wir sowohl das benannte Volume als auch den Host-Pfad:

        • drupal-data:/var/www/html: Hiermit wird unser Drupal-Anwendungscode im Verzeichnis /var/www/html, das wir als die root in unserem Nginx-Serverblock festgelegt haben, bereitgestellt.
        • ./nginx-conf:/etc/nginx/conf.d: Hiermit wird das Nginx-Konfigurationsverzeichnis auf dem Host in dem entsprechenden Verzeichnis im Container bereitgestellt. Dadurch wird sichergestellt, dass alle Änderungen, die wir an Dateien auf dem Host vornehmen, im Container reflektiert werden.
        • certbot-etc:/etc/letsencrypt: Hiermit werden die relevanten Let’s-Encrypt-Zertifikate und die Schlüssel für unsere Domäne in dem entsprechenden Verzeichnis des Containers bereitgestellt.
        • networks: Wir haben das external-Netzwerk nur definiert, damit dieser Container mit dem drupal-Container, aber nicht mit dem mysql-Container kommunizieren kann.

      Schließlich fügen wir unsere letzte Dienstdefinition für den certbot-Dienst hinzu. Achten Sie darauf, sammy@your_domain und your_domain durch Ihre eigene E-Mail-Adresse und den Domänennamen zu ersetzen:

      ~/drupal/docker-compose.yml

      ...
        certbot:
          depends_on:
            - webserver
          image: certbot/certbot
          container_name: certbot
          volumes:
            - certbot-etc:/etc/letsencrypt
            - drupal-data:/var/www/html
          command: certonly --webroot --webroot-path=/var/www/html --email sammy@your_domain --agree-tos --no-eff-email --staging -d your_domain -d www.your_domain
      

      Diese Definition weist Compose an, das Image certbot/certbot von Docker Hub zu pullen. Außerdem werden benannte Volumes verwendet, um Ressourcen für den Nginx-Container freizugeben, einschließlich der Domänenzertifikate und des Schlüssels in certbot-etc und des Anwendungscodes in drupal-data.

      Wir haben auch depends_on verwendet, um sicherzustellen, dass der certbot-Container gestartet wird, nachdem der webserver-Dienst ausgeführt wird.

      Wir haben hier keine networks angegeben, da dieser Container mit keinem Dienst über das Netzwerk kommunizieren wird. Es werden nur die Domänenzertifikate und der Schlüssel hinzugefügt, die wir mit den benannten Volumes bereitgestellt haben.

      Außerdem haben wir die Option command eingeschlossen, die einen Unterbefehl angibt, der mit dem Standardbefehl certbot des Containers ausgeführt werden soll. Der Certbot-Client unterstützt Plugins zur Erstellung und Installation von Zertifikaten. Wir verwenden das webroot-Plugin, um ein Zertifikat zu erlangen, indem wir certonly und --webroot in die Befehlszeile einfügen. Lesen Sie mehr über das Plugin und zusätzliche Befehle in der offiziellen Certbot-Dokumentation.

      Fügen Sie nach der certbot-Dienstdefinition die Netzwerk- und Volume-Definitionen hinzu:

      ~/drupal/docker-compose.yml

      ...
      networks:
        external:
          driver: bridge
        internal:
          driver: bridge
      
      volumes:
        drupal-data:
        db-data:
        certbot-etc:
      

      Mit dem networks-Schlüssel der obersten Ebene können wir die zu erstellenden Netzwerke angeben. networks ermöglicht die Kommunikation über die Dienste/Container auf allen Ports, da sie sich auf demselben Docker-Daemon-Host befinden. Wir haben zwei Netzwerke, internal und external, definiert, um die Kommunikation der Dienste webserver, drupal und mysql zu sichern.

      Der volumes-Schlüssel wird verwendet, um die benannten Volumes drupal-data, db-data und certbot-etc zu definieren. Wenn Docker Volumes erstellt, werden die Inhalte des Volumes in einem Verzeichnis des Host-Dateisystems, /var/lib/docker/volumes/, gespeichert, das von Docker verwaltet wird. Die Inhalte jedes Volumes werden dann von diesem Verzeichnis in jedem Container bereitgestellt, der das Volume verwendet. Auf diese Weise können Code und Daten zwischen Containern geteilt werden.

      Die fertige docker-compose.yml-Datei sieht so aus:

      ~/drupal/docker-compose.yml

      version: "3"
      
      services:
        mysql:
          image: mysql:8.0
          container_name: mysql
          command: --default-authentication-plugin=mysql_native_password
          restart: unless-stopped
          env_file: .env
          volumes:
            - db-data:/var/lib/mysql
          networks:
            - internal
      
        drupal:
          image: drupal:8.7.8-fpm-alpine
          container_name: drupal
          depends_on:
            - mysql
          restart: unless-stopped
          networks:
            - internal
            - external
          volumes:
            - drupal-data:/var/www/html
      
        webserver:
          image: nginx:1.17.4-alpine
          container_name: webserver
          depends_on:
            - drupal
          restart: unless-stopped
          ports:
            - 80:80
          volumes:
            - drupal-data:/var/www/html
            - ./nginx-conf:/etc/nginx/conf.d
            - certbot-etc:/etc/letsencrypt
          networks:
            - external
      
        certbot:
          depends_on:
            - webserver
          image: certbot/certbot
          container_name: certbot
          volumes:
            - certbot-etc:/etc/letsencrypt
            - drupal-data:/var/www/html
          command: certonly --webroot --webroot-path=/var/www/html --email sammy@your_domain --agree-tos --no-eff-email --staging -d your_domain -d www.your_domain
      
      networks:
        external:
          driver: bridge
        internal:
          driver: bridge
      
      volumes:
        drupal-data:
        db-data:
        certbot-etc:
      

      Nun sind unsere Dienstdefinitionen fertig. Als Nächstes starten wir den Container und testen unsere Zertifikatsanforderungen.

      Schritt 4 — Erlangen der SSL-Zertifikate und Zugangsdaten

      Wir können unsere Container mit dem Befehl docker-compose up starten, der die Container in der von uns angegebenen Reihenfolge erstellt und ausführt. Wenn unsere Domain-Anfragen erfolgreich sind, sehen wir den richtigen Exit-Status in unserer Ausgabe und die richtigen Zertifikate, die im Ordner /etc/letsencrypt/live im Webservercontainer bereitgestellt werden.

      Um die Container im Hintergrund auszuführen, verwenden Sie den Befehl docker-compose up mit dem Flag -d:

      Sie sehen eine ähnliche Ausgabe, die bestätigt, dass Ihre Dienste erstellt wurden:

      Output

      ... Creating mysql ... done Creating drupal ... done Creating webserver ... done Creating certbot ... done

      Überprüfen Sie den Status der Dienste mit dem Befehl docker-compose ps:

      Wir sehen die Dienste mysql, drupal und webserver mit einem State von Up, während certbot mit einer Statusmeldung von 0 beendet wird:

      Output

      Name Command State Ports -------------------------------------------------------------------------- certbot certbot certonly --webroot ... Exit 0 drupal docker-php-entrypoint php-fpm Up 9000/tcp mysql docker-entrypoint.sh --def ... Up 3306/tcp, 33060/tcp webserver nginx -g daemon off; Up 0.0.0.0:80->80/tcp

      Wenn Sie in der Spalte State für die Dienste mysql, drupal oder webserver etwas anderes als Up sehen, oder für den certbot-Container einen anderen Exit-Status als 0, überprüfen Sie die Dienstprotokolle mit dem Befehl docker-compose logs:

      • docker-compose logs service_name

      Wir können nun mit dem Befehl docker-compose exec überprüfen, dass unsere Zertifikate auf dem webserver bereitgestellt wurden:

      • docker-compose exec webserver ls -la /etc/letsencrypt/live

      Dadurch erhalten Sie folgende Ausgabe:

      Output

      total 16 drwx------ 3 root root 4096 Oct 5 09:15 . drwxr-xr-x 9 root root 4096 Oct 5 09:15 .. -rw-r--r-- 1 root root 740 Oct 5 09:15 README drwxr-xr-x 2 root root 4096 Oct 5 09:15 your_domain

      Nachdem nun alles erfolgreich ausgeführt wird, können wir unsere certbot-Dienstdefinition bearbeiten, um das Flag --staging zu entfernen.

      Öffnen Sie die Datei docker-compose.yml, gehen Sie zur certbot-Dienstdefinition und ersetzen Sie das Flag --staging in der Befehlsoption mit dem Flag --force-renewal, das Certbot mitteilt, dass Sie ein neues Zertifikat mit denselben Domänen wie ein vorhandenes Zertifikat anfordern möchten. Die aktualisierte Definition von certbot sieht wie folgt aus:

      ~/drupal/docker-compose.yml

      ...
        certbot:
          depends_on:
            - webserver
          image: certbot/certbot
          container_name: certbot
          volumes:
            - certbot-etc:/etc/letsencrypt
            - drupal-data:/var/www/html
          command: certonly --webroot --webroot-path=/var/www/html --email sammy@your_domain --agree-tos --no-eff-email --force-renewal -d your_domain -d www.your_domain
      ...
      

      Wir müssen docker-compose erneut ausführen, um den certbot-Container neu zu erstellen. Wir schließen auch die Option --no-deps ein, um Compose mitzuteilen, dass das Starten des webserver-Dienstes übersprungen werden kann, da dieser bereits ausgeführt wird:

      • docker-compose up --force-recreate --no-deps certbot

      In der Ausgabe sehen wir, dass unsere Zertifikatsanforderung erfolgreich war:

      Output

      Recreating certbot ... done Attaching to certbot certbot | Saving debug log to /var/log/letsencrypt/letsencrypt.log certbot | Plugins selected: Authenticator webroot, Installer None certbot | Renewing an existing certificate certbot | Performing the following challenges: certbot | http-01 challenge for your_domain certbot | http-01 challenge for www.your_domain certbot | Using the webroot path /var/www/html for all unmatched domains. certbot | Waiting for verification... certbot | Cleaning up challenges certbot | IMPORTANT NOTES: certbot | - Congratulations! Your certificate and chain have been saved at: certbot | /etc/letsencrypt/live/your_domain/fullchain.pem certbot | Your key file has been saved at: certbot | /etc/letsencrypt/live/your_domain/privkey.pem certbot | Your cert will expire on 2020-01-03. To obtain a new or tweaked certbot | version of this certificate in the future, simply run certbot certbot | again. To non-interactively renew *all* of your certificates, run certbot | "certbot renew" certbot | - Your account credentials have been saved in your Certbot certbot | configuration directory at /etc/letsencrypt. You should make a certbot | secure backup of this folder now. This configuration directory will certbot | also contain certificates and private keys obtained by Certbot so certbot | making regular backups of this folder is ideal. certbot | - If you like Certbot, please consider supporting our work by: certbot | certbot | Donating to ISRG / Let's Encrypt: https://letsencrypt.org/donate certbot | Donating to EFF: https://eff.org/donate-le certbot | certbot exited with code 0

      Nachdem wir unsere Zertifikate erfolgreich generiert haben, können wir unsere Nginx-Konfiguration aktualisieren, um SSL einzuschließen.

      Schritt 5 — Ändern der Webserver-Konfiguration und Dienstdefinition

      Nach der Installation von SSL-Zertifikaten in Nginx müssen wir alle HTTP-Anfragen an HTTPS umleiten. Außerdem müssen wir unser SSL-Zertifikat und unsere Schlüsselpositionen angeben und Sicherheitsparameter sowie Header hinzufügen.

      Da Sie den webserver-Dienst neu erstellen, um diese Ergänzungen einzuschließen, können Sie diesen jetzt stoppen:

      • docker-compose stop webserver

      Dadurch erhalten Sie folgende Ausgabe:

      Output

      Stopping webserver ... done

      Als Nächstes entfernen wir die zuvor erstellte Nginx-Konfigurationsdatei:

      Öffnen Sie eine andere Version der Datei:

      • nano nginx-conf/nginx.conf

      Fügen Sie der Datei den folgenden Code hinzu, um HTTP an HTTPS umzuleiten und SSL-Zugangsdaten, Protokolle und Sicherheitsheader hinzuzufügen. Denken Sie daran, your_domain durch Ihre eigene Domäne zu ersetzen:

      ~/drupal/nginx-conf/nginx.conf

      server {
          listen 80;
          listen [::]:80;
      
          server_name your_domain www.your_domain;
      
          location ~ /.well-known/acme-challenge {
              allow all;
              root /var/www/html;
          }
      
          location / {
              rewrite ^ https://$host$request_uri? permanent;
          }
      }
      server {
          listen 443 ssl;
          listen [::]:443 ssl;
          server_name your_domain www.your_domain;
      
          index index.php index.html index.htm;
      
          root /var/www/html;
      
          server_tokens off;
      
          ssl_certificate /etc/letsencrypt/live/your_domain/fullchain.pem;
          ssl_certificate_key /etc/letsencrypt/live/your_domain/privkey.pem;
      
          add_header X-Frame-Options "SAMEORIGIN" always;
          add_header X-XSS-Protection "1; mode=block" always;
          add_header X-Content-Type-Options "nosniff" always;
          add_header Referrer-Policy "no-referrer-when-downgrade" always;
          add_header Content-Security-Policy "default-src * data: 'unsafe-eval' 'unsafe-inline'" always;
      
          location / {
              try_files $uri $uri/ /index.php$is_args$args;
          }
      
          rewrite ^/core/authorize.php/core/authorize.php(.*)$ /core/authorize.php$1;
      
          location ~ .php$ {
              try_files $uri =404;
              fastcgi_split_path_info ^(.+.php)(/.+)$;
              fastcgi_pass drupal:9000;
              fastcgi_index index.php;
              include fastcgi_params;
              fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
              fastcgi_param PATH_INFO $fastcgi_path_info;
          }
      
          location ~ /.ht {
              deny all;
          }
      
          location = /favicon.ico {
              log_not_found off; access_log off;
          }
          location = /robots.txt {
              log_not_found off; access_log off; allow all;
          }
          location ~* .(css|gif|ico|jpeg|jpg|js|png)$ {
              expires max;
              log_not_found off;
          }
      }
      

      Der HTTP-Serverblock gibt das Webroot-Plugin für Certbot-Erneuerungsanfragen an das Verzeichnis .well-known/acme-challenge an. Er enthält auch eine rewrite-Anweisung, die HTTP-Anfragen an das root-Verzeichnis an HTTPS leitet.

      Der HTTPS-Serverblock aktiviert ssl und http2. Weitere Informationen dazu, wie HTTP/2 über HTTP-Protokolle iteriert und welche Vorteile es für die Website-Leistung haben kann, lesen Sie bitte in der Einführung Einrichten von Nginx mit HTTP/2-Support unter Ubuntu 18.04.

      Diese Blocks aktivieren SSL, da wir unser SSL-Zertifikat und die Schlüsselpositionen zusammen mit den empfohlenen Headern eingefügt haben. Diese Header ermöglichen uns eine A-Bewertung auf den Server-Testseiten SSL-Labs und Security Headers.

      Unsere Anweisungen root und index befinden sich ebenfalls in diesem Block, ebenso wie die restlichen Drupal-spezifischen Location-Blocks, die in Schritt 1 behandelt wurden.

      Speichern und schließen Sie die aktualisierte Nginx-Konfigurationsdatei.

      Bevor wir den webserver-Container neu erstellen, müssen wir unserem webserver-Dienst ein 443-Port-Mapping hinzufügen, da wir SSL-Zertifikate aktiviert haben.

      Öffnen Sie die Datei docker-compose.yml:

      Führen Sie die folgenden Änderungen in der webserver-Dienstdefinition aus:

      ~/drupal/docker-compose.yml

      ...
        webserver:
          image: nginx:1.17.4-alpine
          container_name: webserver
          depends_on:
            - drupal
          restart: unless-stopped
          ports:
            - 80:80
            - 443:443
          volumes:
            - drupal-data:/var/www/html
            - ./nginx-conf:/etc/nginx/conf.d
            - certbot-etc:/etc/letsencrypt
          networks:
            - external
      ...
      

      Nach dem Aktivieren der SSL-Zertifikate sieht unsere docker-compose.yml wie folgt aus:

      ~/drupal/docker-compose.yml

      version: "3"
      
      services:
        mysql:
          image: mysql:8.0
          container_name: mysql
          command: --default-authentication-plugin=mysql_native_password
          restart: unless-stopped
          env_file: .env
          volumes:
            - db-data:/var/lib/mysql
          networks:
            - internal
      
        drupal:
          image: drupal:8.7.8-fpm-alpine
          container_name: drupal
          depends_on:
            - mysql
          restart: unless-stopped
          networks:
            - internal
            - external
          volumes:
            - drupal-data:/var/www/html
      
        webserver:
          image: nginx:1.17.4-alpine
          container_name: webserver
          depends_on:
            - drupal
          restart: unless-stopped
          ports:
            - 80:80
            - 443:443
          volumes:
            - drupal-data:/var/www/html
            - ./nginx-conf:/etc/nginx/conf.d
            - certbot-etc:/etc/letsencrypt
          networks:
            - external
      
        certbot:
          depends_on:
            - webserver
          image: certbot/certbot
          container_name: certbot
          volumes:
            - certbot-etc:/etc/letsencrypt
            - drupal-data:/var/www/html
          command: certonly --webroot --webroot-path=/var/www/html --email sammy@your_domain --agree-tos --no-eff-email --force-renewal -d your_domain -d www.your_domain
      
      networks:
        external:
          driver: bridge
        internal:
          driver: bridge
      
      volumes:
        drupal-data:
        db-data:
        certbot-etc:
      

      Speichern und schließen Sie die Datei. Wir erstellen den webserver-Dienst mit unserer aktualisierten Konfiguration nun neu:

      • docker-compose up -d --force-recreate --no-deps webserver

      Dadurch erhalten Sie folgende Ausgabe:

      Output

      Recreating webserver ... done

      Überprüfen Sie die Dienste mit docker-compose ps:

      Wir sehen die Dienste mysql, drupal und webserver als Up, während certbot mit der Statusmeldung 0 beendet wird:

      Output

      Name Command State Ports -------------------------------------------------------------------------- certbot certbot certonly --webroot ... Exit 0 drupal docker-php-entrypoint php-fpm Up 9000/tcp mysql docker-entrypoint.sh --def ... Up 3306/tcp, 33060/tcp webserver nginx -g daemon off; Up 0.0.0.0:443->443/tcp, 0.0.0.0:80->80/tcp

      Jetzt werden alle unsere Dienste ausgeführt und wir können mit der Installation von Drupal über die Web-Oberfläche fortfahren.

      Schritt 6 – Abschließen der Installation über die Weboberfläche

      Beenden wir die Installation über die Weboberfläche von Drupal.

      Navigieren Sie in einem Webbrowser zur Domäne des Servers. Denken Sie daran, your_domain hier mit Ihrem eigenen Domänennamen zu ersetzen:

      https://your_domain
      

      Wählen Sie die Sprache aus, die Sie verwenden möchten:

      Sprachauswahlseite auf der Drupal-Weboberfläche

      Klicken Sie auf Speichern und fortfahren. Wir werden zur Seite der Installationsprofile geleitet. Drupal bietet verschiedene Profile. Wählen Sie das Profil Standard und klicken Sie auf Speichern und fortfahren.

      Profilauswahlseite auf der Drupal-Weboberfläche

      Nach Auswahl des Profils gehen wir weiter zur Seite der Datenbankkonfiguration. Wählen Sie als Datenbanktyp MySQL, MariaDB, Percona Server oder äquivalent aus. Geben Sie die Werte für Datenbankname, Benutzername und Passwort entsprechend der Werte von MYSQL_DATABASE, MYSQL_USER und MYSQL_PASSWORD ein, die jeweils in der .env-Datei in Schritt 2 definiert wurden. Klicken Sie auf Erweiterte Optionen und setzen Sie den Wert für Host auf den Namen des mysql-Dienstcontainers. Klicken Sie auf Speichern und fortfahren.

      Datenbankeinrichtungsseite auf der Drupal-Weboberfläche

      Nach Konfiguration der Datenbank beginnt die Installation der Standardmodule und Themen von Drupal:

      Installationsseite der Website auf der Drupal-Weboberfläche

      Nachdem die Website installiert ist, werden wir auf die Einrichtungsseite der Drupal-Website geleitet, um den Namen der Website, die E-Mail-Adresse, den Benutzernamen, das Passwort und die Ländereinstellungen zu konfigurieren. Geben Sie die Informationen an und klicken Sie auf Speichern und fortfahren:

      Konfigurationsseite der Website auf der Drupal-Weboberfläche

      Nachdem wir auf Speichern und fortfahren geklickt haben, sehen wir die Seite Willkommen bei Drupal. Diese zeigt uns, dass unsere Drupal-Website eingerichtet ist und erfolgreich ausgeführt wird.

      Seite Willkommen bei Drupal auf der Drupal-Weboberfläche

      Nachdem die Installation von Drupal nun abgeschlossen ist, müssen wir sicherstellen, dass unsere SSL-Zertifikate automatisch erneuert werden.

      Schritt 7 — Erneuern der Zertifikate

      Let’s-Encrypt-Zertifikate sind 90 Tage gültig. Daher müssen wir einen automatisierten Erneuerungsprozess einrichten, um sicherzustellen, dass sie nicht ablaufen. Eine Möglichkeit hierzu ist das Erstellen eines Jobs mit dem Planungsprogramm cron. In diesem Fall erstellen wir einen cron-Job, der in regelmäßigen Abständen ein Skript ausführt, das unsere Zertifikate erneuert und die Nginx-Konfiguration neu lädt.

      Wir erstellen die Datei ssl_renew.sh, um unsere Zertifikate zu erneuern:

      Fügen Sie folgenden Code hinzu. Denken Sie daran, den Verzeichnisnamen durch Ihren eigenen non-root user zu ersetzen:

      ~/drupal/ssl_renew.sh

      
      #!/bin/bash
      
      cd /home/sammy/drupal/
      /usr/local/bin/docker-compose -f docker-compose.yml run certbot renew --dry-run && 
      /usr/local/bin/docker-compose -f docker-compose.yml kill -s SIGHUP webserver
      

      Das Skript wechselt zum ~/drupal-Projektverzeichnis und führt die folgenden docker-compose-Befehle aus.

      • docker-compose run: Hiermit wird ein certbot-Container gestartet und der in unserer certbot-Dienstdefinition verfügbare command überschrieben. Anstatt des Unterbefehls certonly verwenden wir hier den Unterbefehl renew, mit dem Zertifikate, die kurz vor Ablauf stehen, erneuert werden. Wir haben hier die Option --dry-run zum Testen unseres Skripts hinzugefügt.

      • docker-compose kill: Hiermit wird ein SIGHUP-Signal an den webserver-Container gesendet, um die Nginx-Konfiguration neu zu laden.

      Schließen Sie die Datei und machen Sie sie mit folgendem Befehl ausführbar:

      • sudo chmod +x ssl_renew.sh

      Öffnen Sie als Nächstes die Datei root crontab, um das Erneuerungsskript in einem angegebenen Intervall auszuführen:

      Wenn Sie die Datei zum ersten Mal bearbeiten, werden Sie dazu aufgefordert, einen Texteditor zum Öffnen der Datei zu wählen:

      Output

      no crontab for root - using an empty one Select an editor. To change later, run 'select-editor'. 1. /bin/nano 2. /usr/bin/vim.basic 3. /usr/bin/vim.tiny 4. /bin/ed Choose 1-4 [1]: ...

      Fügen Sie am Ende der Datei die folgende Zeile hinzu und ersetzen Sie sammy mit Ihrem Benutzernamen:

      crontab

      ...
      */5 * * * * /home/sammy/drupal/ssl_renew.sh >> /var/log/cron.log 2>&1
      

      Hiermit wird das Job-Intervall auf alle fünf Minuten festgelegt, sodass wir testen können, ob unsere Erneuerungsanfrage wie beabsichtigt funktioniert hat oder nicht. Außerdem haben wir eine Protokolldatei, cron.log, zum Aufzeichnen der relevanten Ausgabe erstellt.

      Verwenden Sie nach fünf Minuten den Befehl tail, um cron.log zu prüfen und zu sehen, ob die Erneuerungsanfrage erfolgreich war oder nicht:

      • tail -f /var/log/cron.log

      Sie sehen eine Ausgabe, die eine erfolgreiche Erneuerung bestätigt:

      Output

      ** DRY RUN: simulating 'certbot renew' close to cert expiry ** (The test certificates below have not been saved.) Congratulations, all renewals succeeded. The following certs have been renewed: /etc/letsencrypt/live/your_domain/fullchain.pem (success) ** DRY RUN: simulating 'certbot renew' close to cert expiry ** (The test certificates above have not been saved.) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

      Drücken Sie STRG+C, um den tail-Prozess zu beenden.

      Wir können jetzt die Datei crontab ändern, um das Skript jeden zweiten Tag der Woche um 02:00 Uhr auszuführen. Ändern Sie die letzte Zeile der crontab wie folgt:

      crontab

      ...
      * 2 * * 2 /home/sammy/drupal/ssl_renew.sh >> /var/log/cron.log 2>&1
      

      Speichern und schließen Sie die Datei.

      Nun entfernen wir die Option --dry-run aus dem Skript ssl_renew.sh. Öffnen Sie es zunächst:

      Ändern Sie dann den Inhalt wie folgt:

      ~/drupal/ssl_renew.sh

      #!/bin/bash
      
      cd /home/sammy/drupal/
      /usr/local/bin/docker-compose -f docker-compose.yml run certbot renew && 
      /usr/local/bin/docker-compose -f docker-compose.yml kill -s SIGHUP webserver
      

      Unser cron-Job kümmert sich nun um den Ablauf unserer SSL-Zertifikate, indem er sie erneuert, wenn sie hierfür infrage kommen.

      Zusammenfassung

      In diesem Tutorial haben wir Docker Compose verwendet, um eine Drupal-Installation mit einem Nginx-Webserver zu erstellen. Als Teil des Workflows haben wir TLS/SSL-Zertifikate für die Domäne erlangt, mit der wir unsere Drupal-Website verknüpfen wollten, und einen cron-Job erstellt, um diese Zertifikate bei Bedarf zu erneuern.

      Wenn Sie mehr über Docker erfahren möchten, besuchen Sie unsere Docker-Themenseite.



      Source link

      Cómo eliminar imágenes, contenedores y volúmenes de Docker


      Una página con trucos de Docker

      Introducción

      Docker hace que sea fácil envolver sus aplicaciones y servicios en contenedores para poder ejecutarlos en cualquier lugar. Sin embargo, a medida que se trabaja con Docker, también es fácil acumular una cantidad excesiva de imágenes, contenedores y volúmenes de datos que consumen recursos y ocupan espacio en disco.

      Docker le brinda todas las herramientas necesarias para limpiar su sistema desde la línea de comandos. En esta guía a modo de página de trucos se brinda una referencia rápida a comandos útiles para liberar espacio en el disco y mantener su sistema organizado mediante la eliminación de imágenes, contenedores y volúmenes no utilizados de Docker.

      Cómo utilizar esta guía:

      • Esta guía se ofrece con formato de página de trucos con fragmentos de líneas de comandos independientes.
      • Vaya a cualquiera de las secciones que corresponda a la tarea que está tratando de completar.

      La sintaxis de sustitución de comandos, command $(command), que se utiliza en los comandos, está disponible en muchos shells populares como bash, zsh y Windows Powershell.

      Eliminar las imágenes, los contenedores, los volúmenes y las redes sin utilizar o pendientes.

      Docker proporciona un solo comando que eliminará cualquier recurso (imágenes, contenedores, volúmenes y redes) que estén pendientes (no asociados con un contenedor):

      Para eliminar adicionalmente los contenedores detenidos y todas las imágenes no utilizadas (no solo aquellas pendientes), añada el indicador -a al comando:

      Eliminar imágenes de Docker

      Eliminar una o más imágenes específicas

      Utilice el comando docker images con el indicador -a para localizar el ID de las imágenes que quiere eliminar. Esto le mostrará todas las imágenes, incluidas las capas de imagen intermedias. Cuando localice las imágenes que desee eliminar, puede pasar su ID o etiqueta a docker rmi:

      Enumerar:

      Eliminar:

      Eliminar imágenes pendientes

      Las imágenes de Docker constan de varias capas. Las imágenes pendientes son capas que no tienen relación con imágenes etiquetadas. Ya no sirven para nada y ocupan espacio en el disco. Se pueden ubicar añadiendo el indicador de filtro -f junto con el valor dangling=true al comando docker images. Si está seguro de que quiere eliminarlas, puede utilizar el comando docker images purge:

      Nota: Si crea una imagen sin etiquetar, aparecerá en la lista de imágenes pendientes porque no está asociada a una imagen con etiqueta. Puede evitar esta situación proporcionando una etiqueta cuando cree imágenes y puede etiquetar de forma retroactiva una imagen con el comando docker tag.

      Enumerar:

      • docker images -f dangling=true

      Eliminar:

      Eliminar imágenes según un patrón

      Puede encontrar todas las imágenes que coinciden con un patrón utilizando una combinación de docker images y grep. Cuando esté conforme, puede eliminarlas utilizando awk para pasar los ID a docker rmi. Tenga en cuenta que Docker no proporciona estas utilidades y que estas no están necesariamente disponibles en todos los sistemas:

      Enumerar:

      • docker images -a | grep "pattern"

      Eliminar:

      • docker images -a | grep "pattern" | awk '{print $3}' | xargs docker rmi

      Eliminar todas las imágenes

      Es posible enumerar todas las imágenes de Docker de un sistema añadiendo -a al comando docker images. Una vez que esté seguro de que desea eliminarlas por completo, puede añadir el indicador -q para pasar el ID de la imagen a docker rmi:

      Enumerar:

      Eliminar:

      • docker rmi $(docker images -a -q)

      Eliminar contenedores

      Eliminar uno o más contenedores específicos

      Utilice el comando docker ps con el indicador -a para localizar el nombre o la ID de los contenedores que desee eliminar.

      Enumerar:

      Eliminar:

      • docker rm ID_or_Name ID_or_Name

      Eliminar un contenedor al cerrarlo

      Si al crear un contenedor sabe que no querrá conservarlo una vez que lo termine, puede ejecutar docker run --rm para eliminarlo automáticamente después de cerrarlo.

      Ejecutar y eliminar:

      • docker run --rm image_name

      Eliminar todos los contenedores terminados

      Puede localizar contenedores utilizando docker ps -a y filtrarlos según su estado: “created”, “restarting”, “running”, “paused” o “exited”. A fin de revisar la lista de contenedores terminados, utilice el indicador -f para filtrar según el estado. Cuando haya verificado que desea eliminar esos contenedores, utilice -q para pasar los IDs al comando docker rm.

      Enumerar:

      • docker ps -a -f status=exited

      Eliminar:

      • docker rm $(docker ps -a -f status=exited -q)

      Eliminar contenedores utilizando más de un filtro

      Los filtros de Docker pueden combinarse repitiendo el indicador de filtro con un valor adicional. Esto da como resultado una lista de contenedores que cumplen cualquier condición. Por ejemplo, si desea eliminar todos los contenedores marcados como Created (un estado que se puede generar cuando ejecuta un contenedor con un comando no válido) o Exited, puede utilizar dos filtros:

      Enumerar:

      • docker ps -a -f status=exited -f status=created

      Eliminar:

      • docker rm $(docker ps -a -f status=exited -f status=created -q)

      Eliminar contenedores según un patrón

      Puede encontrar todos los contenedores que coinciden con un patrón utilizando la combinación de docker ps y grep. Cuando esté convencido de que tiene la lista que desea eliminar, podrá utilizar awk y xargs para proporcionar el ID a docker rmi. Tenga en cuenta que Docker no proporciona estas utilidades y que no están necesariamente disponibles en todos los sistemas:

      Enumerar:

      • docker ps -a | grep "pattern

      Eliminar:

      • docker ps -a | grep "pattern" | awk '{print $3}' | xargs docker rmi

      Detener y eliminar todos los contenedores

      Puede revisar los contenedores de su sistema con docker ps. Al añadir el indicador -a se mostrarán todos los contenedores. Cuando esté seguro de que desea eliminarlos, puede añadir el indicador -q para proporcionar los ID a los comandos docker stop y docker rm:

      Enumerar:

      Eliminar:

      • docker stop $(docker ps -a -q)
      • docker rm $(docker ps -a -q)

      Eliminar volúmenes

      Eliminar uno o más volúmenes específicos – Docker 1.9 y versiones posteriores

      Utilice el comando docker volume ls para ubicar el nombre o los nombres de los volúmenes que desea eliminar. Luego, puede eliminar uno o más volúmenes con el comando docker volume rm:

      Enumerar:

      Eliminar:

      • docker volume rm volume_name volume_name

      Eliminar volúmenes pendientes: Docker 1.9 y versiones posteriores

      Debido a que el punto de volúmenes debe existir independientemente de los contenedores, cuando se elimina un contenedor un volumen no se elimina automáticamente al mismo tiempo. Cuando un volumen existe y ya no está conectado a ningún contenedor, se denomina “volumen pendiente”. Para ubicarlos y confirmar que desea eliminarlos, puede utilizar el comando docker volume ls con un filtro a fin de limitar los resultados a volúmenes pendientes. Cuando esté conforme con la lista, puede eliminarlos con docker volume prune:

      Enumerar:

      • docker volume ls -f dangling=true

      Eliminar:

      Eliminar un contenedor y su volumen

      Si creó un volumen sin nombre, puede eliminarlo al mismo tiempo que el contenedor utilizando el indicador -v. Tenga en cuenta que esto solo funciona con volúmenes sin nombre. Cuando el contenedor se elimina correctamente, se muestra su ID. Tenga en cuenta que no se hace referencia a la eliminación del volumen. Si no tiene nombre, se elimina silenciosamente del sistema. Si se nombra, permanece silenciosamente presente.

      Eliminar:

      • docker rm -v container_name

      Conclusión

      Esta guía abarca algunos de los comandos comunes que se utilizan para eliminar imágenes, contenedores y volúmenes con Docker. Hay una gran cantidad adicional de combinaciones e indicadores que se pueden utilizar con cada uno de estos. Para acceder a una guía completa de lo que está disponible, consulte la documentación de Docker sobre docker system prune, docker rmi, docker rm y docker volume rm. Si hay tareas de limpieza comunes que desearía ver en la guía, haga preguntas o sugerencias en los comentarios.



      Source link