Skip to content

Commit

Permalink
ci: docker compose configuration for production
Browse files Browse the repository at this point in the history
  • Loading branch information
josecelano committed Sep 4, 2024
1 parent f8b82e9 commit 0313925
Show file tree
Hide file tree
Showing 8 changed files with 377 additions and 0 deletions.
4 changes: 4 additions & 0 deletions cSpell.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,14 @@
"bitvec",
"btih",
"camino",
"certbot",
"certonly",
"comms",
"Containerfile",
"distroless",
"ikatson",
"infohash",
"letsencrypt",
"librqbit",
"libz",
"metainfo",
Expand All @@ -26,6 +29,7 @@
"thiserror",
"tlsv",
"urlencoding",
"webroot",
"Werror"
],
"enableFiletypes": [
Expand Down
1 change: 1 addition & 0 deletions droplet/.env.production
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
USER_ID=1000
2 changes: 2 additions & 0 deletions droplet/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
.env
storage/
191 changes: 191 additions & 0 deletions droplet/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,191 @@
# Droplet configuration

It's a sample production configuration to deploy the webapp on a Digital Ocean droplet.

## Requirements

- Docker version 24.0.7, build afdd53b.
- Docker Compose version v2.3.3.
- GNU bash, version 5.2.15(1)-release (x86_64-pc-linux-gnu).

## Install

```console
cd \
&& mkdir -p github/torrust \
&& cd torrust/ \
&& git clone --single-branch --branch main https://github.com/torrust/torrust-hash2torrent.git \
&& cd torrust-hash2torrent/ \
&& git status \
&& cd droplet/ \
&& ./bin/install.sh
```

### HTTPS

Get certificates:

Log into the `certbot` container:

```console
docker com1pose run --entrypoint /bin/sh certbot
```

Get staging certificates:

```console
certbot certonly --webroot --webroot-path=/var/www/html --email [email protected] --agree-tos --no-eff-email --staging -d hash2torrent.com
```

Get production certificates:

```console
certbot certonly --webroot --webroot-path=/var/www/html --email [email protected] --agree-tos --no-eff-email --force-renewal -d hash2torrent.com
```

Check that the proxy can see the certificates:

```console
docker compose exec proxy ls -la /etc/letsencrypt/live
```

Generate your key with the openssl command:

```console
sudo openssl dhparam -out /home/torrust/github/torrust/torrust-hash2torrent/droplet/storage/dhparam/dhparam-2048.pem 2048
```

Edit the Nginx config file:

```console
vim ./storage/proxy/etc/nginx-conf/nginx.conf
```

Uncomment the lines for HTTPS servers and recreate the proxy with:

```console
docker compose up -d --force-recreate --no-deps proxy
```

Add the following cronjob with `sudo crontab -e` to auto-renew certificates:

```text
0 12 * * * /home/torrust/github/torrust/torrust-hash2torrent/droplet/bin/ssl_renew.sh >> /var/log/cron.log 2>&1
```

You can check the cronjob output with `tail -n 200 /var/log/cron.log`.

### Storage

This is how the storage folder is configured after installation (including HTTPS).

```console
$ sudo tree storage
storage
├── certbot
│   ├── etc
│   │   ├── accounts
│   │   │   ├── acme-staging-v02.api.letsencrypt.org
│   │   │   │   └── directory
│   │   │   │   └── 2cedba87be07faf5da056edf65b8939f
│   │   │   │   ├── meta.json
│   │   │   │   ├── private_key.json
│   │   │   │   └── regr.json
│   │   │   └── acme-v02.api.letsencrypt.org
│   │   │   └── directory
│   │   │   └── 08ee268c3eef6bf23301b1300bda96e5
│   │   │   ├── meta.json
│   │   │   ├── private_key.json
│   │   │   └── regr.json
│   │   ├── archive
│   │   │   └── hash2torrent.com
│   │   │   ├── cert1.pem
│   │   │   ├── cert2.pem
│   │   │   ├── chain1.pem
│   │   │   ├── chain2.pem
│   │   │   ├── fullchain1.pem
│   │   │   ├── fullchain2.pem
│   │   │   ├── privkey1.pem
│   │   │   └── privkey2.pem
│   │   ├── live
│   │   │   ├── README
│   │   │   └── hash2torrent.com
│   │   │   ├── README
│   │   │   ├── cert.pem -> ../../archive/hash2torrent.com/cert2.pem
│   │   │   ├── chain.pem -> ../../archive/hash2torrent.com/chain2.pem
│   │   │   ├── fullchain.pem -> ../../archive/hash2torrent.com/fullchain2.pem
│   │   │   └── privkey.pem -> ../../archive/hash2torrent.com/privkey2.pem
│   │   ├── renewal
│   │   │   └── hash2torrent.com.conf
│   │   └── renewal-hooks
│   │   ├── deploy
│   │   ├── post
│   │   └── pre
│   └── lib
├── dhparam
│   └── dhparam-2048.pem
├── hash2torrent
│   ├── etc
│   ├── lib
│   │   ├── session
│   │   └── torrents
│   │   └── 443c7602b4fde83d1154d6d9da48808418b181b6.torrent
│   └── log
└── proxy
├── etc
│   └── nginx-conf
│   └── nginx.conf
└── webroot

30 directories, 24 files
```

## Usage

To start the application:

```s
docker compose up --build --detach
```

To stop the application:

```s
docker compose down
```

By default, the application will:

- Be available at <http://localhost:3000>.
- Use the `./storage` directory to store the data.

After starting the application you should see these running containers:

```s
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
03e2f0a66512 nginx:mainline-alpine "/docker-entrypoint.…" 3 hours ago Up 8 minutes 0.0.0.0:80->80/tcp, :::80->80/tcp, 0.0.0.0:443->443/tcp, :::443->443/tcp proxy
5b30ef8ddcd1 torrust/hash2torrent:main "/usr/local/bin/entr…" 3 hours ago Up 3 hours (healthy) 0.0.0.0:3000->3000/tcp, :::3000->3000/tcp, 51000-51010/tcp hash2torrent
```

Other commands are:

Restart all (reloading env vars from `.env` file by forcing recreation):

```console
docker compose up -d --force-recreate
```

Restart proxy (to reload Nginx configuration):

```console
docker compose --ansi never restart proxy
```

Update container images (to upgrade the services):

```console
docker compose down
docker compose pull
docker compose up --build --detach
```
27 changes: 27 additions & 0 deletions droplet/bin/install.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#!/bin/bash

if ! [ -f "./.env" ]; then
echo "Creating compose .env './.env'"
cp .env.production .env
fi

## Proxy

mkdir -p ./storage/proxy/etc/nginx-conf
mkdir -p ./storage/proxy/webroot
mkdir -p ./storage/dhparam

if ! [ -f "./storage/proxy/etc/nginx-conf/nginx.conf" ]; then
echo "Creating proxy config file: './storage/proxy/etc/nginx-conf/nginx.conf'"
cp ./share/container/default/config/nginx.conf ./storage/proxy/etc/nginx-conf/nginx.conf
fi

## Certbot

mkdir -p ./storage/certbot/etc
mkdir -p ./storage/certbot/lib

## hash2torrent

mkdir -p ./storage/hash2torrent/lib/session
mkdir -p ./storage/hash2torrent/lib/torrents
15 changes: 15 additions & 0 deletions droplet/bin/ssl_renew.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#!/bin/bash

COMPOSE="/usr/bin/docker compose --ansi never"
DOCKER="/usr/bin/docker"

cd /home/torrust/github/torrust/hash2torrent/droplet || exit

# Run this just for testing purposes
#$COMPOSE run certbot renew --dry-run && $COMPOSE kill -s SIGHUP proxy

# Renew certificates that are close to expiring and restart proxy server
# to reload Nginx configuration.
$COMPOSE run certbot renew && $COMPOSE --ansi never restart proxy

$DOCKER system prune -af
62 changes: 62 additions & 0 deletions droplet/compose.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
---
name: torrust
services:
certbot:
image: certbot/certbot
container_name: certbot
volumes:
- ./storage/proxy/webroot:/var/www/html
- ./storage/certbot/etc:/etc/letsencrypt
- ./storage/certbot/lib:/var/lib/letsencrypt
logging:
options:
max-size: "10m"
max-file: "10"
depends_on:
- proxy

proxy:
image: nginx:mainline-alpine
container_name: proxy
restart: unless-stopped
networks:
- backend_network
ports:
- "80:80"
- "443:443"
volumes:
- ./storage/proxy/webroot:/var/www/html
- ./storage/proxy/etc/nginx-conf:/etc/nginx/conf.d
- ./storage/certbot/etc:/etc/letsencrypt
- ./storage/certbot/lib:/var/lib/letsencrypt
- ./storage/dhparam:/etc/ssl/certs
logging:
options:
max-size: "10m"
max-file: "10"
depends_on:
- hash2torrent

hash2torrent:
image: torrust/hash2torrent:main
container_name: hash2torrent
tty: true
restart: unless-stopped
environment:
- USER_ID=${USER_ID}
networks:
- backend_network
ports:
- "3000:3000"
- "51000-51010"
volumes:
- ./storage/hash2torrent/lib:/var/lib/torrust/hash2torrent:Z
- ./storage/hash2torrent/log:/var/log/torrust/hash2torrent:Z
- ./storage/hash2torrent/etc:/etc/torrust/hash2torrent:Z
logging:
options:
max-size: "10m"
max-file: "10"

networks:
backend_network: {}
Loading

0 comments on commit 0313925

Please sign in to comment.