【问题标题】:Docker-compose up exited with code 1 but successful docker-compose buildDocker-compose up 以代码 1 退出,但 docker-compose 构建成功
【发布时间】:2020-02-16 01:36:08
【问题描述】:

当尝试 docker-compose up 时,我从前端和后端收到错误,它们以代码 1 退出。 docker ps 显示 postgres 容器仍在运行,但前端和后端仍然退出。使用 npm start,没有错误。我不知道这是否有帮助,但我的文件没有从我的 src 文件夹复制到 /usr/src/app/ 所以我的 docker-compose 或 Dockerfiles 可能有错误。

Docker ps 显示:

CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                    NAMES 
509208b2243b        postgres:latest     "docker-entrypoint.s…"   14 hours ago        Up 11 minutes       0.0.0.0:5432->5432/tcp   example_db_1
docker-compose.yml

version: '3'

services:
  frontend:
    build: ./frontend
    volumes:
      - ./data/nginx:/etc/nginx/conf.d
      - ./data/certbot/conf:/etc/letsencrypt
      - ./data/certbot/www:/var/www/certbot
      - ./frontend/build:/usr/share/nginx/html
    ports:
      - 80:80
      - 443:443
    depends_on:
      - backend
  backend:
    build: ./backend
    volumes:
      - ./backend/src:/usr/src/app/src
      - ./data/certbot/conf:/etc/letsencrypt
    ports:
      - 3000:3000
    depends_on:
      - db
  db:
    image: postgres:latest
    restart: always
    environment:
      POSTGRES_USER: example
      POSTGRES_PASSWORD: example1234
      POSTGRES_DB: example
    ports:
      - 5432:5432
  certbot:
    image: certbot/certbot
    volumes:
      - ./data/certbot/conf:/etc/letsencrypt
      - ./data/certbot/www:/var/www/certbot
    # Automatic certificate renewal
    # entrypoint: "/bin/sh -c 'trap exit TERM; while :; do certbot renew; sleep 12h & wait $${!}; done;'"

这就是后端 Dockerfile 的样子。

FROM node:current-alpine

RUN mkdir -p /usr/src/app

WORKDIR /usr/src/app/

COPY package*.json /usr/src/app/

RUN npm install

COPY . /usr/src/app/

EXPOSE 3000

ENV NODE_ENV=production

CMD ["npm", "start"]

还有输出错误:

example_db_1 is up-to-date
Starting example_certbot_1 ... done
Starting example_backend_1 ... done
Starting example_frontend_1 ... done
Attaching to example_db_1, example_certbot_1, example_backend_1, example_frontend_1
backend_1   |
backend_1   | > example-backend@1.0.0 start /usr/src/app
backend_1   | > npx tsc; node ./out/
backend_1   |
certbot_1   | Saving debug log to /var/log/letsencrypt/letsencrypt.log
certbot_1   | Certbot doesn't know how to automatically configure the web server on this system. However, it can still get a certificate for you. Please run "certbot certonly" to do so. You'll need to manually configure your web server to use the resulting certificate.
frontend_1  | 2020/02/13 11:35:59 [emerg] 1#1: open() "/etc/letsencrypt/options-ssl-nginx.conf" failed (2: No such file or directory) in /etc/nginx/conf.d/app.conf:21
frontend_1  | nginx: [emerg] open() "/etc/letsencrypt/options-ssl-nginx.conf" failed (2: No such file or directory) in /etc/nginx/conf.d/app.conf:21
db_1        | The files belonging to this database system will be owned by user "postgres".
db_1        | This user must also own the server process.
db_1        |
db_1        | The database cluster will be initialized with locale "en_US.utf8".
db_1        | The default database encoding has accordingly been set to "UTF8".
db_1        | The default text search configuration will be set to "english".
db_1        |
db_1        | Data page checksums are disabled.
db_1        |
db_1        | fixing permissions on existing directory /var/lib/postgresql/data ... ok
db_1        | creating subdirectories ... ok
db_1        | selecting dynamic shared memory implementation ... posix
db_1        | selecting default max_connections ... 100
db_1        | selecting default shared_buffers ... 128MB
db_1        | selecting default time zone ... Etc/UTC
db_1        | creating configuration files ... ok
db_1        | running bootstrap script ... ok
db_1        | performing post-bootstrap initialization ... ok
db_1        | syncing data to disk ... ok
db_1        |
db_1        | initdb: warning: enabling "trust" authentication for local connections
db_1        | You can change this by editing pg_hba.conf or using the option -A, or
db_1        | --auth-local and --auth-host, the next time you run initdb.
db_1        |
db_1        | Success. You can now start the database server using:
db_1        |
db_1        |     pg_ctl -D /var/lib/postgresql/data -l logfile start
db_1        |
db_1        | waiting for server to start....2020-02-12 21:51:40.137 UTC [43] LOG:  starting PostgreSQL 12.1 (Debian 12.1-1.pgdg100+1) on x86_64-pc-linux-gnu, compiled by gcc (Debian 8.3.0-6) 8.3.0, 64-bit
db_1        | 2020-02-12 21:51:40.147 UTC [43] LOG:  listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432"
db_1        | 2020-02-12 21:51:40.229 UTC [44] LOG:  database system was shut down at 2020-02-12 21:51:39 UTC
db_1        | 2020-02-12 21:51:40.240 UTC [43] LOG:  database system is ready to accept connections
db_1        |  done
db_1        | server started
db_1        | CREATE DATABASE
db_1        |
db_1        |
db_1        | /usr/local/bin/docker-entrypoint.sh: ignoring /docker-entrypoint-initdb.d/*
db_1        |
db_1        | 2020-02-12 21:51:40.606 UTC [43] LOG:  received fast shutdown request
db_1        | waiting for server to shut down....2020-02-12 21:51:40.608 UTC [43] LOG:  aborting any 
active transactions
db_1        | 2020-02-12 21:51:40.614 UTC [43] LOG:  background worker "logical replication launcher" (PID 50) exited with exit code 1
db_1        | 2020-02-12 21:51:40.614 UTC [45] LOG:  shutting down
db_1        | 2020-02-12 21:51:40.652 UTC [43] LOG:  database system is shut down
db_1        |  done
db_1        | server stopped
db_1        |
db_1        | PostgreSQL init process complete; ready for start up.
db_1        |
db_1        | 2020-02-12 21:51:40.728 UTC [1] LOG:  starting PostgreSQL 12.1 (Debian 12.1-1.pgdg100+1) on x86_64-pc-linux-gnu, compiled by gcc (Debian 8.3.0-6) 8.3.0, 64-bit
db_1        | 2020-02-12 21:51:40.729 UTC [1] LOG:  listening on IPv4 address "0.0.0.0", port 5432   
db_1        | 2020-02-12 21:51:40.729 UTC [1] LOG:  listening on IPv6 address "::", port 5432        
db_1        | 2020-02-12 21:51:40.748 UTC [1] LOG:  listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432"
db_1        | 2020-02-12 21:51:40.788 UTC [61] LOG:  database system was shut down at 2020-02-12 21:51:40 UTC
db_1        | 2020-02-12 21:51:40.799 UTC [1] LOG:  database system is ready to accept connections
db_1        | 2020-02-13 09:51:41.562 UTC [787] LOG:  invalid length of startup packet
db_1        | 2020-02-13 11:09:27.384 UTC [865] FATAL:  password authentication failed for user "postgres"
db_1        | 2020-02-13 11:09:27.384 UTC [865] DETAIL:  Role "postgres" does not exist.
db_1        |   Connection matched pg_hba.conf line 95: "host all all all md5"
db_1        | 2020-02-13 11:32:18.771 UTC [1] LOG:  received smart shutdown request
db_1        | 2020-02-13 11:32:18.806 UTC [1] LOG:  background worker "logical replication launcher" 
(PID 67) exited with exit code 1
db_1        | 2020-02-13 11:32:18.806 UTC [62] LOG:  shutting down
db_1        | 2020-02-13 11:32:18.876 UTC [1] LOG:  database system is shut down
db_1        |
db_1        | PostgreSQL Database directory appears to contain a database; Skipping initialization   
db_1        |
db_1        | 2020-02-13 11:33:01.343 UTC [1] LOG:  starting PostgreSQL 12.1 (Debian 12.1-1.pgdg100+1) on x86_64-pc-linux-gnu, compiled by gcc (Debian 8.3.0-6) 8.3.0, 64-bit
db_1        | 2020-02-13 11:33:01.343 UTC [1] LOG:  listening on IPv4 address "0.0.0.0", port 5432   
db_1        | 2020-02-13 11:33:01.343 UTC [1] LOG:  listening on IPv6 address "::", port 5432        
db_1        | 2020-02-13 11:33:01.355 UTC [1] LOG:  listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432"
db_1        | 2020-02-13 11:33:01.427 UTC [23] LOG:  database system was shut down at 2020-02-13 11:32:18 UTC
db_1        | 2020-02-13 11:33:01.466 UTC [1] LOG:  database system is ready to accept connections   
example_certbot_1 exited with code 1
example_frontend_1 exited with code 1
backend_1   | Authenticating with database...
backend_1   | internal/fs/utils.js:220
backend_1   |     throw err;
backend_1   |     ^
backend_1   |
backend_1   | Error: ENOENT: no such file or directory, open '/etc/letsencrypt/live/example.org/privkey.pem'
backend_1   |     at Object.openSync (fs.js:440:3)
backend_1   |     at Object.readFileSync (fs.js:342:35)
backend_1   |     at Object.<anonymous> (/usr/src/app/out/index.js:68:23)
backend_1   |     at Module._compile (internal/modules/cjs/loader.js:955:30)
backend_1   |     at Object.Module._extensions..js (internal/modules/cjs/loader.js:991:10)
backend_1   |   syscall: 'open',                                 811:32)
backend_1   |   code: 'ENOENT',                                  loader.js:723:14)
backend_1   |   path: '/etc/letsencrypt/live/example.org/s/loader.js:1043:10)privkey.pem'
backend_1   | }
backend_1   | npm ERR! code ELIFECYCLE
backend_1   | npm ERR! errno 1
backend_1   | npm ERR! example-backend@1.0.0 start: `npx tsc; noprivkey.pem'de ./out/`
backend_1   | npm ERR! Exit status 1
backend_1   | npm ERR!
backend_1   | npm ERR! Failed at the example-backend@1.0.0 startde ./out/` script.
backend_1   | npm ERR! This is probably not a problem with npm. There is likely additional logging output above.                   script.
backend_1   |                                                    here is likely additional logging ou
backend_1   | npm ERR! A complete log of this run can be found in:
backend_1   | npm ERR!     /root/.npm/_logs/2020-02-13T11_36_10_3:30Z-debug.log                                                    30Z-debug.log
example_backend_1 exited with code 1

在此项目之外运行时,certbot 没有错误。

目录结构:

src/
    - docker-compose.yml
    - init.letsencrypt.sh
    - .gitignore
    backend
        src
        - Dockerfile
        - package.json
        - .gitignore
    data
        nginx
        - app.conf
    frontend
        src
        - Dockerfile
        - package.json
        - .gitignore

任何帮助将不胜感激,谢谢。

更新了 nginx.conf:

server {
    listen 80;
    server_name example.org;

    location / {
        root /var/www/html/;
        index index.html;
        autoindex on;
    }

    location /frontend {
        proxy_pass http://example.org:8080;
        try_files $uri /public/index.html;
    }

    location /backend {
        proxy_pass http://example.org:3000;
    }

    location /db {
        proxy_pass http://example.org:5432;
    }
}

更改 .gitignore 时出现新错误:

frontend_1  | 2020/02/13 16:34:58 [emerg] 1#1: cannot load certificate "/etc/letsencrypt/live/example.org/fullchain.pem": 
BIO_new_file() failed (SSL: error:02001002:system library:fopen:No such file or directory:fopen('/etc/letsencrypt/live/example.org/fullchain.pem','r') error:2006D080:BIO routines:BIO_new_file:no such file)
frontend_1  | nginx: [emerg] cannot load certificate "/etc/letsencrypt/live/example.org/fullchain.pem": BIO_new_file() failed (SSL: error:02001002:system library:fopen:No such file or directory:fopen('/etc/letsencrypt/live/example.org/fullchain.pem','r') error:2006D080:BIO routines:BIO_new_file:no such file)
example_frontend_1 exited with code 1

【问题讨论】:

  • 你在data/certbot/conf里面有options-ssl-nginx.conf吗?
  • 是的,它存在。
  • 确定吗?它不在您的目录结构中。
  • 对不起,它存在于我的服务器上。我假设当我运行 certbot 时它创建了目录结构。它存在于 /src/data/certbot - 与 ssl-dhparams 相同。
  • 抱歉忘了回复,问题出在我的 nginx 和 docker-compose 配置上。感谢您的帮助。

标签: node.js postgresql docker docker-compose


【解决方案1】:

设置似乎很复杂。我给你的建议:尝试使用 certbot 作为自己的 docker-container 来减少复杂的开销。

#docker-compose.yml

version: '3'

services:
  frontend:
    build: ./frontend
    volumes:
      - ./data/nginx:/etc/nginx/conf.d
      # no source-code of the frontend via volumes - 
      # only a nginx-image with your source. 
      # nginx-conf as volume is valid.
    ports:
      - 8080:80
    depends_on:
      - backend
  backend:
    build: ./backend
    # dont put your source as volume in, 
    # your docker-image should contains the whole code
    # and no certbot magic here
    ports:
      - 3000:3000
    depends_on:
      - db
  db:
    image: postgres:latest
    restart: always
    environment:
      POSTGRES_USER: example
      POSTGRES_PASSWORD: example1234
      POSTGRES_DB: example
    ports:
      - 5432:5432

这更加简洁易读。现在你应该在你的主机上设置一个反向代理(easy with nginx)。将您发布的端口配置到您的 nginx-reverse-proxy 中(以proxy_pass localhost:8080 为例,您的前端)。

之后,您可以安装 certbot 并获取您的lets-encrypt-certificates。 certbot 应该会自动发现您的 nginx-endpoints 并可以自动更新您的证书。

【讨论】:

  • 感谢您的快速回答,但无论添加您的建议,我仍然会遇到相同的错误。如果在运行 docker-compose up 之前证书已经存在,会有什么不同吗?
  • 没有。您可以为我们发布您的 app.conf 吗?似乎有错误(它试图对不存在的/etc/letsencrypt/options-ssl-nginx.conf 做一些事情)。
最近更新 更多