From 93f3cf2fbdec4b8273e8bbba20f7eee62cdadf18 Mon Sep 17 00:00:00 2001 From: Pietro Albini Date: Tue, 29 Oct 2019 12:45:13 +0100 Subject: [PATCH 01/15] add an ignored directory to store non-docker data dirs If someone also builds docs.rs outside of Docker they need to have a place to store the prefix and the rustwide workspace. This commit adds a directory named ignored to both the gitignore and the dockerignore. --- .dockerignore | 1 + .gitignore | 1 + 2 files changed, 2 insertions(+) diff --git a/.dockerignore b/.dockerignore index ea4a0ace1..4c9a2b70c 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,2 +1,3 @@ /.rustwide +/ignored **/target diff --git a/.gitignore b/.gitignore index e5e7c1e51..fff7dfe93 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ +/ignored target *.css *.css.map From a94a6ee84eca34713283b78f8a325a29b8352df9 Mon Sep 17 00:00:00 2001 From: Pietro Albini Date: Tue, 29 Oct 2019 12:49:51 +0100 Subject: [PATCH 02/15] docker: don't store data in the cratesfyi home directory --- Dockerfile | 10 ++++++---- docker-entrypoint.sh | 2 +- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/Dockerfile b/Dockerfile index ab213ebe8..267e014c8 100644 --- a/Dockerfile +++ b/Dockerfile @@ -11,8 +11,8 @@ ENV HOME=/home/cratesfyi RUN adduser --home $HOME --disabled-login --disabled-password --gecos "" cratesfyi ### STEP 3: Setup build environment as new user ### -ENV CRATESFYI_PREFIX=/home/cratesfyi/prefix -RUN mkdir $CRATESFYI_PREFIX && chown cratesfyi:cratesfyi "$CRATESFYI_PREFIX" +ENV CRATESFYI_PREFIX=/opt/docsrs/prefix +RUN mkdir -p $CRATESFYI_PREFIX && chown cratesfyi:cratesfyi "$CRATESFYI_PREFIX" USER cratesfyi RUN mkdir -vp "$CRATESFYI_PREFIX"/documentations "$CRATESFYI_PREFIX"/public_html "$CRATESFYI_PREFIX"/sources @@ -24,8 +24,10 @@ RUN git --git-dir="$CRATESFYI_PREFIX"/crates.io-index/.git branch crates-index-d # every time the source code changes. This takes advantage of Docker's layer # caching, and it works by copying the Cargo.{toml,lock} with dummy source code # and doing a full build with it. -RUN mkdir -p ~/docs.rs ~/docs.rs/src/web/badge -WORKDIR $HOME/docs.rs +USER root +RUN mkdir -p /build/docs.rs /build/src/web/badge && chown -R cratesfyi:cratesfyi /build +USER cratesfyi +WORKDIR /build COPY --chown=cratesfyi Cargo.lock Cargo.toml ./ COPY --chown=cratesfyi src/web/badge src/web/badge/ RUN echo "fn main() {}" > src/main.rs && \ diff --git a/docker-entrypoint.sh b/docker-entrypoint.sh index 5c284da0a..266f0b17f 100755 --- a/docker-entrypoint.sh +++ b/docker-entrypoint.sh @@ -10,7 +10,7 @@ export CRATESFYI_CONTAINER_NAME=cratesfyi-container export CRATESFYI_GITHUB_USERNAME= export CRATESFYI_GITHUB_ACCESSTOKEN= export RUST_LOG=cratesfyi,rustwide=info -export PATH="$PATH:$HOME/docs.rs/target/release" +export PATH="$PATH:/build/target/release" sudo -E -u $USER $BIN database migrate sudo -E -u $USER $BIN database update-search-index From 28c594c14d05353b1a014f789a48a214bbe4ddb5 Mon Sep 17 00:00:00 2001 From: Pietro Albini Date: Tue, 29 Oct 2019 12:59:19 +0100 Subject: [PATCH 03/15] docker: remove the cratesfyi user The user is not actually used to run the application (is run as root), but only during parts of the build process. It's not really needed, so this removes it. --- Dockerfile | 28 ++++++++++------------------ docker-entrypoint.sh | 11 ++++------- 2 files changed, 14 insertions(+), 25 deletions(-) diff --git a/Dockerfile b/Dockerfile index 267e014c8..fe310eb38 100644 --- a/Dockerfile +++ b/Dockerfile @@ -6,47 +6,40 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ build-essential git curl cmake gcc g++ pkg-config libmagic-dev \ libssl-dev zlib1g-dev sudo docker.io -### STEP 2: Create user ### -ENV HOME=/home/cratesfyi -RUN adduser --home $HOME --disabled-login --disabled-password --gecos "" cratesfyi - -### STEP 3: Setup build environment as new user ### +### STEP 2: Setup build environment as new user ### ENV CRATESFYI_PREFIX=/opt/docsrs/prefix -RUN mkdir -p $CRATESFYI_PREFIX && chown cratesfyi:cratesfyi "$CRATESFYI_PREFIX" +RUN mkdir -p $CRATESFYI_PREFIX -USER cratesfyi RUN mkdir -vp "$CRATESFYI_PREFIX"/documentations "$CRATESFYI_PREFIX"/public_html "$CRATESFYI_PREFIX"/sources RUN git clone https://github.com/rust-lang/crates.io-index.git "$CRATESFYI_PREFIX"/crates.io-index RUN git --git-dir="$CRATESFYI_PREFIX"/crates.io-index/.git branch crates-index-diff_last-seen -### STEP 4: Build the project ### +### STEP 3: Build the project ### # Build the dependencies in a separate step to avoid rebuilding all of them # every time the source code changes. This takes advantage of Docker's layer # caching, and it works by copying the Cargo.{toml,lock} with dummy source code # and doing a full build with it. -USER root -RUN mkdir -p /build/docs.rs /build/src/web/badge && chown -R cratesfyi:cratesfyi /build -USER cratesfyi +RUN mkdir -p /build/docs.rs /build/src/web/badge WORKDIR /build -COPY --chown=cratesfyi Cargo.lock Cargo.toml ./ -COPY --chown=cratesfyi src/web/badge src/web/badge/ +COPY Cargo.lock Cargo.toml ./ +COPY src/web/badge src/web/badge/ RUN echo "fn main() {}" > src/main.rs && \ echo "fn main() {}" > build.rs RUN cargo fetch RUN cargo build --release -### STEP 5: Build the website ### +### STEP 4: Build the website ### # Dependencies are now cached, copy the actual source code and do another full # build. The touch on all the .rs files is needed, otherwise cargo assumes the # source code didn't change thanks to mtime weirdness. RUN rm -rf src build.rs -COPY --chown=cratesfyi build.rs build.rs +COPY build.rs build.rs RUN touch build.rs -COPY --chown=cratesfyi src src/ +COPY src src/ RUN find src -name "*.rs" -exec touch {} \; -COPY --chown=cratesfyi templates/style.scss templates/ +COPY templates/style.scss templates/ RUN cargo build --release @@ -55,6 +48,5 @@ ADD css $CRATESFYI_PREFIX/public_html ENV DOCS_RS_DOCKER=true COPY docker-entrypoint.sh ./ -USER root ENTRYPOINT ["./docker-entrypoint.sh"] CMD ["daemon", "--foreground"] diff --git a/docker-entrypoint.sh b/docker-entrypoint.sh index 266f0b17f..980b82c0c 100755 --- a/docker-entrypoint.sh +++ b/docker-entrypoint.sh @@ -2,9 +2,6 @@ set -euv -USER=cratesfyi -BIN=target/release/cratesfyi - export CRATESFYI_DATABASE_URL=postgresql://cratesfyi:password@db export CRATESFYI_CONTAINER_NAME=cratesfyi-container export CRATESFYI_GITHUB_USERNAME= @@ -12,8 +9,8 @@ export CRATESFYI_GITHUB_ACCESSTOKEN= export RUST_LOG=cratesfyi,rustwide=info export PATH="$PATH:/build/target/release" -sudo -E -u $USER $BIN database migrate -sudo -E -u $USER $BIN database update-search-index -sudo -E -u $USER $BIN database update-release-activity +cratesfyi database migrate +cratesfyi database update-search-index +cratesfyi database update-release-activity -$BIN "$@" +cratesfyi "$@" From e20572a8bed0297093db7db2f964e91b6a1d5f7b Mon Sep 17 00:00:00 2001 From: Pietro Albini Date: Tue, 29 Oct 2019 13:09:17 +0100 Subject: [PATCH 04/15] docker: move environment variables around - The CRATESFYI_CONTAINER_NAME variable was removed as it's not needed anymore. - The CRATESFYI_DATABASE_URL variable was moved to docker-compose.yml as it's only correct when starting the website with it. - The CRATESFYI_GITHUB_USERNAME and CRATESFYI_GITHUB_ACCESSTOKEN variables were moved to a new, gitignored .env file in the root of the repository, to allow people changing them without accidentally committing them. - The DOCS_RS_DOCKER variable was moved to the entrypoint just to remove yet another useless layer from the image. --- .env.sample | 2 ++ .gitignore | 1 + Dockerfile | 1 - README.md | 1 + docker-compose.yml | 3 +++ docker-entrypoint.sh | 5 +---- 6 files changed, 8 insertions(+), 5 deletions(-) create mode 100644 .env.sample diff --git a/.env.sample b/.env.sample new file mode 100644 index 000000000..383a7db4b --- /dev/null +++ b/.env.sample @@ -0,0 +1,2 @@ +CRATESFYI_GITHUB_USERNAME= +CRATESFYI_GITHUB_ACCESSTOKEN= diff --git a/.gitignore b/.gitignore index fff7dfe93..9724e40b8 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ /ignored +/.env target *.css *.css.map diff --git a/Dockerfile b/Dockerfile index fe310eb38..7a64bda5c 100644 --- a/Dockerfile +++ b/Dockerfile @@ -46,7 +46,6 @@ RUN cargo build --release ADD templates templates/ ADD css $CRATESFYI_PREFIX/public_html -ENV DOCS_RS_DOCKER=true COPY docker-entrypoint.sh ./ ENTRYPOINT ["./docker-entrypoint.sh"] CMD ["daemon", "--foreground"] diff --git a/README.md b/README.md index e5c2407bc..7d77e0ebe 100644 --- a/README.md +++ b/README.md @@ -60,6 +60,7 @@ Make sure you have docker-compose and are able to download ~10GB data on the fir ```sh git clone https://github.com/rust-lang/docs.rs.git docs.rs cd docs.rs +cp .env.sample .env docker-compose up # This may take a half hour or more on the first run ``` diff --git a/docker-compose.yml b/docker-compose.yml index cbf447534..5ab4f6831 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -11,6 +11,9 @@ services: - ".rustwide:/home/cratesfyi/rustwide" environment: CRATESFYI_RUSTWIDE_WORKSPACE: /home/cratesfyi/rustwide + CRATESFYI_DATABASE_URL: postgresql://cratesfyi:password@db + env_file: + - .env db: image: postgres:alpine volumes: diff --git a/docker-entrypoint.sh b/docker-entrypoint.sh index 980b82c0c..3a474bb44 100755 --- a/docker-entrypoint.sh +++ b/docker-entrypoint.sh @@ -2,10 +2,7 @@ set -euv -export CRATESFYI_DATABASE_URL=postgresql://cratesfyi:password@db -export CRATESFYI_CONTAINER_NAME=cratesfyi-container -export CRATESFYI_GITHUB_USERNAME= -export CRATESFYI_GITHUB_ACCESSTOKEN= +export DOCS_RS_DOCKER=true export RUST_LOG=cratesfyi,rustwide=info export PATH="$PATH:/build/target/release" From d89338b9cb778b6f060e9400173ee8864ec12c6a Mon Sep 17 00:00:00 2001 From: Pietro Albini Date: Tue, 29 Oct 2019 13:24:57 +0100 Subject: [PATCH 05/15] docker: remove most of the prefix initialization --- Dockerfile | 9 ++------- docker-entrypoint.sh | 1 + 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/Dockerfile b/Dockerfile index 7a64bda5c..2170b9e90 100644 --- a/Dockerfile +++ b/Dockerfile @@ -7,12 +7,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ libssl-dev zlib1g-dev sudo docker.io ### STEP 2: Setup build environment as new user ### -ENV CRATESFYI_PREFIX=/opt/docsrs/prefix -RUN mkdir -p $CRATESFYI_PREFIX - -RUN mkdir -vp "$CRATESFYI_PREFIX"/documentations "$CRATESFYI_PREFIX"/public_html "$CRATESFYI_PREFIX"/sources -RUN git clone https://github.com/rust-lang/crates.io-index.git "$CRATESFYI_PREFIX"/crates.io-index -RUN git --git-dir="$CRATESFYI_PREFIX"/crates.io-index/.git branch crates-index-diff_last-seen +RUN mkdir -p /opt/docsrs/prefix ### STEP 3: Build the project ### # Build the dependencies in a separate step to avoid rebuilding all of them @@ -44,7 +39,7 @@ COPY templates/style.scss templates/ RUN cargo build --release ADD templates templates/ -ADD css $CRATESFYI_PREFIX/public_html +COPY css /opt/docsrs/prefix/public_html COPY docker-entrypoint.sh ./ ENTRYPOINT ["./docker-entrypoint.sh"] diff --git a/docker-entrypoint.sh b/docker-entrypoint.sh index 3a474bb44..59245590b 100755 --- a/docker-entrypoint.sh +++ b/docker-entrypoint.sh @@ -2,6 +2,7 @@ set -euv +export CRATESFYI_PREFIX=/opt/docsrs/prefix export DOCS_RS_DOCKER=true export RUST_LOG=cratesfyi,rustwide=info export PATH="$PATH:/build/target/release" From 2cd9a9db17bf7c1e6389866f775f7478040a8eba Mon Sep 17 00:00:00 2001 From: Pietro Albini Date: Tue, 29 Oct 2019 13:43:21 +0100 Subject: [PATCH 06/15] docker: clone the index at startup This prevents a stale index from being backed into the image. --- docker-compose.yml | 4 +++- docker-entrypoint.sh | 4 ++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/docker-compose.yml b/docker-compose.yml index 5ab4f6831..e9562b5ab 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -9,6 +9,7 @@ services: volumes: - "/var/run/docker.sock:/var/run/docker.sock" - ".rustwide:/home/cratesfyi/rustwide" + - "cratesio-index:/opt/docsrs/prefix/crates.io-index" environment: CRATESFYI_RUSTWIDE_WORKSPACE: /home/cratesfyi/rustwide CRATESFYI_DATABASE_URL: postgresql://cratesfyi:password@db @@ -22,4 +23,5 @@ services: POSTGRES_USER: cratesfyi POSTGRES_PASSWORD: password volumes: - postgres-data: + postgres-data: {} + cratesio-index: {} diff --git a/docker-entrypoint.sh b/docker-entrypoint.sh index 59245590b..7c4d29b4d 100755 --- a/docker-entrypoint.sh +++ b/docker-entrypoint.sh @@ -11,4 +11,8 @@ cratesfyi database migrate cratesfyi database update-search-index cratesfyi database update-release-activity +if ! [ -d "${CRATESFYI_PREFIX}/crates.io-index/.git" ]; then + git clone https://github.com/rust-lang/crates.io-index "${CRATESFYI_PREFIX}/crates.io-index" +fi + cratesfyi "$@" From 7e416f7b7ad42122eab65d83fb7f60378c4e4d3f Mon Sep 17 00:00:00 2001 From: Pietro Albini Date: Tue, 29 Oct 2019 15:38:02 +0100 Subject: [PATCH 07/15] docker: switch image to ubuntu bionic --- Dockerfile | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index 2170b9e90..d36a4ca28 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,10 +1,16 @@ -FROM rust:slim +FROM ubuntu:bionic ### STEP 1: Install dependencies ### # Install packaged dependencies RUN apt-get update && apt-get install -y --no-install-recommends \ build-essential git curl cmake gcc g++ pkg-config libmagic-dev \ - libssl-dev zlib1g-dev sudo docker.io + libssl-dev zlib1g-dev sudo ca-certificates docker.io + +# Install the stable toolchain with rustup +RUN curl https://static.rust-lang.org/rustup/dist/x86_64-unknown-linux-gnu/rustup-init >/tmp/rustup-init && \ + chmod +x /tmp/rustup-init && \ + /tmp/rustup-init -y --no-modify-path --default-toolchain stable +ENV PATH=/root/.cargo/bin:$PATH ### STEP 2: Setup build environment as new user ### RUN mkdir -p /opt/docsrs/prefix From 8f5bb7596af36ea14ad544b8d6bf4f7a63781623 Mon Sep 17 00:00:00 2001 From: Pietro Albini Date: Tue, 29 Oct 2019 16:44:01 +0100 Subject: [PATCH 08/15] docker: use multi-stage builds to shrink the image size Using multi-stage builds got us from 2.8GB to 500MB, which is a great space saving. --- Dockerfile | 45 +++++++++++++++++++++++++++++++++------------ 1 file changed, 33 insertions(+), 12 deletions(-) diff --git a/Dockerfile b/Dockerfile index d36a4ca28..39798ad87 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,21 +1,27 @@ -FROM ubuntu:bionic +# To produce a smaller image this Dockerfile contains two separate stages: in +# the first one all the build dependencies are installed and docs.rs is built, +# while in the second one just the runtime dependencies are installed, with the +# binary built in the previous stage copied there. +# +# As of 2019-10-29 this reduces the image from 2.8GB to 500 MB. + +################# +# Build stage # +################# + +FROM ubuntu:bionic AS build -### STEP 1: Install dependencies ### # Install packaged dependencies -RUN apt-get update && apt-get install -y --no-install-recommends \ +RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \ build-essential git curl cmake gcc g++ pkg-config libmagic-dev \ libssl-dev zlib1g-dev sudo ca-certificates docker.io # Install the stable toolchain with rustup RUN curl https://static.rust-lang.org/rustup/dist/x86_64-unknown-linux-gnu/rustup-init >/tmp/rustup-init && \ chmod +x /tmp/rustup-init && \ - /tmp/rustup-init -y --no-modify-path --default-toolchain stable + /tmp/rustup-init -y --no-modify-path --default-toolchain stable --profile minimal ENV PATH=/root/.cargo/bin:$PATH -### STEP 2: Setup build environment as new user ### -RUN mkdir -p /opt/docsrs/prefix - -### STEP 3: Build the project ### # Build the dependencies in a separate step to avoid rebuilding all of them # every time the source code changes. This takes advantage of Docker's layer # caching, and it works by copying the Cargo.{toml,lock} with dummy source code @@ -30,7 +36,6 @@ RUN echo "fn main() {}" > src/main.rs && \ RUN cargo fetch RUN cargo build --release -### STEP 4: Build the website ### # Dependencies are now cached, copy the actual source code and do another full # build. The touch on all the .rs files is needed, otherwise cargo assumes the # source code didn't change thanks to mtime weirdness. @@ -44,9 +49,25 @@ COPY templates/style.scss templates/ RUN cargo build --release -ADD templates templates/ +################## +# Output stage # +################## + +FROM ubuntu:bionic AS output + +RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y \ + git \ + libmagic1 \ + docker.io \ + ca-certificates + +RUN mkdir -p /opt/docsrs/prefix + +COPY --from=build /build/target/release/cratesfyi /usr/local/bin COPY css /opt/docsrs/prefix/public_html +COPY templates /opt/docsrs/templates +COPY docker-entrypoint.sh /opt/docsrs/entrypoint.sh -COPY docker-entrypoint.sh ./ -ENTRYPOINT ["./docker-entrypoint.sh"] +WORKDIR /opt/docsrs +ENTRYPOINT ["/opt/docsrs/entrypoint.sh"] CMD ["daemon", "--foreground"] From d206d99c8ca6166b708a787e1ae389cb87bff584 Mon Sep 17 00:00:00 2001 From: Pietro Albini Date: Tue, 29 Oct 2019 16:48:24 +0100 Subject: [PATCH 09/15] docker: ensure the git commit hash is detected inside docker --- Dockerfile | 1 + 1 file changed, 1 insertion(+) diff --git a/Dockerfile b/Dockerfile index 39798ad87..937a4ad99 100644 --- a/Dockerfile +++ b/Dockerfile @@ -41,6 +41,7 @@ RUN cargo build --release # source code didn't change thanks to mtime weirdness. RUN rm -rf src build.rs +COPY .git .git COPY build.rs build.rs RUN touch build.rs COPY src src/ From bcd8c0cea6390c9eb31a6049068d52cd47674da3 Mon Sep 17 00:00:00 2001 From: Pietro Albini Date: Tue, 29 Oct 2019 17:09:25 +0100 Subject: [PATCH 10/15] docker: include other essential files --- ...main-20160526-1.10.0-nightly-97e3a2401.css | 128 ++++ ...tdoc-20160526-1.10.0-nightly-97e3a2401.css | 717 ++++++++++++++++++ 2 files changed, 845 insertions(+) create mode 100644 css/main-20160526-1.10.0-nightly-97e3a2401.css create mode 100644 css/rustdoc-20160526-1.10.0-nightly-97e3a2401.css diff --git a/css/main-20160526-1.10.0-nightly-97e3a2401.css b/css/main-20160526-1.10.0-nightly-97e3a2401.css new file mode 100644 index 000000000..59b2ff7e3 --- /dev/null +++ b/css/main-20160526-1.10.0-nightly-97e3a2401.css @@ -0,0 +1,128 @@ +/** + * Copyright 2015 The Rust Project Developers. See the COPYRIGHT + * file at the top-level directory of this distribution and at + * http://rust-lang.org/COPYRIGHT. + * + * Licensed under the Apache License, Version 2.0 or the MIT license + * , at your + * option. This file may not be copied, modified, or distributed + * except according to those terms. + */ + +/* General structure and fonts */ + +body { + background-color: white; + color: black; +} + +h1, h2, h3:not(.impl):not(.method):not(.type):not(.tymethod), h4:not(.method):not(.type):not(.tymethod) { + color: black; +} +h1.fqn { + border-bottom-color: #D5D5D5; +} +h2, h3:not(.impl):not(.method):not(.type):not(.tymethod), h4:not(.method):not(.type):not(.tymethod) { + border-bottom-color: #DDDDDD; +} +.in-band, code { + background-color: white; +} + +.docblock code { + background-color: #F5F5F5; +} +pre { + background-color: #F5F5F5; +} + +.sidebar .location { + background: #e1e1e1; + color: #333; +} + +.block a:hover { + background: #F5F5F5; +} + +.line-numbers span { color: #c67e2d; } +.line-numbers .line-highlighted { + background-color: #f6fdb0 !important; +} + +:target { background: #FDFFD3; } +.content .highlighted { + color: #000 !important; + background-color: #ccc; +} +.content .highlighted a, .content .highlighted span { color: #000 !important; } +.content .highlighted.trait { background-color: #fece7e; } +.content .highlighted.mod { background-color: #afc6e4; } +.content .highlighted.enum { background-color: #b4d1b9; } +.content .highlighted.struct { background-color: #e7b1a0; } +.content .highlighted.fn { background-color: #c6afb3; } +.content .highlighted.method { background-color: #c6afb3; } +.content .highlighted.tymethod { background-color: #c6afb3; } +.content .highlighted.type { background-color: #c6afb3; } + +.docblock h1, .docblock h2, .docblock h3, .docblock h4, .docblock h5 { + border-bottom-color: #DDD; +} + +.docblock table { + border-color: #ddd; +} + +.docblock table td { + border-top-color: #ddd; + border-bottom-color: #ddd; +} + +.docblock table th { + border-top-color: #ddd; + border-bottom-color: #ddd; +} + +.content a.primitive { color: #39a7bf; } +.content span.externcrate, span.mod, .content a.mod, block a.current.mod { color: #4d76ae; } +.content span.fn, .content a.fn, .block a.current.fn, +.content span.method, .content a.method, .block a.current.method, +.content span.tymethod, .content a.tymethod, .block a.current.tymethod, +.content .fnname { color: #8c6067; } + +pre.rust .comment { color: #8E908C; } +pre.rust .doccomment { color: #4D4D4C; } + +nav { + border-bottom-color: #e0e0e0; +} +nav.main .current { + border-top-color: #000; + border-bottom-color: #000; +} +nav.main .separator { + border-color: 1px solid #000; +} +a { + color: #000; +} + +.docblock a, .stability a { + color: #3873AD; +} + +a.test-arrow { + color: #f5f5f5; +} + +.content span.trait, .content a.trait, .block a.current.trait { color: #7c5af3; } + +.search-input { + color: #555; + box-shadow: 0 0 0 1px #e0e0e0, 0 0 0 2px transparent; + background-color: white; +} + +em.stab.unstable { background: #FFF5D6; border-color: #FFC600; } +em.stab.deprecated { background: #F3DFFF; border-color: #7F0087; } diff --git a/css/rustdoc-20160526-1.10.0-nightly-97e3a2401.css b/css/rustdoc-20160526-1.10.0-nightly-97e3a2401.css new file mode 100644 index 000000000..8e4245d4e --- /dev/null +++ b/css/rustdoc-20160526-1.10.0-nightly-97e3a2401.css @@ -0,0 +1,717 @@ +/** + * Copyright 2013 The Rust Project Developers. See the COPYRIGHT + * file at the top-level directory of this distribution and at + * http://rust-lang.org/COPYRIGHT. + * + * Licensed under the Apache License, Version 2.0 or the MIT license + * , at your + * option. This file may not be copied, modified, or distributed + * except according to those terms. + */ + +/* See FiraSans-LICENSE.txt for the Fira Sans license. */ +@font-face { + font-family: 'Fira Sans'; + font-style: normal; + font-weight: 400; + src: local('Fira Sans'), url("FiraSans-Regular.woff") format('woff'); +} +@font-face { + font-family: 'Fira Sans'; + font-style: normal; + font-weight: 500; + src: local('Fira Sans Medium'), url("FiraSans-Medium.woff") format('woff'); +} + +/* See SourceSerifPro-LICENSE.txt for the Source Serif Pro license and + * Heuristica-LICENSE.txt for the Heuristica license. */ +@font-face { + font-family: 'Source Serif Pro'; + font-style: normal; + font-weight: 400; + src: local('Source Serif Pro'), url("SourceSerifPro-Regular.woff") format('woff'); +} +@font-face { + font-family: 'Source Serif Pro'; + font-style: italic; + font-weight: 400; + src: url("Heuristica-Italic.woff") format('woff'); +} +@font-face { + font-family: 'Source Serif Pro'; + font-style: normal; + font-weight: 700; + src: local('Source Serif Pro Bold'), url("SourceSerifPro-Bold.woff") format('woff'); +} + +/* See SourceCodePro-LICENSE.txt for the Source Code Pro license. */ +@font-face { + font-family: 'Source Code Pro'; + font-style: normal; + font-weight: 400; + src: local('Source Code Pro'), url("SourceCodePro-Regular.woff") format('woff'); +} +@font-face { + font-family: 'Source Code Pro'; + font-style: normal; + font-weight: 600; + src: local('Source Code Pro Semibold'), url("SourceCodePro-Semibold.woff") format('woff'); +} + +@import "normalize.css"; + +* { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} + +/* General structure and fonts */ + +body { + font: 16px/1.4 "Source Serif Pro", Georgia, Times, "Times New Roman", serif; + margin: 0; + position: relative; + padding: 10px 15px 20px 15px; + + -webkit-font-feature-settings: "kern", "liga"; + -moz-font-feature-settings: "kern", "liga"; + font-feature-settings: "kern", "liga"; +} + +h1 { + font-size: 1.5em; +} +h2 { + font-size: 1.4em; +} +h3 { + font-size: 1.3em; +} +h1, h2, h3:not(.impl):not(.method):not(.type):not(.tymethod), h4:not(.method):not(.type):not(.tymethod) { + font-weight: 500; + margin: 20px 0 15px 0; + padding-bottom: 6px; +} +h1.fqn { + border-bottom: 1px dashed; + margin-top: 0; + position: relative; +} +h2, h3:not(.impl):not(.method):not(.type):not(.tymethod), h4:not(.method):not(.type):not(.tymethod) { + border-bottom: 1px solid; +} +h3.impl, h3.method, h4.method, h3.type, h4.type { + font-weight: 600; + margin-top: 10px; + margin-bottom: 10px; + position: relative; +} +h3.impl, h3.method, h3.type { + margin-top: 15px; +} +h1, h2, h3, h4, .sidebar, a.source, .search-input, .content table :not(code)>a, .collapse-toggle { + font-family: "Fira Sans", "Helvetica Neue", Helvetica, Arial, sans-serif; +} + +ol, ul { + padding-left: 25px; +} +ul ul, ol ul, ul ol, ol ol { + margin-bottom: 0; +} + +p { + margin: 0 0 .6em 0; +} + +code, pre { + font-family: "Source Code Pro", Menlo, Monaco, Consolas, "DejaVu Sans Mono", Inconsolata, monospace; + white-space: pre-wrap; +} +.docblock code { + border-radius: 3px; + padding: 0 0.2em; +} +.docblock pre code { + padding: 0; +} +pre { + padding: 14px; +} + +.source pre { + padding: 20px; +} + +img { + max-width: 100%; +} + +.content.source { + margin-top: 50px; + max-width: none; + overflow: visible; + margin-left: 0px; + min-width: 70em; +} + +nav.sub { + font-size: 16px; + text-transform: uppercase; +} + +.sidebar { + width: 200px; + position: absolute; + left: 0; + top: 0; + min-height: 100%; +} + +.content, nav { max-width: 960px; } + +/* Everything else */ + +.js-only, .hidden { display: none !important; } + +.sidebar { + padding: 10px; +} +.sidebar img { + margin: 20px auto; + display: block; +} + +.sidebar .location { + font-size: 17px; + margin: 30px 0 20px 0; + text-align: center; +} + +.location a:first-child { font-weight: 500; } + +.block { + padding: 0 10px; + margin-bottom: 14px; +} +.block h2, .block h3 { + margin-top: 0; + margin-bottom: 8px; + text-align: center; +} +.block ul, .block li { + margin: 0; + padding: 0; + list-style: none; +} + +.block a { + display: block; + text-overflow: ellipsis; + overflow: hidden; + line-height: 15px; + padding: 7px 5px; + font-size: 14px; + font-weight: 300; + transition: border 500ms ease-out; +} + +.content { + padding: 15px 0; +} + +.content.source pre.rust { + white-space: pre; + overflow: auto; + padding-left: 0; +} +.content pre.line-numbers { + float: left; + border: none; + position: relative; + + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} +.line-numbers span { cursor: pointer; } + +.docblock.short p { + display: inline; +} + +.docblock.short.nowrap { + display: block; + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; +} + +.docblock.short p { + overflow: hidden; + text-overflow: ellipsis; + margin: 0; +} +.docblock.short code { white-space: nowrap; } + +.docblock h1, .docblock h2, .docblock h3, .docblock h4, .docblock h5 { + border-bottom: 1px solid; +} + +.docblock h1 { font-size: 1.3em; } +.docblock h2 { font-size: 1.15em; } +.docblock h3, .docblock h4, .docblock h5 { font-size: 1em; } + +.content .out-of-band { + font-size: 23px; + margin: 0px; + padding: 0px; + text-align: right; + display: inline-block; + font-weight: normal; + position: absolute; + right: 0; +} + +h3.impl > .out-of-band { + font-size: 21px; +} + +h4 > code, h3 > code { + position: inherit; +} + +.in-band, code { + z-index: 5; +} + +.content .in-band { + margin: 0px; + padding: 0px; + display: inline-block; +} + +#main { position: relative; } +#main > .since { + top: inherit; + font-family: "Fira Sans", "Helvetica Neue", Helvetica, Arial, sans-serif; +} + +.content table { + border-spacing: 0 5px; + border-collapse: separate; +} +.content td { vertical-align: top; } +.content td:first-child { padding-right: 20px; } +.content td p:first-child { margin-top: 0; } +.content td h1, .content td h2 { margin-left: 0; font-size: 1.1em; } + +.docblock table { + border: 1px solid; + margin: .5em 0; + border-collapse: collapse; + width: 100%; +} + +.docblock table td { + padding: .5em; + border-top: 1px dashed; + border-bottom: 1px dashed; +} + +.docblock table th { + padding: .5em; + text-align: left; + border-top: 1px solid; + border-bottom: 1px solid; +} + +.content .item-list { + list-style-type: none; + padding: 0; +} + +.content .item-list li { margin-bottom: 3px; } + +.content .multi-column { + -moz-column-count: 5; + -moz-column-gap: 2.5em; + -webkit-column-count: 5; + -webkit-column-gap: 2.5em; + column-count: 5; + column-gap: 2.5em; +} +.content .multi-column li { width: 100%; display: inline-block; } + +.content .method { + font-size: 1em; + position: relative; +} +/* Shift "where ..." part of method or fn definition down a line */ +.content .method .where, .content .fn .where { display: block; } +/* Bit of whitespace to indent it */ +.content .method .where::before, .content .fn .where::before { content: ' '; } + +.content .methods > div { margin-left: 40px; } + +.content .impl-items .docblock, .content .impl-items .stability { + margin-left: 40px; +} +.content .impl-items .method, .content .impl-items > .type { + margin-left: 20px; +} + +.content .stability code { + font-size: 90%; +} + +nav { + border-bottom: 1px solid; + padding-bottom: 10px; + margin-bottom: 10px; +} +nav.main { + padding: 20px 0; + text-align: center; +} +nav.main .current { + border-top: 1px solid; + border-bottom: 1px solid; +} +nav.main .separator { + border: 1px solid; + display: inline-block; + height: 23px; + margin: 0 20px; +} +nav.sum { text-align: right; } +nav.sub form { display: inline; } + +nav.sub, .content { + margin-left: 230px; +} + +a { + text-decoration: none; + background: transparent; +} + +.docblock a:hover, .stability a { + text-decoration: underline; +} + +.content span.enum, .content a.enum, .block a.current.enum { color: #5e9766; } +.content span.struct, .content a.struct, .block a.current.struct { color: #df3600; } +.content a.type { color: #e57300; } +.content a.macro { color: #068000; } +.block a.current.crate { font-weight: 500; } + +.search-input { + width: 100%; + /* Override Normalize.css: we have margins and do + not want to overflow - the `moz` attribute is necessary + until Firefox 29, too early to drop at this point */ + -moz-box-sizing: border-box !important; + box-sizing: border-box !important; + outline: none; + border: none; + border-radius: 1px; + margin-top: 5px; + padding: 10px 16px; + font-size: 17px; + transition: border-color 300ms ease; + transition: border-radius 300ms ease-in-out; + transition: box-shadow 300ms ease-in-out; +} + +.search-input:focus { + border-color: #66afe9; + border-radius: 2px; + border: 0; + outline: 0; + box-shadow: 0 0 8px #078dd8; +} + +.search-results .desc { + white-space: nowrap; + text-overflow: ellipsis; + overflow: hidden; + display: block; +} + +.search-results a { + display: block; +} + +.content .search-results td:first-child { padding-right: 0; } +.content .search-results td:first-child a { padding-right: 10px; } + +tr.result span.primitive::after { content: ' (primitive type)'; font-style: italic; } + +body.blur > :not(#help) { + filter: blur(8px); + -webkit-filter: blur(8px); + opacity: .7; +} + +#help { + width: 100%; + height: 100vh; + position: fixed; + top: 0; + left: 0; + display: flex; + justify-content: center; + align-items: center; +} +#help > div { + flex: 0 0 auto; + background: #e9e9e9; + box-shadow: 0 0 6px rgba(0,0,0,.2); + width: 550px; + height: 330px; + border: 1px solid #bfbfbf; +} +#help dt { + float: left; + border-radius: 4px; + border: 1px solid #bfbfbf; + background: #fff; + width: 23px; + text-align: center; + clear: left; + display: block; + margin-top: -1px; +} +#help dd { margin: 5px 33px; } +#help .infos { padding-left: 0; } +#help h1, #help h2 { margin-top: 0; } +#help > div div { + width: 50%; + float: left; + padding: 20px; +} + +em.stab { + display: inline-block; + border-width: 1px; + border-style: solid; + padding: 3px; + margin-bottom: 5px; + font-size: 90%; + font-style: normal; +} +em.stab p { + display: inline; +} + +.module-item .stab { + border-width: 0; + padding: 0; + margin: 0; + background: inherit !important; +} + +.module-item.unstable { + opacity: 0.65; +} + +.since { + font-weight: normal; + font-size: initial; + color: grey; + position: absolute; + right: 0; + top: 0; +} + +.variants_table { + width: 100%; +} + +.variants_table tbody tr td:first-child { + width: 1%; /* make the variant name as small as possible */ +} + +td.summary-column { + width: 100%; +} + +.summary { + padding-right: 0px; +} + +.line-numbers :target { background-color: transparent; } + +/* Code highlighting */ +pre.rust .kw { color: #8959A8; } +pre.rust .kw-2, pre.rust .prelude-ty { color: #4271AE; } +pre.rust .number, pre.rust .string { color: #718C00; } +pre.rust .self, pre.rust .boolval, pre.rust .prelude-val, +pre.rust .attribute, pre.rust .attribute .ident { color: #C82829; } +pre.rust .macro, pre.rust .macro-nonterminal { color: #3E999F; } +pre.rust .lifetime { color: #B76514; } + +.rusttest { display: none; } +pre.rust { position: relative; } +a.test-arrow { + display: inline-block; + position: absolute; + background-color: #4e8bca; + padding: 5px 10px 5px 10px; + border-radius: 5px; + font-size: 130%; + top: 5px; + right: 5px; +} + +.methods .section-header { + /* Override parent class attributes. */ + border-bottom: none !important; + font-size: 1.1em !important; + margin: 0 0 -5px; + padding: 0; +} + +.section-header:hover a:after { + content: '\2002\00a7\2002'; +} + +.section-header:hover a { + text-decoration: none; +} + +.section-header a { + color: inherit; +} + +.collapse-toggle { + font-weight: 300; + position: absolute; + left: -23px; + color: #999; + top: 0; +} + +.toggle-wrapper > .collapse-toggle { + left: -24px; + margin-top: 0px; +} + +.toggle-wrapper { + position: relative; +} + +.toggle-wrapper.collapsed { + height: 1em; + transition: height .2s; +} + +.collapse-toggle > .inner { + display: inline-block; + width: 1.2ch; + text-align: center; +} + +.toggle-label { + color: #999; +} + +.ghost { + display: none; +} + +.ghost + .since { + position: initial; + display: table-cell; +} + +.since + .srclink { + display: table-cell; + padding-left: 10px; +} + +span.since { + position: initial; + font-size: 20px; + margin-right: 5px; +} + +:target > code { + background: #FDFFD3; +} + +/* Media Queries */ + +@media (max-width: 700px) { + body { + padding-top: 0px; + } + + .sidebar { + height: 40px; + min-height: 40px; + width: 100%; + margin: 0px; + padding: 0px; + position: static; + } + + .sidebar .location { + float: right; + margin: 0px; + padding: 3px 10px 1px 10px; + min-height: 39px; + background: inherit; + text-align: left; + font-size: 24px; + } + + .sidebar .location:empty { + padding: 0; + } + + .sidebar img { + width: 35px; + margin-top: 5px; + margin-bottom: 0px; + float: left; + } + + nav.sub { + margin: 0 auto; + } + + .sidebar .block { + display: none; + } + + .content { + margin-left: 0px; + } + + .content .in-band { + width: 100%; + } + + .content .out-of-band { + display: none; + } + + .toggle-wrapper > .collapse-toggle { + left: 0px; + } + + .toggle-wrapper { + height: 1.5em; + } +} + +@media print { + nav.sub, .content .out-of-band, .collapse-toggle { + display: none; + } +} From ec6918125af06be8993459dbbe56bc7f17bfe3dc Mon Sep 17 00:00:00 2001 From: Pietro Albini Date: Tue, 29 Oct 2019 17:09:47 +0100 Subject: [PATCH 11/15] docker: retry running migrations if postgresql is not already up --- docker-entrypoint.sh | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/docker-entrypoint.sh b/docker-entrypoint.sh index 7c4d29b4d..3f9d6edfc 100755 --- a/docker-entrypoint.sh +++ b/docker-entrypoint.sh @@ -7,7 +7,26 @@ export DOCS_RS_DOCKER=true export RUST_LOG=cratesfyi,rustwide=info export PATH="$PATH:/build/target/release" -cratesfyi database migrate +# Try migrating the database multiple times if it fails +# This avoids the docker container crashing the first time it's started with +# docker-compose, as PostgreSQL needs some time to initialize. +set +e +failed=0 +while true; do + if ! cratesfyi database migrate; then + ((failed=failed + 1)) + if [ "${failed}" -eq 5 ]; then + exit 1 + fi + echo "failed to migrate the database" + echo "waiting 1 second..." + sleep 1 + else + break + fi +done +set -e + cratesfyi database update-search-index cratesfyi database update-release-activity From d9c4c66726c5124a070dfe8ce0350fa6c0e95344 Mon Sep 17 00:00:00 2001 From: Pietro Albini Date: Tue, 29 Oct 2019 17:13:39 +0100 Subject: [PATCH 12/15] docker: avoid past creates being scheduled during first start --- docker-entrypoint.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docker-entrypoint.sh b/docker-entrypoint.sh index 3f9d6edfc..c2ba355fa 100755 --- a/docker-entrypoint.sh +++ b/docker-entrypoint.sh @@ -32,6 +32,8 @@ cratesfyi database update-release-activity if ! [ -d "${CRATESFYI_PREFIX}/crates.io-index/.git" ]; then git clone https://github.com/rust-lang/crates.io-index "${CRATESFYI_PREFIX}/crates.io-index" + # Prevent new crates built before the container creation to be built + git --git-dir="$CRATESFYI_PREFIX/crates.io-index/.git" branch crates-index-diff_last-seen fi cratesfyi "$@" From 7b1eaa811f6e9373d8afa8dd47b346c729f35f17 Mon Sep 17 00:00:00 2001 From: Pietro Albini Date: Tue, 29 Oct 2019 17:47:00 +0100 Subject: [PATCH 13/15] ci: build the docker image and on master upload it to ecr --- .github/workflows/ci.yml | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 863289c23..76b5209a7 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -21,3 +21,25 @@ jobs: - name: Test docs.rs run: cargo test -- --test-threads=1 + + docker: + name: Docker + runs-on: ubuntu-latest + steps: + + - uses: actions/checkout@master + with: + fetch-depth: 2 + + - name: Build the Docker image + run: docker build -t docsrs . + + - name: Upload the Docker image to ECR + uses: rust-lang/simpleinfra/github-actions/upload-docker-image@master + with: + image: docsrs + repository: docsrs + region: us-west-1 + aws_access_key_id: "${{ secrets.aws_access_key_id }}" + aws_secret_access_key: "${{ secrets.aws_secret_access_key }}" + if: github.ref == 'refs/heads/master' From db195c86aaf907a94ddd3fc52468306703901894 Mon Sep 17 00:00:00 2001 From: Pietro Albini Date: Wed, 30 Oct 2019 17:22:17 +0100 Subject: [PATCH 14/15] docker: address review comments --- Dockerfile | 4 ++-- README.md | 4 ++++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index 937a4ad99..f0a567742 100644 --- a/Dockerfile +++ b/Dockerfile @@ -14,7 +14,7 @@ FROM ubuntu:bionic AS build # Install packaged dependencies RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \ build-essential git curl cmake gcc g++ pkg-config libmagic-dev \ - libssl-dev zlib1g-dev sudo ca-certificates docker.io + libssl-dev zlib1g-dev ca-certificates # Install the stable toolchain with rustup RUN curl https://static.rust-lang.org/rustup/dist/x86_64-unknown-linux-gnu/rustup-init >/tmp/rustup-init && \ @@ -26,7 +26,7 @@ ENV PATH=/root/.cargo/bin:$PATH # every time the source code changes. This takes advantage of Docker's layer # caching, and it works by copying the Cargo.{toml,lock} with dummy source code # and doing a full build with it. -RUN mkdir -p /build/docs.rs /build/src/web/badge +RUN mkdir -p /build/src/web/badge WORKDIR /build COPY Cargo.lock Cargo.toml ./ COPY src/web/badge src/web/badge/ diff --git a/README.md b/README.md index 7d77e0ebe..3bd41e51a 100644 --- a/README.md +++ b/README.md @@ -64,6 +64,10 @@ cp .env.sample .env docker-compose up # This may take a half hour or more on the first run ``` +If you need to store big files in the repository's directory is recommended to +put them in the `ignored/` subdirectory, which is ignored both by git and +Docker. + ### CLI #### Starting web server From dda2eb3e740d4dad51c95f499addc4df3a8a8a52 Mon Sep 17 00:00:00 2001 From: Pietro Albini Date: Wed, 30 Oct 2019 18:05:35 +0100 Subject: [PATCH 15/15] Update README.md Co-Authored-By: Joshua Nelson --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 3bd41e51a..a228b7304 100644 --- a/README.md +++ b/README.md @@ -64,7 +64,7 @@ cp .env.sample .env docker-compose up # This may take a half hour or more on the first run ``` -If you need to store big files in the repository's directory is recommended to +If you need to store big files in the repository's directory it's recommended to put them in the `ignored/` subdirectory, which is ignored both by git and Docker.