Skip to content

Commit

Permalink
Added cron support
Browse files Browse the repository at this point in the history
  • Loading branch information
Sherex committed Jul 6, 2020
1 parent 83c2966 commit 869a9dd
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 4 deletions.
4 changes: 2 additions & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ USER deno
# These steps will be re-run upon each file change in your working directory:
ADD src/ .
# Compile the main app so that it doesn't need to be compiled each startup/entry.
RUN deno cache index.ts
RUN deno cache index*.ts

# "deno" is entrypoint, so all commands are arguments to deno
CMD [ "run", "--allow-read", "--allow-write", "--allow-net", "--allow-env", "index.ts" ]
CMD [ "run", "--allow-read", "--allow-run", "--allow-env", "index.docker.ts" ]
18 changes: 17 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,20 @@ This project's purpose was mostly to test Deno and learn Typescript (I have a lo
## How to use
[![Docker stats](https://dockeri.co/image/sherex/ddns-client)](https://hub.docker.com/r/sherex/ddns-client/)
### Docker Compose
Use environment variable `DDNS_CRON` to schedule it.

1. Create a `docker-compose.yml` file
```yml
# docker-compose.yml
version: "3.7"
services:
ddns_client:
container_name: ddns-client
environment:
- GD_KEY=YOUR_KEY_HERE
- GD_SECRET=YOUR_SECRET_HERE
- DDNS_CRON=1 */60 * * * *
- DDNS_LOGLEVEL=info
image: sherex/ddns-client:latest
volumes:
- "./config:/app/config"
Expand All @@ -37,10 +44,11 @@ $ docker-compose up # -d # Add '-d' switch to run as daemon
Check out [configuration](#Configuration) further down.

### Docker
Use environment variable `DDNS_CRON` to schedule it.
```sh
# Creates the config directory and places config.json inside
# Replace $PWD with %cd% on Windows
$ docker run -v $PWD/config:/app/config --name ddns-client sherex/ddns-client
$ docker run -v $PWD/config:/app/config -d -e "DDNS_CRON=1 */60 * * * *" --name ddns-client sherex/ddns-client

# Edit 'config/config.json' - I recommend VSCode to use the JSON schema.

Expand Down Expand Up @@ -86,6 +94,14 @@ It can be one of the values (case insensitive):

The default is `info`.

### Cron
The `index.docker.ts` file starts `index.ts` as a subprocess and exits when it's done.
But if you set the environment variable `DDNS_CRON` to a cron string, it will stay running and start `index.ts` every time the cron string matches.

The docker container on [Docker Hub](https://hub.docker.com/r/sherex/ddns-client/) uses this file.

It uses [deno_cron](https://deno.land/x/deno_cron) for the cron jobs.

## TODO
- [X] Move config from .env to config.json
- [X] Use config.json
Expand Down
7 changes: 6 additions & 1 deletion docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@ version: "3.7"
services:
ddns_client:
container_name: ddns-client
image: sherex/ddns-client:latest
environment:
- GD_KEY=YOUR_KEY_HERE
- GD_SECRET=YOUR_SECRET_HERE
- DDNS_CRON=1 */60 * * * *
- DDNS_LOGLEVEL=INFO
build: ./
volumes:
- "./config:/app/config"
46 changes: 46 additions & 0 deletions src/index.docker.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import "https://deno.land/x/dotenv/load.ts";
import { cron, stop, start } from 'https://deno.land/x/deno_cron/cron.ts'
import { log } from './lib/logger.ts'
import { exists } from './lib/exists.ts'

let mainPath = "index.ts"

if (exists("./index.ts") === 'file') mainPath = "./index.ts"
else if (exists("./src/index.ts") === 'file') mainPath = "./src/index.ts"

const cronString = Deno.env.get('DDNS_CRON')
let timesFailed = 0

if (cronString) {
log('info', ["index.docker", "start", "with cron", cronString])

stop()
await run() // Make sure it runs once when started
start()

cron(cronString, () => run())
} else {
stop()
log('info', ["index.docker", "start", "single-run"])
await run()
Deno.exit(0)
}

async function run() {
const process = Deno.run({
cmd: ["deno", "run", "--allow-read", "--allow-write", "--allow-net", "--allow-env", mainPath],
env: Deno.env.toObject()
})
const status = await process.status()
if (status.code === 0) {
timesFailed = 0
log('info', ["index.docker", "success"])
return
} else if (timesFailed < 3) {
timesFailed++
log('error', ["index.docker", "failed", "total times failed", String(timesFailed)])
} else {
log("warn", ["index.docker", "too many failed attempts", String(timesFailed), "exiting"])
Deno.exit(1)
}
}

0 comments on commit 869a9dd

Please sign in to comment.