224 lines
8.3 KiB
Markdown
224 lines
8.3 KiB
Markdown
# Racket Package Library Website
|
|
|
|
## Prerequisites
|
|
|
|
You will need to install the following Racket packages:
|
|
|
|
raco pkg install reloadable
|
|
|
|
## Configuration
|
|
|
|
See the directory `configs/` for example configuration files. To
|
|
select a configuration file, set the environment variable `CONFIG` to
|
|
its base filename. For example, to select `configs/live.rkt`, set
|
|
`CONFIG` to `live`. A good place to do this is in the `run-prelude`
|
|
file; see the description of `run-prelude` below.
|
|
|
|
If `CONFIG` is not set, it defaults to the short hostname of the
|
|
machine (`hostname -s`).
|
|
|
|
Within a configuration file, configuration details are to be given as
|
|
a hashtable to `main`.
|
|
|
|
Keys useful for deployment:
|
|
|
|
- *port*: number; default the value of the `SITE_PORT` environment
|
|
variable, if defined; otherwise, 7443.
|
|
- *ssl?*: boolean; default `#t`.
|
|
- *reloadable?*: boolean; `#t` if the `SITE_RELOADABLE` environment
|
|
variable is defined; otherwise, `#f`.
|
|
- *recent-seconds*: number, in seconds; default 172800. Packages
|
|
modified fewer than this many seconds ago are considered "recent",
|
|
and displayed as such in the UI.
|
|
- *static-output-type*: either `'aws-s3` or `'file`.
|
|
- When `'file`,
|
|
- *static-content-target-directory*: either `#f` or a string
|
|
denoting a path to a folder to which the static content of
|
|
the site will be copied.
|
|
- When `'aws-s3`,
|
|
- *aws-s3-bucket+path*: a string naming an S3 bucket and path.
|
|
Must end with a forward slash, ".../". AWS access keys are
|
|
loaded per the documentation for the `aws` module; usually
|
|
from a file `~/.aws-keys`.
|
|
- *dynamic-urlprefix*: string; absolute or relative URL, prepended to
|
|
URLs targetting dynamic content on the site.
|
|
- *static-urlprefix*: string; absolute or relative URL, prepended to
|
|
relative URLs referring to static HTML files placed in
|
|
`static-generated-directory`.
|
|
- *pkg-index-generated-directory*: a string pointing to where the
|
|
`pkg-index` package places its redered files, to be served
|
|
statically. The source file `static.rkt` in this codebase knows
|
|
precisely which files and directories within
|
|
`pkg-index-generated-directory` to upload to the final site.
|
|
|
|
Keys useful for development:
|
|
|
|
- *package-index-url*: string; default
|
|
`http://pkgs.racket-lang.org/pkgs-all.json.gz`.
|
|
- *package-fetch-interval*; number, in seconds; default 300.
|
|
- *session-lifetime*: number, in seconds; default 604800.
|
|
- *static-generated-directory*: string; names a directory relative to
|
|
`src/` within which generated static HTML files are to be placed.
|
|
Must be writable by the user running the server.
|
|
- *disable-cache?*: boolean; default `#f`.
|
|
- *backend-baseurl*: string; default `https://pkgd.racket-lang.org`.
|
|
Must point to the backend package server API root, such that (for
|
|
example) `/jsonp/authenticate`, when appended to it, resolves to
|
|
the authentication call.
|
|
- *pkg-build-baseurl*: string; default
|
|
`http://pkg-build.racket-lang.org/`. Used to build URLs relative to
|
|
the package build host, for such as documentation links and build
|
|
reports.
|
|
|
|
## Local testing
|
|
|
|
You will need some dummy SSL keys. Run `make keys` to produce some.
|
|
|
|
Running `src/main.rkt` starts a local server. For your convenience,
|
|
|
|
make compile run
|
|
|
|
compiles the code and starts the server.
|
|
|
|
### Automatic code reloading
|
|
|
|
If you would like to enable the automatic code-reloading feature, set
|
|
the environment variable `SITE_RELOADABLE` to a non-empty string or
|
|
set the `reloadable?` configuration variable to `#t`.
|
|
|
|
You must also delete any compiled code `.zo` files. Otherwise, the
|
|
system will not be able to correctly replace modules while running.
|
|
|
|
Therefore, when using automatic code reloading, use just
|
|
|
|
make run
|
|
|
|
and make sure to run `make clean` beforehand, if you've run `make
|
|
compile` at all previously.
|
|
|
|
## Deployment
|
|
|
|
### Static Content
|
|
|
|
The site can be set up to run either
|
|
|
|
0. entirely dynamically, generating package pages on-the-fly for each
|
|
request;
|
|
0. both statically and dynamically, with HTML renderings of package
|
|
pages stored on and served from disk like other static resources
|
|
such as Javascript and CSS; or
|
|
0. both statically and dynamically, as the previous option, but
|
|
additionally replicating both static and generated content to a
|
|
local file-system directory and invoking an optional update hook
|
|
that can be used to further replicate the content to S3 or a
|
|
remote host.
|
|
|
|
The default is mixed static/dynamic, with no additional replication.
|
|
|
|
For a fully dynamic site, set configuration variable `disable-cache?`
|
|
to `#t`.
|
|
|
|
To enable replication, set configuration variable
|
|
`static-content-target-directory` to a non-`#f` value, and optionally
|
|
set `static-content-update-hook` to a string containing a shell
|
|
command to execute every time the static content is updated.
|
|
|
|
#### S3 Content
|
|
|
|
To set up an S3 bucket---let's call it `s3.example`---for use with
|
|
this site, follow these steps:
|
|
|
|
0. Create the bucket ("`s3.example`")
|
|
0. Optionally add a CNAME record to DNS mapping `s3.example` to
|
|
`s3.example.s3-website-us-east-1.amazonaws.com`. If you do, static
|
|
resources will be available at `http://s3.example/`; if not, at
|
|
the longer URL.
|
|
0. Enable "Static Website Hosting" for the bucket. Set the index
|
|
document to `index.html` and the error document to `not-found`.
|
|
|
|
Then, under "Permissions", click "Add bucket policy", and add
|
|
something like the following.
|
|
|
|
{
|
|
"Id": "RacketPackageWebsiteS3Policy",
|
|
"Version": "2012-10-17",
|
|
"Statement": [
|
|
{
|
|
"Sid": "RacketPackageWebsiteS3PolicyStmt1",
|
|
"Action": "s3:*",
|
|
"Effect": "Allow",
|
|
"Resource": ["arn:aws:s3:::s3.example",
|
|
"arn:aws:s3:::s3.example/*"],
|
|
"Principal": {
|
|
"AWS": ["<<<ARN OF THE USER TO WHOM ACCESS SHOULD BE GRANTED>>>"]
|
|
}
|
|
}
|
|
]
|
|
}
|
|
|
|
The user will need to be able to read and write objects and set CORS
|
|
policy. (CORS is configured automatically by code in
|
|
`src/static.rkt`.)
|
|
|
|
### Supervision
|
|
|
|
Startable using djb's [daemontools](http://cr.yp.to/daemontools.html);
|
|
symlink this directory into your services directory and start it as
|
|
usual. The `run` script starts the program, and `log/run` sets up
|
|
logging of stdout/stderr.
|
|
|
|
If the file `run-prelude` exists in the same directory as `run`, it
|
|
will be dotted in before racket is invoked. I use this to update my
|
|
`PATH` to include my locally-built racket `bin` directory, necessary
|
|
because I don't have a system-wide racket, and to select an
|
|
appropriate `CONFIG` setting.
|
|
|
|
On Debian, daemontools can be installed with `apt-get install
|
|
daemontools daemontools-run`, and the services directory is
|
|
`/etc/service/`.
|
|
|
|
### Control signals
|
|
|
|
You can send signals to the running service by creating files in
|
|
`/etc/service/webservice/signals/`. For example:
|
|
|
|
- creating `.pull-required` causes the server to shell out to `git
|
|
pull` and then exit. Daemontools will restart it.
|
|
|
|
- creating `.restart-required` causes it to exit, to be restarted by
|
|
daemontools.
|
|
|
|
- creating `.reload` causes an explicit code reload. Useful when
|
|
automatic code reloading is disabled.
|
|
|
|
- creating `.fetchindex` causes an immediate refetch of the package
|
|
index from the backend server.
|
|
|
|
- creating `.rerender` causes an immediate rerendering of all
|
|
generated static HTML files.
|
|
|
|
See `src/signals.rkt` for details of the available signals.
|
|
|
|
So long as `sudo chmod 0777 /etc/service/webservice/signals`, these
|
|
are useful for non-root administrators to control the running service.
|
|
|
|
In particular, a git `post-receive` hook can be used to create the
|
|
`.pull-required` signal in order to update the service on git push.
|
|
|
|
## Copyright and License
|
|
|
|
Copyright © 2014 Tony Garnock-Jones
|
|
|
|
This program is free software: you can redistribute it and/or modify
|
|
it under the terms of the GNU Lesser General Public License as published by
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
(at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU Lesser General Public License for more details.
|
|
|
|
You should have received a copy of the GNU Lesser General Public License
|
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|