Skip to content

Commit 17b0ef0

Browse files
committed
Run separate web server, registry watcher and build servers in docker-compose
1 parent ad94784 commit 17b0ef0

File tree

6 files changed

+191
-113
lines changed

6 files changed

+191
-113
lines changed

.github/workflows/docker.yml

+4-2
Original file line numberDiff line numberDiff line change
@@ -9,5 +9,7 @@ jobs:
99
steps:
1010
- uses: actions/checkout@v4
1111

12-
- name: Build the Docker image
13-
run: docker build -t docs-rs -f dockerfiles/Dockerfile .
12+
- run: docker build --target web-server -f dockerfiles/Dockerfile .
13+
- run: docker build --target build-server -f dockerfiles/Dockerfile .
14+
- run: docker build --target registry-watcher -f dockerfiles/Dockerfile .
15+
- run: docker build --target cli -f dockerfiles/Dockerfile .

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
/ignored
22
/.env
3+
/.docker.env
34
/src/web/badge/Cargo.lock
45
target
56
*.css

README.md

+15-11
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ mkdir -p ignored/cratesfyi-prefix/crates.io-index
6464
# Builds the docs.rs binary
6565
cargo build
6666
# Start the external services.
67-
docker compose up -d db s3
67+
docker compose up --wait db s3
6868
# anything that doesn't run via docker-compose needs the settings defined in
6969
# .env. Either via `. ./.env` as below, or via any dotenv shell integration.
7070
. ./.env
@@ -106,14 +106,18 @@ which uses docker-compose for the web server as well.
106106
This will not cache dependencies - in particular, you'll have to rebuild all 400 whenever the lockfile changes -
107107
but makes sure that you're in a known environment so you should have fewer problems getting started.
108108

109-
You can also use the `web` container to run builds on systems which don't support running builds directly (mostly on Mac OS or Windows):
109+
You'll need to `touch .docker.env` first, this file can have any environment
110+
variable overrides you want to use in docker containers.
111+
112+
You can also use the `cli` container to run builds on systems which don't support running builds directly (mostly on Mac OS or Windows):
113+
110114
```sh
111115
# run a build for a single crate
112-
docker compose run web build crate regex 1.3.1
116+
docker compose run --rm cli build crate regex 1.3.1
113117
# or build essential files
114-
docker compose run web build add-essential-files
115-
# rebuild the web container when you changed code.
116-
docker compose up -d web --build
118+
docker compose run --rm cli build add-essential-files
119+
# rebuild containers when you changed code.
120+
docker compose up --wait --build
117121
```
118122

119123
You can also run other commands like the setup above from within the container:
@@ -142,7 +146,7 @@ Three services are defined:
142146

143147
#### Rebuilding Containers
144148

145-
To rebuild the site, run `docker compose build`.
149+
To rebuild the site, run `docker compose --profile all build`.
146150
Note that docker-compose caches the build even if you change the source code,
147151
so this will be necessary anytime you make changes.
148152

@@ -163,7 +167,7 @@ This is probably because you have `git.autocrlf` set to true,
163167

164168
##### I see the error `/opt/rustwide/cargo-home/bin/cargo: cannot execute binary file: Exec format error` when running builds.
165169

166-
You are most likely not on a Linux platform. Running builds directly is only supported on `x86_64-unknown-linux-gnu`. On other platforms you can use the `docker compose run web build [...]` workaround described above.
170+
You are most likely not on a Linux platform. Running builds directly is only supported on `x86_64-unknown-linux-gnu`. On other platforms you can use the `docker compose run --rm cli build [...]` workaround described above.
167171

168172
See [rustwide#41](https://github.com/rust-lang/rustwide/issues/41) for more details about supporting more platforms directly.
169173

@@ -191,11 +195,11 @@ cargo run -- start-web-server
191195
```sh
192196
# Builds <CRATE_NAME> <CRATE_VERSION> and adds it into database
193197
# This is the main command to build and add a documentation into docs.rs.
194-
# For example, `docker compose run web build crate regex 1.1.6`
198+
# For example, `docker compose run --rm cli build crate regex 1.1.6`
195199
cargo run -- build crate <CRATE_NAME> <CRATE_VERSION>
196200

197-
# alternatively, via the web container
198-
docker compose run web build crate <CRATE_NAME> <CRATE_VERSION>
201+
# alternatively, within docker-compose containers
202+
docker compose run --rm cli build crate <CRATE_NAME> <CRATE_VERSION>
199203

200204
# Builds every crate on crates.io and adds them into database
201205
# (beware: this may take months to finish)

docker-compose.yml

+108-38
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,119 @@
1-
version: "3"
1+
version: "3.4"
2+
3+
x-healthcheck: &healthcheck-interval
4+
interval: 10s
5+
timeout: 1s
6+
start_period: 10s
7+
# TODO: https://github.com/docker/compose/issues/10461
8+
# start_interval: 1s
9+
10+
x-environment: &environment
11+
RUST_BACKTRACE: true
12+
13+
DOCSRS_PREFIX: /opt/docsrs/prefix
14+
15+
DOCSRS_DATABASE_URL: postgresql://cratesfyi:password@db
16+
DOCSRS_MIN_POOL_SIZE: 2
17+
DOCSRS_MAX_POOL_SIZE: 10
18+
19+
DOCSRS_STORAGE_BACKEND: s3
20+
21+
S3_ENDPOINT: http://s3:9000
22+
AWS_ACCESS_KEY_ID: cratesfyi
23+
AWS_SECRET_ACCESS_KEY: secret_key
24+
25+
DOCSRS_RENDER_THREADS: 2
26+
27+
DOCSRS_RUSTWIDE_WORKSPACE: /opt/docsrs/rustwide
28+
DOCSRS_DOCKER: true
29+
DOCSRS_DOCKER_IMAGE: ghcr.io/rust-lang/crates-build-env/linux-micro
30+
DOCSRS_BUILD_CPU_LIMIT: 2
31+
DOCSRS_INCLUDE_DEFAULT_TARGETS: false
32+
33+
x-builder: &builder
34+
build:
35+
context: .
36+
dockerfile: ./dockerfiles/Dockerfile
37+
target: build-server
38+
depends_on:
39+
- db
40+
- s3
41+
environment: *environment
42+
env_file:
43+
- .docker.env
44+
healthcheck:
45+
<< : *healthcheck-interval
46+
test: curl --silent --fail localhost:3000/about/metrics
47+
248
services:
349
web:
450
build:
551
context: .
652
dockerfile: ./dockerfiles/Dockerfile
53+
target: web-server
754
platform: "linux/amd64"
855
depends_on:
956
- db
1057
- s3
1158
ports:
12-
- "3000:3000"
13-
# for metrics
14-
expose: ["3000"]
59+
- "3000:80"
60+
environment: *environment
61+
env_file:
62+
- .docker.env
63+
healthcheck:
64+
<< : *healthcheck-interval
65+
test: curl --silent --fail localhost:80/about/metrics
66+
67+
# Include the registry watcher with `docker compose --profile watch up -d`
68+
registry-watcher:
69+
build:
70+
context: .
71+
dockerfile: ./dockerfiles/Dockerfile
72+
target: registry-watcher
73+
platform: "linux/amd64"
74+
depends_on:
75+
- db
1576
volumes:
16-
- "/var/run/docker.sock:/var/run/docker.sock"
17-
- ".rustwide-docker:/opt/docsrs/rustwide"
1877
- "cratesio-index:/opt/docsrs/prefix/crates.io-index"
19-
environment:
20-
DOCSRS_RUSTWIDE_WORKSPACE: /opt/docsrs/rustwide
21-
DOCSRS_DATABASE_URL: postgresql://cratesfyi:password@db
22-
DOCSRS_STORAGE_BACKEND: s3
23-
S3_ENDPOINT: http://s3:9000
24-
AWS_ACCESS_KEY_ID: cratesfyi
25-
AWS_SECRET_ACCESS_KEY: secret_key
78+
environment: *environment
2679
env_file:
27-
- .env
80+
- .docker.env
81+
profiles:
82+
- watch
83+
- all
2884
healthcheck:
29-
test: ["CMD", "curl", "--silent", "--fail", "localhost:3000"]
30-
interval: 10s
31-
timeout: 5s
32-
retries: 10
85+
<< : *healthcheck-interval
86+
test: curl --silent --fail localhost:3000/about/metrics
87+
88+
builder-a:
89+
<< : *builder
90+
volumes:
91+
- ".rustwide-docker/builder-a:/opt/docsrs/rustwide"
92+
- "/var/run/docker.sock:/var/run/docker.sock"
93+
94+
builder-b:
95+
<< : *builder
96+
volumes:
97+
- ".rustwide-docker/builder-b:/opt/docsrs/rustwide"
98+
- "/var/run/docker.sock:/var/run/docker.sock"
99+
100+
cli:
101+
build:
102+
context: .
103+
dockerfile: ./dockerfiles/Dockerfile
104+
target: cli
105+
depends_on:
106+
- db
107+
- s3
108+
volumes:
109+
- ".rustwide-docker/cli:/opt/docsrs/rustwide"
110+
- "cratesio-index:/opt/docsrs/prefix/crates.io-index"
111+
- "/var/run/docker.sock:/var/run/docker.sock"
112+
environment: *environment
113+
env_file:
114+
- .docker.env
115+
profiles:
116+
- all
33117

34118
db:
35119
build:
@@ -44,10 +128,8 @@ services:
44128
# Use a non-standard port on the host to avoid conflicting with existing postgres servers
45129
- "127.0.0.1:15432:5432"
46130
healthcheck:
47-
test: ["CMD", "pg_isready", "--username", "cratesfyi"]
48-
interval: 10s
49-
timeout: 5s
50-
retries: 10
131+
<< : *healthcheck-interval
132+
test: pg_isready --username cratesfyi
51133

52134
s3:
53135
image: minio/minio
@@ -65,17 +147,8 @@ services:
65147
MINIO_ROOT_USER: cratesfyi
66148
MINIO_ROOT_PASSWORD: secret_key
67149
healthcheck:
68-
test:
69-
[
70-
"CMD",
71-
"curl",
72-
"--silent",
73-
"--fail",
74-
"localhost:9000/minio/health/ready",
75-
]
76-
interval: 10s
77-
timeout: 5s
78-
retries: 10
150+
<< : *healthcheck-interval
151+
test: curl --silent --fail localhost:9000/minio/health/ready
79152

80153
prometheus:
81154
build:
@@ -84,11 +157,8 @@ services:
84157
ports:
85158
- "127.0.0.1:9090:9090"
86159
healthcheck:
87-
test:
88-
["CMD", "curl", "--silent", "--fail", "localhost:9090/-/ready"]
89-
interval: 10s
90-
timeout: 5s
91-
retries: 10
160+
<< : *healthcheck-interval
161+
test: promtool check healthy
92162

93163
volumes:
94164
postgres-data: {}

dockerfiles/Dockerfile

+63-24
Original file line numberDiff line numberDiff line change
@@ -65,42 +65,81 @@ RUN apt-get update \
6565
&& DEBIAN_FRONTEND=noninteractive apt-get upgrade -y \
6666
&& DEBIAN_FRONTEND=noninteractive apt-get install -y \
6767
ca-certificates \
68+
curl \
6869
tini \
6970
&& rm -rf /var/lib/apt/lists/*
7071

72+
WORKDIR /srv/docsrs
73+
74+
# Tini is a small init binary to properly handle signals
75+
CMD ["/usr/bin/tini", "/usr/local/bin/cratesfyi", "start-web-server", "0.0.0.0:80"]
76+
7177
COPY --from=build /build/target/release/cratesfyi /usr/local/bin
7278
COPY static /srv/docsrs/static
7379
COPY templates /srv/docsrs/templates
7480
COPY vendor /srv/docsrs/vendor
7581

76-
WORKDIR /srv/docsrs
82+
########################
83+
# Build server stage #
84+
########################
85+
86+
FROM ubuntu:22.04 AS build-server
87+
88+
RUN apt-get update \
89+
&& DEBIAN_FRONTEND=noninteractive apt-get upgrade -y \
90+
&& DEBIAN_FRONTEND=noninteractive apt-get install -y \
91+
ca-certificates \
92+
tini \
93+
curl \
94+
docker.io \
95+
build-essential \
96+
gcc \
97+
pkg-config \
98+
libssl-dev \
99+
&& rm -rf /var/lib/apt/lists/*
100+
77101
# Tini is a small init binary to properly handle signals
78-
CMD ["/usr/bin/tini", "/usr/local/bin/cratesfyi", "start-web-server", "0.0.0.0:80"]
102+
CMD ["/usr/bin/tini", "/usr/local/bin/cratesfyi", "start-build-server"]
103+
104+
COPY --from=build /build/target/release/cratesfyi /usr/local/bin
79105

80-
##################
81-
# Output stage #
82-
##################
106+
############################
107+
# Registry watcher stage #
108+
############################
83109

84-
FROM ubuntu:22.04 AS output
110+
FROM ubuntu:22.04 AS registry-watcher
85111

86-
RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y \
87-
git \
88-
libmagic1 \
89-
docker.io \
90-
ca-certificates \
91-
build-essential \
92-
gcc \
93-
pkg-config \
94-
libssl-dev
112+
RUN apt-get update \
113+
&& DEBIAN_FRONTEND=noninteractive apt-get upgrade -y \
114+
&& DEBIAN_FRONTEND=noninteractive apt-get install -y \
115+
ca-certificates \
116+
tini \
117+
curl \
118+
git \
119+
&& rm -rf /var/lib/apt/lists/*
120+
121+
# Tini is a small init binary to properly handle signals
122+
CMD ["/usr/bin/tini", "/usr/local/bin/cratesfyi", "start-registry-watcher", "--repository-stats-updater=enabled", "--cdn-invalidator=enabled"]
123+
124+
COPY --from=build /build/target/release/cratesfyi /usr/local/bin
125+
126+
###############
127+
# CLI stage #
128+
###############
129+
130+
FROM ubuntu:22.04 AS cli
131+
132+
RUN apt-get update \
133+
&& DEBIAN_FRONTEND=noninteractive apt-get upgrade -y \
134+
&& DEBIAN_FRONTEND=noninteractive apt-get install -y \
135+
ca-certificates \
136+
docker.io \
137+
build-essential \
138+
gcc \
139+
pkg-config \
140+
libssl-dev \
141+
&& rm -rf /var/lib/apt/lists/*
95142

96-
RUN mkdir -p /opt/docsrs/prefix
143+
ENTRYPOINT ["/usr/bin/tini", "/usr/local/bin/cratesfyi"]
97144

98145
COPY --from=build /build/target/release/cratesfyi /usr/local/bin
99-
COPY static /opt/docsrs/static
100-
COPY templates /opt/docsrs/templates
101-
COPY dockerfiles/entrypoint.sh /opt/docsrs/
102-
COPY vendor /opt/docsrs/vendor
103-
104-
WORKDIR /opt/docsrs
105-
ENTRYPOINT ["/opt/docsrs/entrypoint.sh"]
106-
CMD ["daemon", "--registry-watcher=disabled"]

0 commit comments

Comments
 (0)