diff --git a/.circleci/config.yml b/.circleci/config.yml index 16b113f..b933d65 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1,4 +1,6 @@ -# Use the latest 2.1 version of CircleCI pipeline process engine. See: https://circleci.com/docs/2.0/configuration-reference +--- +# Use the latest 2.1 version of CircleCI pipeline process engine. See: +# https://circleci.com/docs/2.0/configuration-reference version: 2.1 # Orchestrate or schedule a set of jobs workflows: @@ -8,17 +10,8 @@ workflows: jobs: build-and-test: machine: true - resource_class: medium + resource_class: large steps: - # CircleCI has its own docker-compose already installed, but as of this writing, their version is too old to understand our docker-compose.yml - - run: - name: Install Docker Compose - command: | - set -x - curl -L https://github.com/docker/compose/releases/download/1.26.2/docker-compose-`uname -s`-`uname -m` > /home/circleci/bin/docker-compose - sudo chmod +x /home/circleci/bin/docker-compose - which docker-compose - docker-compose --version - checkout - run: command: | @@ -26,7 +19,7 @@ jobs: name: clone missing repositories - run: command: | - docker-compose --verbose up -d api_test + docker-compose --verbose --profile test up -d name: compose up # Since we're running docker-compose -d, we don't actually know if # Elasticsearch is available at the time this build step begins. We @@ -38,21 +31,12 @@ jobs: - run: name: Run complete MetaCPAN API Test Suite command: | - docker-compose exec -T api_test prove -lr --jobs 2 t - docker-compose down + docker-compose --profile test exec -T api_test prove -lr --jobs 4 t + docker-compose --profile test down - run: name: Show Docker container logs on Error command: | - docker-compose logs + docker-compose --profile test logs docker stats --no-stream docker ps -a | head - name: docker-compose logs when: on_fail - - run: - command: | - docker-compose --verbose up -d github-meets-cpan - name: github-meets-cpan up - - run: - command: | - docker-compose exec -T github-meets-cpan prove -lr --jobs 2 t - docker-compose down diff --git a/.env b/.env index 074398d..6536994 100644 --- a/.env +++ b/.env @@ -1,4 +1,14 @@ -COMPOSE_PROJECT_NAME=metacpan +API_SERVER="morbo -l http://*:5000 -w app.psgi -w bin -w lib -w templates --verbose" +COLUMNS=80 +ES=elasticsearch:9200 +ES_TEST=elasticsearch_test:9200 +MINICPAN=/CPAN +MOJO_MODE=development +NET_ASYNC_HTTP_MAXCONNS=1 +PERL_CARTON_PATH=/carton +PG_DATABASE=metacpan +PG_HOST=pghost +PG_PASSWORD=t00lchain +PG_PORT=5432 +PG_USER=metacpan PLACK_ENV=development -PGDB=pgdb:5432 -API_SERVER=morbo -l http://*:5000 -w app.psgi -w bin -w lib -w templates --verbose diff --git a/.github/workflows/up.yml b/.github/workflows/up.yml index 9d6a13f..0adfc79 100644 --- a/.github/workflows/up.yml +++ b/.github/workflows/up.yml @@ -13,7 +13,7 @@ jobs: strategy: max-parallel: 1 steps: - - uses: actions/checkout@v1 + - uses: actions/checkout@v3 - name: init run: bin/metacpan-docker init @@ -28,16 +28,6 @@ jobs: - name: down run: docker-compose down - - name: up github-meets-cpan - run: docker-compose up -d github-meets-cpan - - name: down - run: docker-compose down - - - name: up github-meets-cpan-cron - run: docker-compose up -d github-meets-cpan-cron - - name: down - run: docker-compose down - - name: up web run: docker-compose up -d web - name: down diff --git a/README.md b/README.md index 4d102ee..8bf4b24 100644 --- a/README.md +++ b/README.md @@ -2,45 +2,45 @@ [![CircleCI](https://circleci.com/gh/metacpan/metacpan-docker.svg?style=svg)](https://circleci.com/gh/metacpan/metacpan-docker) -![docker-compose up](https://github.com/metacpan/metacpan-docker/workflows/docker-compose%20up/badge.svg?branch=master) +![docker compose up](https://github.com/metacpan/metacpan-docker/workflows/docker-compose%20up/badge.svg?branch=master) -* [Running the MetaCPAN stack with Docker (via Docker Compose)](#running-the-metacpan-stack-with-docker-via-docker-compose) -* [Quick Start](#quick-start) -* [Working with Containers](#working-with-containers) - * [Building Containers](#building-containers) - * [Accessing Containers](#accessing-containers) - * [Accessing Services](#accessing-services) - * [`web`](#web) - * [`api`](#api) - * [`github-meets-cpan`](#github-meets-cpan) - * [`Elasticsearch`](#elasticsearch) - * [`grep`](#grep) -* [System architecture](#system-architecture) - * [The `bin/metacpan-docker` script](#the-binmetacpan-docker-script) - * [`bin/metacpan init`](#binmetacpan-init) - * [`bin/metacpan localapi`](#binmetacpan-localapi) - * [`bin/metacpan-docker pull`](#binmetacpan-docker-pull) - * [`bin/metacpan-docker reset`](#binmetacpan-docker-reset) - * [`bin/metacpan-docker` build/up/down/start/stop/run/ps/top...](#binmetacpan-docker-buildupdownstartstoprunpstop) - * [Services](#services) - * [`web`](#web-1) - * [`api`](#api-1) - * [`grep`](#grep-1) - * [Setting up a partial CPAN in the `api` service](#setting-up-a-partial-cpan-in-the-api-service) - * [Bootstrapping the `elasticsearch` indices](#bootstrapping-the-elasticsearch-indices) - * [Putting the above all together](#putting-the-above-all-together) - * [elasticsearch and elasticsearch_test](#elasticsearch-and-elasticsearch_test) -* [Tips and tricks](#tips-and-tricks) - * [Running your own miniCPAN inside metacpan-docker](#running-your-own-minicpan-inside-metacpan-docker) - * [Running tests](#running-tests) - * [Updating Carton dependencies](#updating-carton-dependencies) - * [Updating the git repositories](#updating-the-git-repositories) - * [Running Kibana to peek into Elasticsearch data](#running-kibana-to-peek-into-elasticsearch-data) -* [Peeking Inside the Container](#peeking-inside-the-container) -* [To Do](#to-do) -* [See also](#see-also) +- [Running the MetaCPAN stack with Docker (via Docker Compose)](#running-the-metacpan-stack-with-docker-via-docker-compose) +- [Quick Start](#quick-start) +- [Working with Containers](#working-with-containers) + - [Building Containers](#building-containers) + - [Accessing Containers](#accessing-containers) + - [Accessing Services](#accessing-services) + - [`web`](#web) + - [`api`](#api) + - [`Elasticsearch`](#elasticsearch) + - [`PostgreSQL`](#postgresql) + - [`grep`](#grep) +- [System architecture](#system-architecture) + - [The `bin/metacpan-docker` script](#the-binmetacpan-docker-script) + - [`bin/metacpan init`](#binmetacpan-init) + - [`bin/metacpan localapi`](#binmetacpan-localapi) + - [`bin/metacpan-docker pull`](#binmetacpan-docker-pull) + - [`bin/metacpan-docker reset`](#binmetacpan-docker-reset) + - [`bin/metacpan-docker` build/up/down/start/stop/run/ps/top...](#binmetacpan-docker-buildupdownstartstoprunpstop) + - [Services](#services) + - [`web`](#web-1) + - [`api`](#api-1) + - [`grep`](#grep-1) + - [Setting up a partial CPAN in the `api` service](#setting-up-a-partial-cpan-in-the-api-service) + - [Bootstrapping the `elasticsearch` indices](#bootstrapping-the-elasticsearch-indices) + - [Putting the above all together](#putting-the-above-all-together) + - [elasticsearch and elasticsearch_test](#elasticsearch-and-elasticsearch_test) +- [Tips and tricks](#tips-and-tricks) + - [Running your own miniCPAN inside metacpan-docker](#running-your-own-minicpan-inside-metacpan-docker) + - [Running tests](#running-tests) + - [Updating Carton dependencies](#updating-carton-dependencies) + - [Updating the git repositories](#updating-the-git-repositories) + - [Running Kibana to peek into Elasticsearch data](#running-kibana-to-peek-into-elasticsearch-data) +- [Peeking Inside the Container](#peeking-inside-the-container) +- [To Do](#to-do) +- [See also](#see-also) @@ -51,7 +51,7 @@ of things to be done better. Please use it and create Issues with your problems. ## Quick Start -Install [Docker][0] and [Docker Compose][1] for your platform. [Docker for +Install [Docker][0] and [Docker Compose][1] (v2+) for your platform. [Docker for Mac][2] or [Docker for Windows][3] will install both tools for you, if you are on either of these environments. @@ -60,6 +60,10 @@ on either of these environments. [2]: https://docs.docker.com/docker-for-mac/ [3]: https://docs.docker.com/docker-for-windows/ +On Debian / Ubuntu, install using: + + apt install docker-compose-v2 + On Linux, Docker's default implementation only allows `root` user access to Docker commands and to control containers. In order to allow a regular user to access docker follow the @@ -67,8 +71,25 @@ access docker follow the This document assumes the post-installation steps have been followed for the current user. -It is highly recommended that you alias `docker-compose` to `fig` (its original -name) and use it wherever `docker-compose` is used. You are going to have to +You will also need Docker buildx, and to enable Docker BuildKit. They should be +set up by default when using Docker Desktop, but on Linux you may need to +install them. buildx is the `docker-buildx` package on Debian based systems. +Docker BuildKit can be enabled by following the +[Getting Started](https://docs.docker.com/build/buildkit/#getting-started) +instructions. + +On Debian / Ubuntu, install using: + + apt install docker-buildx + +If you are running a Mac ARM64 system, you will need to manually tell docker to +use the x86_64 version of Elasticsearch 2.4. This can be done by running the +command: + + docker pull elasticsearch:2.4 --platform=linux/x86_64 + +It is highly recommended that you alias `docker compose` to `fig` (its original +name) and use it wherever `docker compose` is used. You are going to have to type this command a lot. Then, clone this repo and set up the environment: @@ -88,10 +109,11 @@ These repositories are automatically mounted into the appropriate docker containers allowing the developer to use their preferred tools to work with the source code. -The `docker-compose up` command on its own will bring up the entire stack in the -foreground (logs will be displayed). +The `docker compose --profile dev up` command on its own will bring up the +entire stack in the foreground (logs will be displayed). -The `docker-compose up` command will also fetch the official container images from +The `docker compose --profile dev up` command will also fetch the official +container images from [MetaCPAN Docker Hub](https://cloud.docker.com/u/metacpan/repository/list) repositories. @@ -102,20 +124,20 @@ Docker) and run the services. Don't forget to seed the local `metacpan-api` with a partial CPAN; run the following command in a separate terminal to get yourself up to speed: - docker-compose exec api index-cpan.sh + docker compose exec api index-cpan.sh This will prompt you to confirm removing old indices and setting up mappings on -the Elasticsearch service (say `YES`). It will then proceed to rsync a partial CPAN in -`/CPAN` for its metadata to be imported. +the Elasticsearch service (say `YES`). It will then proceed to rsync a partial +CPAN in `/CPAN` for its metadata to be imported. -Once the above is done, you should be able to see your local partial CPAN data -in e.g. [http://localhost:5001/recent](http://localhost:5001/recent) and -elsewhere. +After the initialization above completes, the next step is to start the web +frontend with the following command: -Alternatively, if you just want to hack on the web frontend, you can run this -instead of all the above: + docker compose up web-server - docker-compose up web +Once that is done, you should be able to see your local partial CPAN data +in e.g. [http://localhost:5001/recent](http://localhost:5001/recent) and +elsewhere. From here, you can proceed and hack on the MetaCPAN code at `src/metacpan-api` and/or `src/metacpan-web` directories, and saving edits will reload the @@ -124,7 +146,7 @@ corresponding apps automatically! When done hacking (or, more likely, when you need to rebuild/refresh your Docker environment) you can then run - docker-compose down + docker compose --profile dev down in another terminal to stop all MetaCPAN services and remove the containers. @@ -134,110 +156,69 @@ For further details, read on! ### Building Containers -You can (re)build arbitrary containers. For instance, if you want to rebuild -the `api` container: +You can (re)build arbitrary containers. For instance, if you want to rebuild the +`api` container: -``` -docker-compose build api -``` + docker compose build api ### Accessing Containers -Containers are accessible via the `docker-compose exec` command followed by the +Containers are accessible via the `docker compose exec` command followed by the container and then the command to execute. For example, to start a shell prompt in the `api` container: - docker-compose exec api /bin/bash + docker compose exec api /bin/bash Executing tests via `prove` inside the API container: - docker-compose exec api_test prove -lvr \ + docker compose exec api_test prove -lvr \ t/00_setup.t \ t/01_darkpan.t \ t/api/controller/cover.t To access the `psql` command line client in the PostgreSQL container: - docker-compose exec pgdb psql - -Similarly the `mongodb` command line client in the MongoDB container is accessed -via: - - docker-compose exec mongodb mongo --host mongodb test + docker compose exec pgdb psql ### Accessing Services Each container is responsible for a different service. Some of these services are available in the developer environment via ports on the host system. -We are using [traefik][13] to manage the traffic between services. -The current configuration is: - -- api: [http://api.metacpan.localhost](http://api.metacpan.localhost) -- web: [http://web.metacpan.localhost](http://web.metacpan.localhost) -- github-meets-cpan: [http://gh.metacpan.localhost](http://gh.metacpan.localhost) -- grep: [http://grep.metacpan.localhost](http://grep.metacpan.localhost) - -In order to access to the localhost subdomains, you probably have to manually -add these entries in you `/etc/hosts` file. - -``` -# add to /etc/hosts -127.0.0.1 api.metacpan.localhost -127.0.0.1 gh.metacpan.localhost -127.0.0.1 grep.metacpan.localhost -127.0.0.1 metacpan.localhost -127.0.0.1 web.metacpan.localhost -``` - -You can access the dashboard configuration via: -[http://metacpan.localhost:8080](http://metacpan.localhost:8080) - -[0]: https://docs.traefik.io/providers/docker/ - #### `web` -The local instance of the web front end is accessiable via: +The local instance of the web front end is accessible via: -* [http://localhost:5001](http://localhost:5001) -* [http://web.metacpan.localhost](http://web.metacpan.localhost) +- [http://localhost:5001](http://localhost:5001) +- [http://web.metacpan.localhost](http://web.metacpan.localhost) #### `api` -* [http://localhost:5000](http://localhost:5000) -* [http://api.metacpan.localhost](http://api.metacpan.localhost) - -#### `github-meets-cpan` - -* [http://localhost:3000](http://localhost:3000) -* [http://gh.metacpan.localhost](http://gh.metacpan.localhost) +- [http://localhost:5000](http://localhost:5000) +- [http://api.metacpan.localhost](http://api.metacpan.localhost) #### `Elasticsearch` -The `elasticsearch` and `elasticsearch_test` containers are not exposed directly. They are available via the `api` and `api_test` containers. +The `elasticsearch` and `elasticsearch_test` containers are not exposed +directly. They are available via the `api` and `api_test` containers. You can query the `elasticsearch` container via: -``` -docker-compose exec elasticsearch curl http://localhost:9200 -``` + docker compose exec elasticsearch curl http://localhost:9200 You can query the `elasticsearch_test` container via: -``` -docker-compose exec elasticsearch_test curl http://localhost:9200 -``` + docker compose exec elasticsearch_test curl http://localhost:9200 -#### `PostgreSQL and MongoDB` +#### `PostgreSQL` -The PostgreSQL and MongoDB services by default are only accessible from other -containers. +The PostgreSQL service by default is only accessible from other containers. #### `grep` The grep metacpan front end is accessible via: -* [http://grep.metacpan.localhost](http://grep.metacpan.localhost) +- [http://localhost:3000](http://localhost:3000) Note: this is using a smaller, frozen version of `metacpan-cpan-extracted` via [metacpan-cpan-extracted-lite](https://github.com/metacpan/metacpan-cpan-extracted-lite). @@ -253,8 +234,8 @@ The system consists of several services that live in docker containers: - `elasticsearch_test` — database for `api_test` - `pgdb` - PostgreSQL database container - `logspout` - Docker log interface to [honeycomb.io](https://honeycomb.io) -- `github-meets-cpan` - Containerized version of [gh.metacpan.org](https://gh.metacpan.org) -- `grep` - the web interface for grep.metacpan on [http://localhost:3001](http://localhost:3001) +- `grep` - the web interface for grep.metacpan on + [http://localhost:3001](http://localhost:3001) These services use one or more Docker volumes: @@ -266,20 +247,20 @@ These services use one or more Docker volumes: mounted on `/carton` instead of `local`, to prevent clashing with the host user's Carton - `metacpan_git_shared`: points to the git repo containing all extracted CPAN - versions. This is mounted in `/shared/metacpan_git`. - This can be either `metacpan-cpan-extracted` or `metacpan-cpan-extracted-lite`. - The volume is bound to the local repo at `${PWD}/src/metacpan-cpan-extracted`. + versions. This is mounted in `/shared/metacpan_git`. This can be either + `metacpan-cpan-extracted` or `metacpan-cpan-extracted-lite`. The volume is + bound to the local repo at `${PWD}/src/metacpan-cpan-extracted`. [4]: https://metacpan.org/pod/Carton Docker Compose is used to, uh, _compose_ them all together into one system. -Using `docker-compose` directly is a mouthful, however, so putting this all +Using `docker compose` directly is a mouthful, however, so putting this all together is done via the `bin/metacpan-docker` script to simplify setup and usage (and to get you started hacking on the MetaCPAN sooner!) ### The `bin/metacpan-docker` script -`bin/metacpan-docker` is a thin wrapper around the `docker-compose` command, +`bin/metacpan-docker` is a thin wrapper around the `docker compose` command, providing the environment variables necessary to run a basic MetaCPAN environment. It provides these subcommands: @@ -287,41 +268,42 @@ environment. It provides these subcommands: The `init` subcommand basically clones the [metacpan-api][5] and [metacpan-web][6] repositories, and sets up the git commit hooks for each of -them, in preparation for future `docker-compose` or +them, in preparation for future `docker compose` or `bin/metacpan-docker localapi` commands. -It also clones the `metacpan-grep-front-end` and `metacpan-cpan-extracted-lite` repositories. +It also clones the `metacpan-grep-front-end` and `metacpan-cpan-extracted-lite` +repositories. [5]: https://github.com/metacpan/metacpan-api [6]: https://github.com/metacpan/metacpan-web #### `bin/metacpan localapi` -The `localapi` subcommand adds the necessary configuration for `docker-compose` +The `localapi` subcommand adds the necessary configuration for `docker compose` to run both the `metacpan-web` and `metacpan-api` services, along with `elasticsearch` and Docker volumes. Under the hood, it customizes the `COMPOSE_FILE` and `COMPOSE_PROJECT_NAME` environment variables used by -`docker-compose` to use additional YAML configuration files aside from the -default `docker-compose.yml`. +`docker compose` to use additional YAML configuration files aside from the +default `docker compose.yml`. #### `bin/metacpan-docker pull` -This is used to update all the git repository in `src/*`. -This will stay on your current local branch. +This is used to update all the git repository in `src/*`. This will stay on your +current local branch. #### `bin/metacpan-docker reset` -This is used to reset all the git repositories in `src/*` to their -latest version on `upstream/master`. -This will fail if you have some uncommited local changes. -You should then commit or cancel your changes before re-running the command. +This is used to reset all the git repositories in `src/*` to their latest +version on `upstream/master`. This will fail if you have some uncommitted local +changes. You should then commit or cancel your changes before re-running the +command. #### `bin/metacpan-docker` build/up/down/start/stop/run/ps/top... -As noted earlier, `bin/metacpan-docker` is a thin wrapper around `docker-compose`, -so commands like `up`, `down`, and `run` will work as expected from -`docker-compose`. See the [docker-compose docs][7] for an overview of available -commands. +As noted earlier, `bin/metacpan-docker` is a thin wrapper around +`docker compose`, so commands like `up`, `down`, and `run` will work as expected +from `docker compose`. See the [docker compose docs][7] for an overview of +available commands. [7]: https://docs.docker.com/compose/reference/overview/#command-options-overview-and-help @@ -333,8 +315,9 @@ commands. The `web` service is a checkout of `metacpan-web`, built as a Docker image. Running this service alone is enough if you want to just hack on the frontend, since by default the service is configured to talk to -[https://fastapi.metacpan.org](https://fastapi.metacpan.org) for its backend; if this is what you want, then you -can simply invoke `docker-compose up` or `docker-compose up web`. +[https://fastapi.metacpan.org](https://fastapi.metacpan.org) for its backend; if +this is what you want, then you can simply invoke `docker compose up` or +`docker compose up web`. #### `api` @@ -347,8 +330,9 @@ additional commands in a separate terminal once #### `grep` -The `grep` service is a checkout of `metacpan-grep-front-end`, built as a Docker image. Note that this is using the `metacpan_git_shared` volume, which requires the git repo for -`metacpan-cpan-extracted` which can be initialized by running: +The `grep` service is a checkout of `metacpan-grep-front-end`, built as a Docker +image. Note that this is using the `metacpan_git_shared` volume, which requires +the git repo for `metacpan-cpan-extracted` which can be initialized by running: ./bin/metacpan-docker init @@ -358,9 +342,9 @@ Running bin/metacpan-docker localapi exec api partial-cpan-mirror.sh -will `rsync` modules from selected CPAN authors, plus the package and author indices, -into the `api` service's `/CPAN` directory. This is nearly equivalent to the -same script in the (now deprecated) [metacpan-developer][8] repository. +will `rsync` modules from selected CPAN authors, plus the package and author +indices, into the `api` service's `/CPAN` directory. This is nearly equivalent +to the same script in the (now deprecated) [metacpan-developer][8] repository. [8]: https://github.com/metacpan/metacpan-developer ##### Bootstrapping the `elasticsearch` indices @@ -387,7 +371,9 @@ instead will set it all up for you. The `elasticsearch` and `elasticsearch_test` services use the official [Elasticsearch Docker image][9], configured with settings and scripts taken from -the [metacpan-puppet][10] repository. The `api` service depends on the `elasticsearch` service and the `api_test` service depends on the `elasticsearch_test` services. +the [metacpan-puppet][10] repository. The `api` service depends on the +`elasticsearch` service and the `api_test` service depends on the +`elasticsearch_test` services. [9]: https://store.docker.com/images/elasticsearch [10]: https://github.com/metacpan/metacpan-puppet @@ -397,7 +383,7 @@ the [metacpan-puppet][10] repository. The `api` service depends on the `elastics ### Running your own miniCPAN inside metacpan-docker Suppose you have a local minicpan in `/home/ftp/pub/CPAN`. If you would like to -use this in `metacpan-docker`, then edit the `docker-compose.localapi.yml` to +use this in `metacpan-docker`, then edit the `docker compose.localapi.yml` to change the `api` service's volume mounts to use your local minicpan as `/CPAN`, e.g.: @@ -451,17 +437,18 @@ You can use `bin/metacpan-docker pull` to update all `src/*` directories. ### Running Kibana to peek into Elasticsearch data -By default, the `docker-compose.localapi.yml` configures the `elasticsearch` -service to listen on the Docker host at [http://localhost:9200](http://localhost:9200), and is also -accessible via the Docker `default` network address of [http://172.17.0.1:9200](http://172.17.0.1:9200); -you can inspect it via simple `curl` or `wget` requests, or use a [Kibana][12] -container, e.g. +By default, the `docker compose.localapi.yml` configures the `elasticsearch` +service to listen on the Docker host at +[http://localhost:9200](http://localhost:9200), and is also accessible via the +Docker `default` network address of +[http://172.17.0.1:9200](http://172.17.0.1:9200); you can inspect it via simple +`curl` or `wget` requests, or use a [Kibana][12] container, e.g. docker run --rm -p 5601:5601 -e ELASTICSEARCH_URL=http://172.17.0.1:9200 -it kibana:4.6 -Running the above will provide a Kibana container at [http://localhost:5601](http://localhost:5601), -which you can configure to have it read the `cpan*` index in the `elasticsearch` -service. +Running the above will provide a Kibana container at +[http://localhost:5601](http://localhost:5601), which you can configure to have +it read the `cpan*` index in the `elasticsearch` service. It is also certainly possible to run Kibana as part of the compose setup, by configuring e.g. a `kibana` service. @@ -472,7 +459,7 @@ configuring e.g. a `kibana` service. If you run `docker ps` you'll see the containers. You might see something like: -``` +```bash $ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 2efb9c475c83 metacpan-web:latest "carton exec plackup…" 12 hours ago Up 12 hours 0.0.0.0:5001->5001/tcp metacpan_web_1 diff --git a/bin/metacpan-docker b/bin/metacpan-docker index c3ea546..139b4b4 100755 --- a/bin/metacpan-docker +++ b/bin/metacpan-docker @@ -1,13 +1,12 @@ #!/usr/bin/env bash -# metacpan-docker: simple wrapper for docker-compose running MetaCPAN +# metacpan-docker: simple wrapper for docker compose running MetaCPAN set -e -GitRepos=("metacpan-api" "metacpan-web" "metacpan-grep-front-end" "metacpan-cpan-extracted-lite") +GitRepos=("metacpan-api" "metacpan-web" "metacpan-grep-front-end" "metacpan-cpan-extracted-lite" "metacpan-ingest") # sanity check type "docker" > /dev/null -type "docker-compose" > /dev/null git_clone_and_setup_hooks() { local repo=$1 @@ -16,6 +15,7 @@ git_clone_and_setup_hooks() { [ -d "$repo" ] || git clone "https://github.com/metacpan/$repo.git" cd "$repo" [ -e git/hooks/pre-commit ] && chmod +x git/hooks/pre-commit + [ -d .git/hooks ] || mkdir .git/hooks cd .git/hooks ln -sf ../../git/hooks/pre-commit ) @@ -81,30 +81,28 @@ reset_repo() { done } - case "x$1" in - 'xinit') - init - exit - ;; - 'xreset') - reset_repo - exit - ;; - 'xpull') - update - exit - ;; - 'xlocalapi') - shift - ;; - 'x') - init - update - exit - ;; - *) - ;; +'xinit') + init + exit + ;; +'xreset') + reset_repo + exit + ;; +'xpull') + update + exit + ;; +'xlocalapi') + shift + ;; +'x') + init + update + exit + ;; +*) ;; esac -exec docker-compose "$@" +exec docker compose "$@" diff --git a/bin/partial-cpan-mirror.sh b/bin/partial-cpan-mirror.sh index d901723..233b344 100755 --- a/bin/partial-cpan-mirror.sh +++ b/bin/partial-cpan-mirror.sh @@ -16,3 +16,4 @@ $RSYNC $PATH/authors/0* $MINICPAN/ $RSYNC $PATH/modules/0* $MINICPAN/ $RSYNC $PATH/indices/mirrors.json $MINICPAN/ +$RSYNC $PATH/indices/find-ls.gz $MINICPAN/ diff --git a/compose/web.yml b/compose/web.yml new file mode 100644 index 0000000..f6becf1 --- /dev/null +++ b/compose/web.yml @@ -0,0 +1,9 @@ +--- +services: + web-server: + profiles: + - cloud-es + ports: + - "5001:80" + networks: + - web-network diff --git a/configs/metacpan-api/metacpan.pl b/configs/metacpan-api/metacpan.pl deleted file mode 100644 index 8821e2e..0000000 --- a/configs/metacpan-api/metacpan.pl +++ /dev/null @@ -1,23 +0,0 @@ -# do not edit this file -# create etc/metacpan_local.pl instead -use FindBin; - -{ - # ElasticSearch instance, can be either a single server - # or an arrayref of servers - es => 'elasticsearch:9200', - # the port of the api server - port => '5000', - # log level - level => 'info', - # appender for Log4perl - # default layout is "%d %p{1} %c: %m{chomp}%n" - # can be overridden using the layout key - # defining logger in metacpan_local.pl will - # override and not append to this configuration - logger => [{ - class => 'Log::Log4perl::Appender::File', - filename => $FindBin::RealBin . '/../var/log/metacpan.log', - syswrite => 1, - }] -} diff --git a/configs/metacpan-api/metacpan_server.conf b/configs/metacpan-api/metacpan_server.conf deleted file mode 100644 index 1894643..0000000 --- a/configs/metacpan-api/metacpan_server.conf +++ /dev/null @@ -1,25 +0,0 @@ -git /usr/bin/git -cpan /CPAN -minion_dsn = postgresql://metacpan:metacpan@pgdb/minion_queue -secret = I wish I had one to keep - - - servers elasticsearch:9200 - - - - servers elasticsearch:9200 - - - - servers elasticsearch:9200 - - - - servers elasticsearch:9200 - - - - # required for server startup -- override this in metacpan_server_local.conf - private_key 59125ffc09413eed3f2a2c07a37c7a44b95633e2 - diff --git a/configs/metacpan-api/metacpan_server_testing.conf b/configs/metacpan-api/metacpan_server_testing.conf deleted file mode 100644 index 1600860..0000000 --- a/configs/metacpan-api/metacpan_server_testing.conf +++ /dev/null @@ -1,31 +0,0 @@ -cpan var/t/tmp/fakecpan -source_base var/t/tmp/source - - - servers __ENV(ES)__ - - - - servers __ENV(ES)__ - - - - servers __ENV(ES)__ - - - - captcha_class Captcha::Mock - private_key testing - - -github_key = foo -github_secret = bar - -secret weak - - - host smtp.fastmail.com - port 465 - username foo@metacpan.org - password seekrit - diff --git a/configs/metacpan-ingest/metacpan_ingest_local.conf b/configs/metacpan-ingest/metacpan_ingest_local.conf new file mode 100644 index 0000000..aed640c --- /dev/null +++ b/configs/metacpan-ingest/metacpan_ingest_local.conf @@ -0,0 +1 @@ +cpan = /CPAN diff --git a/configs/metacpan-web/metacpan_web_local.conf b/configs/metacpan-web/metacpan_web_local.conf deleted file mode 100644 index 16dc12c..0000000 --- a/configs/metacpan-web/metacpan_web_local.conf +++ /dev/null @@ -1,8 +0,0 @@ -api = http://api:5000 -api_public = http://localhost:5000 -source_host = http://localhost:5000 -web_host = http://localhost:5001 - - - cache_dir = /var/tmp/templates - diff --git a/docker-compose.yml b/docker-compose.yml index 6ddb536..854e883 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,6 +1,6 @@ --- -version: "3.4" - +x-project: + name: metacpan # ____ _____ ______ _____ ____ _____ ____ # / ___|| ____| _ \ \ / /_ _/ ___| ____/ ___| # \___ \| _| | |_) \ \ / / | | | | _| \___ \ @@ -8,109 +8,72 @@ version: "3.4" # |____/|_____|_| \_\ \_/ |___\____|_____|____/ # -services: - # __ _____ __ - # / /__________ ____ / __(_) /__ - # / __/ ___/ __ `/ _ \/ /_/ / //_/ __ - # / /_/ / / /_/ / __/ __/ / ,< _| =\__ - # \__/_/ \__,_/\___/_/ /_/_/|_| /o____o_\ - - traefik: - # The official v2.4.5 Traefik docker image - image: traefik:v2.4.5 - networks: - - traefik-network - # Enables the web UI and tells Traefik to listen to docker - command: - - "--api.insecure=true" - - "--providers.docker" - # Do not expose containers unless explicitly told so - - "--providers.docker.exposedbydefault=false" - ports: - # The HTTP port - - "80:80" - # The Web UI (enabled by --api.insecure=true) - - "8080:8080" - volumes: - # So that Traefik can listen to the Docker events - - /var/run/docker.sock:/var/run/docker.sock - - # _ _ - # | | ___ __ _ ___ _ __ ___ _ _| |_ - # | |/ _ \ / _` / __| '_ \ / _ \| | | | __| - # | | (_) | (_| \__ \ |_) | (_) | |_| | |_ - # |_|\___/ \__, |___/ .__/ \___/ \__,_|\__| - # |___/ |_| - # - - logspout: - image: honeycombio/logspout-honeycomb:1.13 - volumes: - - type: bind - source: /var/run/docker.sock - target: /var/run/docker.sock - env_file: - - logging.env - ports: - - "8100:80" +include: + - path: + - src/metacpan-web/docker-compose.yml + - compose/web.yml - # _ - # __ _____| |__ - # \ \ /\ / / _ \ '_ \ - # \ V V / __/ |_) | - # \_/\_/ \___|_.__/ +services: + # _ + # __ _ _ __ (_) + # / _` | '_ \| | + # | (_| | |_) | | + # \__,_| .__/|_| + # |_| # - web: + cloud_api: + profiles: + - cloud-es depends_on: - - traefik - image: metacpan/metacpan-web:latest + pghost: + condition: service_healthy + image: metacpan/metacpan-api:latest build: - context: ./src/metacpan-web + context: ./src/metacpan-api + # put variables for compose inside a .env file + # use env_file for variables to be set inside the container + env_file: + - .env + command: > + ${API_SERVER} ./bin/api.pl volumes: - type: volume - source: web_carton - target: /carton + source: cpan + target: /CPAN + - type: bind + source: ./src/metacpan-api + target: /metacpan-api - type: bind - source: ./configs/metacpan-web/metacpan_web_local.conf - target: /metacpan-web/metacpan_web_local.conf + source: ./bin/index-cpan.sh + target: /bin/index-cpan.sh read_only: true - type: bind - source: ./src/metacpan-web - target: /metacpan-web + source: ./bin/partial-cpan-mirror.sh + target: /bin/partial-cpan-mirror.sh read_only: true ports: - - "5001:5001" + - "5000:5000" networks: + - database - web-network - - traefik-network - labels: - - "traefik.enable=true" - - "traefik.docker.network=traefik-network" - - "traefik.http.routers.web.rule=Host(`web.metacpan.localhost`)" - - "traefik.http.services.web.loadbalancer.server.port=5001" - - # _ - # __ _ _ __ (_) - # / _` | '_ \| | - # | (_| | |_) | | - # \__,_| .__/|_| - # |_| - # api: + profiles: + - dev depends_on: - - elasticsearch - - pgdb - - traefik + elasticsearch: + condition: service_healthy + pghost: + condition: service_healthy image: metacpan/metacpan-api:latest build: context: ./src/metacpan-api + # put variables for compose inside a .env file + # use env_file for variables to be set inside the container env_file: - - localapi.env + - .env command: > - /metacpan-api/wait-for-es.sh http://elasticsearch:9200 "" -- - /metacpan-api/wait-for-it.sh -t 15 -s ${PGDB} -- ${API_SERVER} ./bin/api.pl volumes: - type: volume @@ -119,18 +82,6 @@ services: - type: bind source: ./src/metacpan-api target: /metacpan-api - - type: bind - source: ./configs/metacpan-api/metacpan_server.conf - target: /metacpan-api/metacpan_server.conf - read_only: true - - type: bind - source: ./configs/metacpan-api/metacpan_server_testing.conf - target: /metacpan-api/metacpan_server_testing.conf - read_only: true - - type: bind - source: ./configs/metacpan-api/metacpan.pl - target: /metacpan-api/etc/metacpan.pl - read_only: true - type: bind source: ./bin/index-cpan.sh target: /bin/index-cpan.sh @@ -144,26 +95,23 @@ services: networks: - database - elasticsearch - - traefik-network - web-network - labels: - - "traefik.enable=true" - - "traefik.docker.network=traefik-network" - - "traefik.http.routers.api.rule=Host(`api.metacpan.localhost`)" - - "traefik.http.services.api.loadbalancer.server.port=5000" api_test: + profiles: + - test + - ingest-test depends_on: - - elasticsearch_test - - pgdb + elasticsearch_test: + condition: service_healthy + pghost: + condition: service_healthy image: metacpan/metacpan-api:latest build: context: ./src/metacpan-api env_file: - localapi_test.env command: > - /metacpan-api/wait-for-es.sh http://elasticsearch_test:9200 "" -- - /metacpan-api/wait-for-it.sh -t 15 -s ${PGDB} -- ${API_SERVER} ./bin/api.pl volumes: - type: volume @@ -172,18 +120,6 @@ services: - type: bind source: ./src/metacpan-api target: /metacpan-api - - type: bind - source: ./configs/metacpan-api/metacpan_server.conf - target: /metacpan-api/metacpan_server.conf - read_only: true - - type: bind - source: ./configs/metacpan-api/metacpan_server_testing.conf - target: /metacpan-api/metacpan_server_testing.conf - read_only: true - - type: bind - source: ./configs/metacpan-api/metacpan.pl - target: /metacpan-api/etc/metacpan.pl - read_only: true - type: bind source: ./bin/index-cpan.sh target: /bin/index-cpan.sh @@ -198,61 +134,42 @@ services: - database - elasticsearch - # _ _ _ _ _ - # __ _(_) |_| |__ _ _| |__ _ __ ___ ___ ___| |_ ___ - # / _` | | __| '_ \| | | | '_ \ | '_ ` _ \ / _ \/ _ \ __/ __| - # | (_| | | |_| | | | |_| | |_) | | | | | | | __/ __/ |_\__ \ - # \__, |_|\__|_| |_|\__,_|_.__/ |_| |_| |_|\___|\___|\__|___/ - # |___/ - # - # ___ _ __ __ _ _ __ - # / __| '_ \ / _` | '_ \ - # | (__| |_) | (_| | | | | - # \___| .__/ \__,_|_| |_| - # |_| - # - github-meets-cpan: - image: metacpan/github-meets-cpan:latest - command: "/wait-for-it.sh mongodb:27017 -- morbo script/app.pl" + ingest: + profiles: + - dev + - ingest + image: metacpan/metacpan-ingest:latest + volumes: + - type: volume + source: cpan + target: /CPAN + - type: bind + source: ./configs/metacpan-ingest/metacpan_ingest_local.conf + target: /metacpan-ingest/metacpan_ingest_local.conf + read_only: true depends_on: - - mongodb - - logspout - - traefik + - elasticsearch networks: - - mongo - - traefik-network - labels: - - "traefik.enable=true" - - "traefik.docker.network=traefik-network" - - "traefik.http.routers.github-meets-cpan.rule=Host(`gh.metacpan.localhost`)" - - "traefik.http.services.gh-meet-cpan-web.loadbalancer.server.port=3000" - - # _ _ _ _ _ - # __ _(_) |_| |__ _ _| |__ _ __ ___ ___ ___| |_ ___ - # / _` | | __| '_ \| | | | '_ \ | '_ ` _ \ / _ \/ _ \ __/ __| - # | (_| | | |_| | | | |_| | |_) | | | | | | | __/ __/ |_\__ \ - # \__, |_|\__|_| |_|\__,_|_.__/ |_| |_| |_|\___|\___|\__|___/ - # |___/ - # - # ___ _ __ __ _ _ __ ___ _ __ ___ _ __ - # / __| '_ \ / _` | '_ \ / __| '__/ _ \| '_ \ - # | (__| |_) | (_| | | | | | (__| | | (_) | | | | - # \___| .__/ \__,_|_| |_| \___|_| \___/|_| |_| - # |_| - # + - elasticsearch - github-meets-cpan-cron: - image: metacpan/github-meets-cpan:latest - command: "/wait-for-it.sh mongodb:27017 -- perl cron/update.pl" - depends_on: - - mongodb + ingest-test: + profiles: + - ingest-test + image: metacpan/metacpan-ingest:latest + environment: + PLACK_ENV: development volumes: + - type: volume + source: cpan + target: /CPAN - type: bind - source: ${MC_CONF_PRIVATE_DIR:-.}/github-meets-cpan/environment.json - target: /code/environment.json + source: ./configs/metacpan-ingest/metacpan_ingest_local.conf + target: /metacpan-ingest/metacpan_ingest_local.conf read_only: true + depends_on: + - elasticsearch_test networks: - - mongo + - elasticsearch # __ _ _ __ ___ _ __ # / _` | '__/ _ \ '_ \ @@ -262,9 +179,11 @@ services: # |___/ |_| grep: - depends_on: - - traefik + profiles: + - grep image: metacpan/metacpan-grep-front-end:latest + ports: + - "3000:3000" build: context: ./src/metacpan-grep-front-end volumes: @@ -278,12 +197,6 @@ services: read_only: true env_file: - grep.env - networks: - - traefik-network - labels: - - "traefik.enable=true" - - "traefik.http.routers.grep.rule=Host(`grep.metacpan.localhost`)" - - "traefik.http.services.grep-web.loadbalancer.server.port=3000" # ____ _ _____ _ ____ _ ____ _____ ____ # | _ \ / \|_ _|/ \ | __ ) / \ / ___|| ____/ ___| @@ -300,19 +213,20 @@ services: # elasticsearch: + profiles: + - dev + - ingest image: elasticsearch:2.4 + environment: + - discovery.type=single-node volumes: - type: volume source: elasticsearch target: /usr/share/elasticsearch/data - - type: bind - source: ./elasticsearch/metacpan.yml - target: /usr/share/elasticsearch/config/metacpan.yml - read_only: true - - type: bind - source: ./elasticsearch/scripts - target: /usr/share/elasticsearch/config/scripts - read_only: true + healthcheck: + timeout: 5s + start_period: 60s + test: ["CMD", "curl", "--fail", "http://localhost:9200/_cluster/health?wait_for_status=yellow&timeout=5s"] ports: - "9200" networks: @@ -332,19 +246,20 @@ services: # elasticsearch_test: + profiles: + - test + - ingest-test image: elasticsearch:2.4 + environment: + - discovery.type=single-node volumes: - type: volume source: elasticsearch_test target: /usr/share/elasticsearch/data - - type: bind - source: ./elasticsearch/test.yml - target: /usr/share/elasticsearch/config/test.yml - read_only: true - - type: bind - source: ./elasticsearch/scripts - target: /usr/share/elasticsearch/config/scripts - read_only: true + healthcheck: + timeout: 5s + start_period: 60s + test: ["CMD", "curl", "--fail", "http://localhost:9200/_cluster/health?wait_for_status=yellow&timeout=5s"] ports: - "9200" networks: @@ -357,8 +272,13 @@ services: # |_| |___/ |_| # - pgdb: - hostname: pgdb + pghost: + profiles: + - cloud-es + - dev + - test + - ingest-test + hostname: pghost image: "postgres:${PG_VERSION_TAG:-9.6-alpine}" build: context: "./pg" @@ -366,7 +286,7 @@ services: PG_TAG: "${PG_VERSION_TAG:-9.6-alpine}" environment: POSTGRES_PASSWORD: metacpan - POSTGRES_USERNAME: metacpan123 + POSTGRES_USER: metacpan123 POSTGRES_DB: metacpan networks: - database @@ -378,7 +298,7 @@ services: test: ["CMD", "/healthcheck.sh"] volumes: - type: volume - source: pgdb-data + source: pghost-data target: /var/lib/postgresql/data - type: bind source: ./pg/docker-entrypoint-initdb.d @@ -389,25 +309,6 @@ services: target: /healthcheck.sh read_only: true - # _ _ - # _ __ ___ ___ _ __ __ _ ___ __| | |__ - # | '_ ` _ \ / _ \| '_ \ / _` |/ _ \ / _` | '_ \ - # | | | | | | (_) | | | | (_| | (_) | (_| | |_) | - # |_| |_| |_|\___/|_| |_|\__, |\___/ \__,_|_.__/ - # |___/ - # - - mongodb: - image: mongo:4.4.9 - networks: - - mongo - healthcheck: - interval: 10s - timeout: 10s - retries: 0 - start_period: 40s - test: echo 'db.runCommand("ping").ok' | mongo mongodb:27017/test --quiet - # _ _ _____ _______ _____ ____ _ ______ # | \ | | ____|_ _\ \ / / _ \| _ \| |/ / ___| # | \| | _| | | \ \ /\ / / | | | |_) | ' /\___ \ @@ -418,8 +319,6 @@ services: networks: database: elasticsearch: - mongo: - traefik-network: web-network: # __ _____ _ _ _ __ __ _____ ____ @@ -430,11 +329,10 @@ networks: # volumes: - web_carton: api_carton: cpan: elasticsearch: elasticsearch_test: - pgdb-data: + pghost-data: metacpan_git_shared: external: true diff --git a/elasticsearch/metacpan.yml b/elasticsearch/metacpan.yml deleted file mode 100644 index 8eafdd9..0000000 --- a/elasticsearch/metacpan.yml +++ /dev/null @@ -1,29 +0,0 @@ -cluster.name: 'dev' - -index: - number_of_replicas: 0 - number_of_shards: 1 - search: - slowlog: - threshold: - query: - warn: 10s - info: 2s - fetch: - warn: 1s - -gateway: - recover_after_nodes: 1 - recover_after_time: 3m - expected_nodes: 1 - -node: - max_local_storage_nodes: 1 - -discovery: - zen: - minimum_master_nodes: 1 - ping: - multicast.enabled: false - unicast.hosts: - - "elasticsearch:9300" diff --git a/elasticsearch/scripts/prefer_shorter_module_names_100.groovy b/elasticsearch/scripts/prefer_shorter_module_names_100.groovy deleted file mode 100644 index f99da4d..0000000 --- a/elasticsearch/scripts/prefer_shorter_module_names_100.groovy +++ /dev/null @@ -1 +0,0 @@ -_score - doc.documentation.value.length().toDouble()/100; \ No newline at end of file diff --git a/elasticsearch/scripts/prefer_shorter_module_names_400.groovy b/elasticsearch/scripts/prefer_shorter_module_names_400.groovy deleted file mode 100644 index 04c787b..0000000 --- a/elasticsearch/scripts/prefer_shorter_module_names_400.groovy +++ /dev/null @@ -1,2 +0,0 @@ -len = (doc.documentation.empty ? 26 : doc.documentation.value.length()); -_score - len.toDouble()/400; \ No newline at end of file diff --git a/elasticsearch/scripts/score_version_numified.groovy b/elasticsearch/scripts/score_version_numified.groovy deleted file mode 100644 index 65032ea..0000000 --- a/elasticsearch/scripts/score_version_numified.groovy +++ /dev/null @@ -1 +0,0 @@ -doc.module.version_numified.value; \ No newline at end of file diff --git a/elasticsearch/scripts/status_is_latest.groovy b/elasticsearch/scripts/status_is_latest.groovy deleted file mode 100644 index ac7ba92..0000000 --- a/elasticsearch/scripts/status_is_latest.groovy +++ /dev/null @@ -1 +0,0 @@ -doc.status.value == 'latest'; \ No newline at end of file diff --git a/elasticsearch/test.yml b/elasticsearch/test.yml deleted file mode 100644 index 8fa6cd5..0000000 --- a/elasticsearch/test.yml +++ /dev/null @@ -1,29 +0,0 @@ -cluster.name: 'dev-test' - -index: - number_of_replicas: 0 - number_of_shards: 1 - search: - slowlog: - threshold: - query: - warn: 10s - info: 2s - fetch: - warn: 1s - -gateway: - recover_after_nodes: 1 - recover_after_time: 2m - expected_nodes: 1 - -node: - max_local_storage_nodes: 1 - -discovery: - zen: - minimum_master_nodes: 1 - ping: - multicast.enabled: false - unicast.hosts: - - "elasticsearch_test:9300" diff --git a/localapi.env b/localapi.env deleted file mode 100644 index 97514a8..0000000 --- a/localapi.env +++ /dev/null @@ -1,9 +0,0 @@ -NET_ASYNC_HTTP_MAXCONNS=1 -COLUMNS=80 -ES=elasticsearch:9200 -ES_TEST=elasticsearch_test:9200 -ES_TEST=elasticsearch_test:9200 -MINICPAN=/CPAN -PERL_MM_USE_DEFAULT=1 -PERL_CARTON_PATH=/carton -MOJO_MODE=development diff --git a/localapi_test.env b/localapi_test.env index 1f49954..e899080 100644 --- a/localapi_test.env +++ b/localapi_test.env @@ -6,6 +6,5 @@ HARNESS_ACTIVE=1 # Instantiate Catalyst models using metacpan_server_testing.conf METACPAN_SERVER_CONFIG_LOCAL_SUFFIX=testing MINICPAN=/CPAN -PERL_MM_USE_DEFAULT=1 PERL_CARTON_PATH=/carton MOJO_MODE=testing diff --git a/pg/docker-entrypoint-initdb.d/100-roles.sql b/pg/docker-entrypoint-initdb.d/100-roles.sql index 6094210..867939c 100644 --- a/pg/docker-entrypoint-initdb.d/100-roles.sql +++ b/pg/docker-entrypoint-initdb.d/100-roles.sql @@ -1,4 +1,4 @@ -CREATE ROLE metacpan WITH LOGIN PASSWORD 'metacpan'; +CREATE ROLE metacpan WITH LOGIN PASSWORD 't00lchain'; CREATE ROLE "metacpan-api" WITH LOGIN; -- make things easier for when we're poking around from inside the container