mirror of
https://github.com/gomods/athens
synced 2026-02-03 12:10:32 +00:00
SystemD installation (#1445)
* First implementation; older systemd is not yet supported; SysV is not supported at all * small correction * more documentation; manual testing confirms that Athens is working as a SystemD service * documentation updates * removed differences from author/master branch
This commit is contained in:
committed by
Aaron Schlesinger
parent
5b194688a0
commit
f8bdeb52f6
+2
-1
@@ -19,11 +19,12 @@ tmp/*
|
|||||||
vgp
|
vgp
|
||||||
bin/*
|
bin/*
|
||||||
.envrc
|
.envrc
|
||||||
|
athens
|
||||||
cmd/proxy/proxy
|
cmd/proxy/proxy
|
||||||
|
cmd/proxy/bin
|
||||||
test-keys.json
|
test-keys.json
|
||||||
tmp
|
tmp
|
||||||
.vs
|
.vs
|
||||||
cmd/proxy/bin
|
|
||||||
.idea
|
.idea
|
||||||
.DS_Store
|
.DS_Store
|
||||||
.vscode
|
.vscode
|
||||||
|
|||||||
+42
-6
@@ -27,15 +27,16 @@ GO_BINARY_PATH=go1.11.X
|
|||||||
|
|
||||||
# Run the Proxy
|
# Run the Proxy
|
||||||
|
|
||||||
We provide three ways to run the proxy on your local machine:
|
We provide four ways to run the proxy on your local machine:
|
||||||
|
|
||||||
1. Using [Docker](https://www.docker.com/) and [Docker Compose](https://docs.docker.com/compose/) (_we suggest this one if you're getting started_)
|
1. Using [Docker](https://www.docker.com/) and [Docker Compose](https://docs.docker.com/compose/) (_we suggest this one if you're getting started_)
|
||||||
2. Natively on your host
|
2. Natively on your host as a service (only SystemD is currently supported)
|
||||||
3. Using [Sail](https://sail.dev)
|
3. Natively on your host as a simple binary
|
||||||
|
4. Using [Sail](https://sail.dev)
|
||||||
|
|
||||||
See below for instructions for each option!
|
See below for instructions for each option!
|
||||||
|
|
||||||
## Using Docker
|
## Run Using Docker
|
||||||
|
|
||||||
As we said above, we suggest that you use this approach because it simulates a more realistic Athens deployment. This technique does the following, completely inside containers:
|
As we said above, we suggest that you use this approach because it simulates a more realistic Athens deployment. This technique does the following, completely inside containers:
|
||||||
|
|
||||||
@@ -79,7 +80,42 @@ When you're ready to stop Athens and all its dependencies, run this command:
|
|||||||
$ make run-docker-teardown
|
$ make run-docker-teardown
|
||||||
```
|
```
|
||||||
|
|
||||||
## Natively on Your Host
|
## Run Natively on Your Host as a Service
|
||||||
|
|
||||||
|
There are many service execution environments. On Linux, two important ones are SystemD and SysV, but at the moment only SystemD is supported; others may follow soon. For other systems, please see the next section.
|
||||||
|
|
||||||
|
### SystemD on Linux
|
||||||
|
|
||||||
|
If you're inside GOPATH, make sure `GO111MODULE=on`, if you're outside GOPATH, then Go Modules are on by default.
|
||||||
|
|
||||||
|
The Makefile builds the necessary `athens` binary. Then a script sets up the service for you.
|
||||||
|
|
||||||
|
```console
|
||||||
|
$ make athens
|
||||||
|
$ sudo ./scripts/systemd.sh install
|
||||||
|
```
|
||||||
|
|
||||||
|
After the server starts, you can manage it as usual via `systemctl`, e.g.:
|
||||||
|
|
||||||
|
```console
|
||||||
|
sudo systemctl status athens
|
||||||
|
```
|
||||||
|
which is the same as
|
||||||
|
|
||||||
|
```console
|
||||||
|
$ sudo ./scripts/systemd.sh status
|
||||||
|
```
|
||||||
|
|
||||||
|
The `systemd.sh` script also has a `remove` option to uninstall the service.
|
||||||
|
|
||||||
|
SystemD allows logs to be collected and inspected; more information is in
|
||||||
|
[this tutorial by Digital Ocean](https://www.digitalocean.com/community/tutorials/how-to-use-journalctl-to-view-and-manipulate-systemd-logs), amongst others. So tailing the logs can be done like this:
|
||||||
|
|
||||||
|
```console
|
||||||
|
$ sudo journalctl -u athens --since today --follow
|
||||||
|
```
|
||||||
|
|
||||||
|
## Run Natively on Your Host
|
||||||
|
|
||||||
If you're inside GOPATH, make sure `GO111MODULE=on`, if you're outside GOPATH, then Go Modules are on by default.
|
If you're inside GOPATH, make sure `GO111MODULE=on`, if you're outside GOPATH, then Go Modules are on by default.
|
||||||
|
|
||||||
@@ -97,7 +133,7 @@ After the server starts, you'll see some console output like:
|
|||||||
Starting application at 127.0.0.1:3000
|
Starting application at 127.0.0.1:3000
|
||||||
```
|
```
|
||||||
|
|
||||||
## Using Sail
|
## Run Using Sail
|
||||||
|
|
||||||
Follow instructions at [sail.dev](https://sail.dev) to setup the sail CLI. Then simply run:
|
Follow instructions at [sail.dev](https://sail.dev) to setup the sail CLI. Then simply run:
|
||||||
|
|
||||||
|
|||||||
@@ -9,9 +9,13 @@ endif
|
|||||||
build: ## build the athens proxy
|
build: ## build the athens proxy
|
||||||
cd cmd/proxy && go build
|
cd cmd/proxy && go build
|
||||||
|
|
||||||
|
.PHONY: build-ver
|
||||||
build-ver: ## build the athens proxy with version number
|
build-ver: ## build the athens proxy with version number
|
||||||
GO111MODULE=on CGO_ENABLED=0 GOPROXY="https://proxy.golang.org" go build -ldflags "-X github.com/gomods/athens/pkg/build.version=$(VERSION) -X github.com/gomods/athens/pkg/build.buildDate=$(DATE)" -o athens ./cmd/proxy
|
GO111MODULE=on CGO_ENABLED=0 GOPROXY="https://proxy.golang.org" go build -ldflags "-X github.com/gomods/athens/pkg/build.version=$(VERSION) -X github.com/gomods/athens/pkg/build.buildDate=$(DATE)" -o athens ./cmd/proxy
|
||||||
|
|
||||||
|
athens:
|
||||||
|
$(MAKE) build-ver
|
||||||
|
|
||||||
# The build-image step creates a docker image that has all the tools required
|
# The build-image step creates a docker image that has all the tools required
|
||||||
# to perform some CI build steps, instead of relying on them being installed locally
|
# to perform some CI build steps, instead of relying on them being installed locally
|
||||||
.PHONY: build-image
|
.PHONY: build-image
|
||||||
@@ -110,6 +114,10 @@ down:
|
|||||||
dev-teardown:
|
dev-teardown:
|
||||||
docker-compose -p athensdev down -v
|
docker-compose -p athensdev down -v
|
||||||
|
|
||||||
|
.PHONY: clean
|
||||||
|
clean: ## delete all locally-built artefacts (not including docker images)
|
||||||
|
rm -f athens cmd/proxy/proxy
|
||||||
|
|
||||||
.PHONY: help
|
.PHONY: help
|
||||||
help: ## display help page
|
help: ## display help page
|
||||||
@grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}'
|
@grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}'
|
||||||
|
|||||||
@@ -0,0 +1,65 @@
|
|||||||
|
[Unit]
|
||||||
|
Description=Athens Go module proxy
|
||||||
|
Documentation=https://docs.gomods.io/
|
||||||
|
After=network-online.target
|
||||||
|
Wants=network-online.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Restart=on-abnormal
|
||||||
|
Nice=5
|
||||||
|
;StartLimitInterval=86400
|
||||||
|
;StartLimitBurst=5
|
||||||
|
|
||||||
|
; User and group the process will run as.
|
||||||
|
User=www-data
|
||||||
|
Group=www-data
|
||||||
|
|
||||||
|
Environment=ATHENS_DISK_STORAGE_ROOT=/var/run/athens
|
||||||
|
|
||||||
|
; The full path and the arguments of the command to be executed to start the process.
|
||||||
|
ExecStart=/usr/local/bin/athens -config_file=/etc/athens/config.toml
|
||||||
|
|
||||||
|
; The command necessary to stop the service.
|
||||||
|
;ExecStop=/bin/kill -INT $MAINPID
|
||||||
|
|
||||||
|
; The command necessary to reload the configuration of the service if available.
|
||||||
|
;ExecReload=/bin/kill -USR1 $MAINPID
|
||||||
|
|
||||||
|
; Use graceful shutdown with a reasonable timeout
|
||||||
|
KillMode=mixed
|
||||||
|
KillSignal=SIGINT
|
||||||
|
TimeoutStopSec=5s
|
||||||
|
|
||||||
|
; Limit the number of file descriptors; see `man systemd.exec` for more limit settings.
|
||||||
|
LimitNOFILE=1048576
|
||||||
|
; Unmodified athens is not expected to use more than that.
|
||||||
|
LimitNPROC=512
|
||||||
|
|
||||||
|
; Use private /tmp and /var/tmp, which are discarded after athens stops.
|
||||||
|
PrivateTmp=true
|
||||||
|
|
||||||
|
; Use a minimal /dev
|
||||||
|
PrivateDevices=true
|
||||||
|
|
||||||
|
; Prevent alteration of /home, /root, and /run/user.
|
||||||
|
ProtectHome=read-only
|
||||||
|
|
||||||
|
; Make /usr, /boot, /etc and possibly some more folders read-only.
|
||||||
|
ProtectSystem=full
|
||||||
|
|
||||||
|
; … except /var/run/athens, because we want disk storage here
|
||||||
|
; This merely retains r/w access rights, it does not add any new. Must still be writable on the host!
|
||||||
|
ReadWritePaths=/var/run/athens
|
||||||
|
|
||||||
|
; The following additional security directives only work with systemd v229 or later.
|
||||||
|
; They further retrict privileges that can be gained by athens. Uncomment if you like.
|
||||||
|
; Note that you may have to add capabilities required by any plugins in use.
|
||||||
|
CapabilityBoundingSet=CAP_NET_BIND_SERVICE
|
||||||
|
AmbientCapabilities=CAP_NET_BIND_SERVICE
|
||||||
|
NoNewPrivileges=true
|
||||||
|
|
||||||
|
; Ensure /var/log subdirectories are available. This is a space-separated list.
|
||||||
|
;LogsDirectory=
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
Executable
+173
@@ -0,0 +1,173 @@
|
|||||||
|
#!/bin/bash -e
|
||||||
|
# This script manages installation using SystemD, if available, or SysV as a fall-back.
|
||||||
|
#
|
||||||
|
# Usage:
|
||||||
|
# systemd.sh [ install | remove | status | log ]
|
||||||
|
|
||||||
|
cd $(dirname $0)/..
|
||||||
|
[[ -n $VERSION ]] || export VERSION=unset
|
||||||
|
|
||||||
|
function ensureSystemdIsPresent
|
||||||
|
{
|
||||||
|
if [[ $( uname -s ) != "Linux" ]]; then
|
||||||
|
echo "SystemD can only be used on Linux systems."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
id=$(uname -msn)
|
||||||
|
|
||||||
|
if command -v systemctl >/dev/null; then
|
||||||
|
echo -n "$id has "
|
||||||
|
systemctl --version | head -1
|
||||||
|
|
||||||
|
elif [ -d /etc/init.d ]; then
|
||||||
|
echo "$id has SysV."
|
||||||
|
|
||||||
|
else
|
||||||
|
echo "Neither SystemD nor SysV is available in this operating system."
|
||||||
|
lsb_release -a
|
||||||
|
exit 1
|
||||||
|
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# doInstallConfig installs the config file
|
||||||
|
function doInstallConfig
|
||||||
|
{
|
||||||
|
if [ ! -r config.toml ]; then
|
||||||
|
echo "Missing: config.toml"
|
||||||
|
echo "Copy & modify config.dev.toml as needed."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
sudo mkdir -p /etc/athens
|
||||||
|
sudo install -v -o root -g root -m 644 config.toml /etc/athens
|
||||||
|
|
||||||
|
# if storage is on disk, this is where the database goes (see scripts/service/athens.service)
|
||||||
|
ATHENS_DISK_STORAGE_ROOT=/var/run/athens
|
||||||
|
sudo mkdir -p $ATHENS_DISK_STORAGE_ROOT
|
||||||
|
sudo chown www-data $ATHENS_DISK_STORAGE_ROOT
|
||||||
|
sudo chgrp www-data $ATHENS_DISK_STORAGE_ROOT
|
||||||
|
}
|
||||||
|
|
||||||
|
# doInstallBinary copies the Athens binary to /usr/local/bin with the necessary settings.
|
||||||
|
function doInstallBinary
|
||||||
|
{
|
||||||
|
[ -f athens ] || make athens
|
||||||
|
|
||||||
|
if [ ! -x /usr/local/bin/athens -o athens -nt /usr/local/bin/athens ]; then
|
||||||
|
|
||||||
|
[ -f /etc/systemd/system/athens.service ] && sudo systemctl stop athens
|
||||||
|
[ -f /etc/init.d/athens ] && sudo /etc/init.d/athens stop
|
||||||
|
|
||||||
|
sudo install -v -o root -g root athens /usr/local/bin
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Give the athens binary the ability to bind to privileged ports (e.g. 80, 443) as a non-root user:
|
||||||
|
command -v setcap >/dev/null && sudo setcap 'cap_net_bind_service=+ep' /usr/local/bin/athens
|
||||||
|
}
|
||||||
|
|
||||||
|
# doInstallSystemd sets up the SystemD service unit.
|
||||||
|
function doInstallSystemd
|
||||||
|
{
|
||||||
|
sudo install -v -o root -g root -m 644 scripts/service/athens.service /etc/systemd/system
|
||||||
|
sudo systemctl daemon-reload
|
||||||
|
sudo systemctl enable athens
|
||||||
|
sudo systemctl start athens
|
||||||
|
}
|
||||||
|
|
||||||
|
# doInstall builds and installs the binary as a SystemD unit
|
||||||
|
function doInstall
|
||||||
|
{
|
||||||
|
doInstallConfig
|
||||||
|
doInstallBinary
|
||||||
|
doInstallSystemd
|
||||||
|
}
|
||||||
|
|
||||||
|
# doRemove deletes the SystemD unit and cleans up log files etc
|
||||||
|
function doRemove
|
||||||
|
{
|
||||||
|
if [ -f /etc/systemd/system/athens.service ]; then
|
||||||
|
sudo systemctl stop athens
|
||||||
|
sudo rm -f /etc/systemd/system/athens.service
|
||||||
|
# Reset systemctl
|
||||||
|
sudo systemctl daemon-reload
|
||||||
|
echo "SystemD installation was removed."
|
||||||
|
|
||||||
|
elif [ -f /etc/init.d/athens ]; then
|
||||||
|
sudo service athens stop
|
||||||
|
sudo update-rc.d athens remove
|
||||||
|
sudo rm -f /etc/init.d/athens
|
||||||
|
echo "SysV installation was removed."
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
sudo rm -rf /etc/athens /etc/ssl/athens /usr/local/bin/athens /var/log/athens.log /var/www/.athens
|
||||||
|
}
|
||||||
|
|
||||||
|
# doStatus shows what is installed, if anything, and whether it is running
|
||||||
|
function doStatus
|
||||||
|
{
|
||||||
|
if [ -x /usr/local/bin/athens ]; then
|
||||||
|
echo "Athens is /usr/local/bin/athens"
|
||||||
|
/usr/local/bin/athens --version
|
||||||
|
else
|
||||||
|
echo "Athens is absent (no /usr/local/bin/athens)."
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -f /etc/systemd/system/athens.service ]; then
|
||||||
|
echo
|
||||||
|
echo "SystemD: /etc/systemd/system/athens.service exists."
|
||||||
|
sudo systemctl status athens ||:
|
||||||
|
|
||||||
|
elif [ -f /etc/init.d/athens ]; then
|
||||||
|
echo
|
||||||
|
echo "SysV: /etc/init.d/athens exists."
|
||||||
|
sudo service athens status ||:
|
||||||
|
|
||||||
|
else
|
||||||
|
echo "Athens is not installed as a service."
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# showLog shows the relevant lines in syslog
|
||||||
|
function showLog
|
||||||
|
{
|
||||||
|
if [ -x /usr/local/bin/athens ]; then
|
||||||
|
echo "Athens is /usr/local/bin/athens"
|
||||||
|
/usr/local/bin/athens --version
|
||||||
|
else
|
||||||
|
echo "Athens is absent (no /usr/local/bin/athens)."
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -f /etc/systemd/system/athens.service ]; then
|
||||||
|
fgrep athens /var/log/syslog | fgrep "$(date '+%b %d')"
|
||||||
|
|
||||||
|
elif [ -f /etc/init.d/athens ]; then
|
||||||
|
fgrep athens /var/log/syslog | fgrep "$(date '+%b %d')"
|
||||||
|
|
||||||
|
else
|
||||||
|
echo "Athens is not installed as a service."
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
### Main script ###doStatus
|
||||||
|
|
||||||
|
case $1 in
|
||||||
|
install)
|
||||||
|
ensureSystemdIsPresent; doInstall ;;
|
||||||
|
|
||||||
|
remove|uninstall)
|
||||||
|
ensureSystemdIsPresent; doRemove ;;
|
||||||
|
|
||||||
|
status)
|
||||||
|
ensureSystemdIsPresent; doStatus ;;
|
||||||
|
|
||||||
|
log)
|
||||||
|
ensureSystemdIsPresent; showLog ;;
|
||||||
|
|
||||||
|
*)
|
||||||
|
echo "Usage: $0 [ install | remove | status | log"
|
||||||
|
exit 1 ;;
|
||||||
|
esac
|
||||||
Reference in New Issue
Block a user