Skip to content

Improve docker deployment configuration and add documentation - #1258

Closed
hbyecoding wants to merge 1 commit into
eclipse-openvsx:mainfrom
hbyecoding:fix/docker-deployment
Closed

hbyecoding wants to merge 1 commit into
eclipse-openvsx:mainfrom
hbyecoding:fix/docker-deployment

Conversation

@hbyecoding

Copy link
Copy Markdown

fix 类型

问题描述

当前 OpenVSX 的 Docker 部署存在以下问题:

  1. Server 服务启动失败 (Exit 127)
  2. Elasticsearch 健康检查失败
  3. 服务依赖关系配置不合理

修复内容

Docker 配置优化

  1. 修改 server 镜像

    • 从 openjdk:17 更改为 openjdk:17-bullseye
    • 添加必要工具: curl, findutils 等
  2. 优化 Elasticsearch 配置

    • 调整内存设置
    • 改进健康检查机制
    • 优化启动顺序
  3. 服务依赖关系

    • 移除不必要的 cli 服务
    • 保留并优化 webui 服务
    • 完善服务间的依赖关系配置

文档改进

  1. 新增 docs/docker-deployment-fix.md
    • 详细的部署步骤说明
    • 配置示例和最佳实践
    • 常见问题排查指南

验证方法

  1. 清理现有容器和卷:
docker-compose down -v
  1. 使用新配置启动服务:
docker-compose --profile openvsx up -d
  1. 验证服务状态:
docker-compose ps
docker-compose logs

hongbo@coduora openvsx (fix/docker-deployment) $ docker-compose ps -a
Name Command State Ports


openvsx_elasticsearch_1 /bin/tini -- /usr/local/bi ... Up (healthy) 0.0.0.0:9200->9200/tcp,:::9200->9200/tcp,
0.0.0.0:9300->9300/tcp,:::9300->9300/tcp
openvsx_postgres_1 docker-entrypoint.sh postgres Up 0.0.0.0:5432->5432/tcp,:::5432->5432/tcp
openvsx_server_1 bash -c Up (health: starting) 0.0.0.0:8080->8080/tcp
apt-get update ...
openvsx_webui_1 docker-entrypoint.sh sh -c ... Up 0.0.0.0:3000->3000/tcp

例如 docker-compose logs -f server

server_1 | Downloading https://services.gradle.org/distributions/gradle-8.1.1-bin.zip
server_1 | ...........10%............20%............30%............40%............50%............60%............70%............80%...........90%............100%
server_1 |
server_1 | Welcome to Gradle 8.1.1!
server_1 |
server_1 | Here are the highlights of this release:
server_1 | - Stable configuration cache
server_1 | - Experimental Kotlin DSL assignment syntax
server_1 | - Building with Java 20
server_1 |
server_1 | For more details see https://docs.gradle.org/8.1.1/release-notes.html
server_1 |
server_1 | Starting a Gradle Daemon (subsequent builds will be faster)
server_1 | 2025-06-10T05:24:21.496Z INFO [openvsx-server,,] 680 --- [openvsx-server] [ restartedMain] [ ] o.eclipse.openvsx.RegistryApplication : Started RegistryApplication in 15.715 seconds (process running for 16.369)

  1. 检查3000 是否curl 通:
curl -I localhost:3000
HTTP/1.1 200 OK
X-Powered-By: Express
Accept-Ranges: bytes
Cache-Control: public, max-age=0
Last-Modified: Tue, 10 Jun 2025 01:45:47 GMT
ETag: W/"160-1975783d7e1"
Content-Type: text/html; charset=UTF-8
Content-Length: 352
Date: Tue, 10 Jun 2025 05:25:07 GMT
Connection: keep-alive
Keep-Alive: timeout=5
  1. 检查 PostgreSQL: 5432
telnet localhost 5432

Trying 127.0.0.1... # 正在尝试连接到本地主机的 IP 地址
Connected to localhost. # 成功连接到本地主机
Escape character is '^]'. # 退出 telnet 的快捷键是 Ctrl + ]

  1. 检查 8080 是否 healthy:
curl http://localhost:8080/actuator/health

curl http://localhost:8080/actuator/health
{"status":"UP","groups":["liveness","readiness"]}

注意事项

  • 首次启动时 Elasticsearch 可能需要 1-2 分钟完成初始化
  • 我这里的 compose 是 v1 版本的 , 用的是 docker-compose 命令

@netomi netomi changed the title fix: improve docker deployment configuration and add documentation Improve docker deployment configuration and add documentation Dec 10, 2025
@netomi

netomi commented Sep 8, 2026

Copy link
Copy Markdown
Contributor

Thanks for this, and apologies it sat so long.

I went through it against the current docker-compose.yml. Two of your changes have since landed independently — the ES_JAVA_OPTS memory settings and the memlock ulimits are both in main now — and some of the rest was overtaken by the file moving on (the base image is eclipse-temurin:25-jdk these days, so the openjdk:17-bullseye fix no longer applies).

But three of the problems you reported are still there, and I have opened #2182 for them:

  1. The profiles are broken. docker compose --profile openvsx up fails with service "server" depends on undefined service "postgres": invalid compose project, because server is in the openvsx profile and postgres is not. Adding those services to the profile — exactly what you did — is the fix. Our own doc/development.md gives that command as the way to start a dev stack, so it is the first thing a new contributor hits.

  2. The elasticsearch healthcheck names a host that does not exist (elasticsearch01). From inside the container it is exit 6 while the cluster is green, so it never went healthy.

  3. The server healthcheck could only ever exit 127 — the same class of failure you hit, just moved to a newer base image: eclipse-temurin:25-jdk has no curl, wget, nc or python. I used bashs /dev/tcp rather than apt-get install curl on every start, so there is no network round trip per up, but your diagnosis was right.

And with 2 and 3 fixed, depends_on: condition: service_healthy finally works, which was the ordering problem you originally described.

#2182 credits you and closes this one. Sorry again for the delay — the report was correct, it just needed re-basing onto a file that had changed a lot underneath it.

netomi added a commit that referenced this pull request Sep 8, 2026
* fix: make the documented docker compose command work

doc/development.md offers `docker compose --profile openvsx --profile kibana up`
as the way to start a development stack. It does not start anything:

    service "server" depends on undefined service "postgres": invalid compose project

`server` is in the `openvsx` and `backend` profiles while `postgres` is in `db`
and `debug`, so the project fails to validate before a container is created.
Anyone following our own instructions hits this first. postgres and
elasticsearch now also belong to the profiles that select the service depending
on them.

Two healthchecks could never have passed either, which is why nothing noticed:

  - elasticsearch curled `http://elasticsearch01:9200`, a host that does not
    exist here - the service is `elasticsearch`. Inside the container that
    resolves to exit 6 while the cluster is green, so it sat in "starting" for
    the full 50 retries and then reported unhealthy.
  - server curled `localhost:8081/actuator/health`, and eclipse-temurin:25-jdk
    ships no curl, wget, nc or python. bash is there, so its /dev/tcp asks the
    actuator the same question with nothing to install. The alternative was
    apt-get on every start, which is what #1258 proposed and what its author
    was working around when the base image was openjdk:17.

With both fixed, `depends_on` can finally wait on readiness rather than only on
container creation, which is the ordering problem #1258 originally reported: the
server no longer races a Postgres that has not finished initialising or an
Elasticsearch that has not opened its port. postgres gained a pg_isready check
for the same reason.

Credit to @hbyecoding, who reported all of this in #1258 in June 2025 against
the file as it then was. Most of that PR has since been overtaken - the memory
settings and ulimits it added are in main already, and the base image it fixed
is gone - but the three findings underneath it were still here.

Verified with docker: both profile commands now resolve, postgres reports
healthy in ~12s and elasticsearch in ~36s where it previously never did, and a
cold `up server` creates the server container only after both report healthy
(dependencies at 20:15:45, server at 20:16:01).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* fix: declare compose dependencies without owning them

Adding postgres and elasticsearch to the `openvsx` and `backend` profiles made
those profiles claim services that are not theirs - postgres is not part of the
backend - and it only papered over one instance of a general problem. Selecting
a profile that holds a service but not that service's dependency is a hard
error, and four of the documented profiles were in that state:

    --profile frontend      service "webui" depends on undefined service "server"
    --profile commandline   service "cli" depends on undefined service "server"
    --profile kibana        service "kibana" depends on undefined service "elasticsearch"
    --profile openvsx       service "server" depends on undefined service "postgres"

`required: false` says the same thing without the ownership: each service
declares what it needs, and the profiles selected decide what is actually
present. Every profile now resolves to exactly the services it names, and
postgres and elasticsearch stay in `db`/`es`/`debug` where they belong.

Verified that this keeps the health gating rather than trading it away, which
was the reason for the conditions in the first place: with
`--profile openvsx --profile debug`, both dependencies are waited on and the
server container is created only afterwards (dependencies 20:45:32, server
20:45:47). An isolated compose project confirms the same for a dependency that
turns healthy on a delay - it is waited for whenever it is enabled, and skipped
silently when it is not.

The cost is that `--profile openvsx` on its own now starts a server with no
database instead of refusing to start at all, so the documentation says to
select the infrastructure too.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* fix: run the server healthcheck under bash, and document the rest of the profiles

Review feedback from Copilot, which was right and caught a check that would
have been as broken as the one it replaced. CMD-SHELL runs /bin/sh, and on
eclipse-temurin /bin/sh is dash:

    $ docker run --rm --entrypoint sh eclipse-temurin:25-jdk -c 'ls -l /bin/sh'
    /bin/sh -> dash
    $ ... -c 'exec 3<>/dev/tcp/127.0.0.1/22'
    sh: 1: cannot create /dev/tcp/127.0.0.1/22: Directory nonexistent

/dev/tcp is a bash feature. I had verified the command with `--entrypoint bash`
and not through the path the healthcheck actually takes, so I proved the wrong
thing. Now the exec form, invoking bash by name.

Re-verified through compose, since `docker run --health-cmd` takes a shell
string and so reproduces the dash bug rather than testing the fix: a container
serving {"status":"UP"} on 8081 reports healthy, and one serving nothing
reports unhealthy.

Also documents `minio`, `valkey` and `valkey-admin`, which had no entry in
development.md at all, along with the ports and credentials they come up on.
Every profile the compose file defines is now listed.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* fix: align kibana with the elasticsearch it connects to

kibana:8.7.1 against elasticsearch:9.2.8 does not work at all - Kibana refuses
a cluster on a different major version:

    [ERROR][elasticsearch-service] This version of Kibana (v8.7.1) is
    incompatible with the following Elasticsearch nodes in your cluster:
    v9.2.8 @ 172.19.0.2:9200

So the `kibana` profile has been non-functional since Elasticsearch moved to 9.
Both are now 9.2.8, and the comment says they move together.

While there: ELASTICSEARCH_URL has not been a Kibana setting since 7.0, where
`elasticsearch.url` was replaced by `elasticsearch.hosts`. The image carries no
such key at all, so that line was quietly doing nothing:

    $ docker run --rm kibana:9.2.8 grep elasticsearch config/kibana.yml
    elasticsearch.hosts: [ "http://elasticsearch:9200" ]

Renamed to ELASTICSEARCH_HOSTS. The image default happens to be the same URL,
so this had gone unnoticed - but relying on an image default matching our
service name is not something to leave to chance.

Kibana now also waits for the Elasticsearch healthcheck rather than merely for
its container, which is available since that check works again.

Verified: kibana 9.2.8 against elasticsearch 9.2.8 reports overall `available`
with `elasticsearch: available`, where 8.7.1 logs the incompatibility above.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* docs: point the docker-compose links at the file they mean

Review feedback. `[docker-compose.yml](docker-compose.yml)` is relative to
doc/, so it resolved to doc/docker-compose.yml, which does not exist.

The other mention of the same file, a few lines up, was broken differently:
`[docker-compose.yml]` is a shortcut reference with no definition anywhere in
the document, so it renders as literal brackets rather than a link.

Both predate this pull request, but this is the document it has been editing
and they point at the file it is about.

Audited the rest of the file's relative links while there; these two were the
only broken ones.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
@netomi netomi closed this in #2182 Sep 8, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants