Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ pm_to_blib
mailer.testfile
privatelib
cover_db
docker-compose/tmp/
29 changes: 29 additions & 0 deletions Containerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
FROM perl:5.42-bookworm

RUN apt-get update \
&& apt-get install -y --no-install-recommends \
libdb-dev libexpat1-dev libgetopt-long-descriptive-perl libpath-tiny-perl libsasl2-modules zlib1g-dev unzip tree vim \
&& rm -fr /var/cache/apt/* /var/lib/apt/lists/*

RUN useradd -m --shell /bin/bash pause
WORKDIR /home/pause

COPY cpanfile cpanfile
RUN cpm install -g

COPY docker-compose/setup.sh /setup.sh
RUN /setup.sh

USER pause

COPY --chown=pause docker-compose/PrivatePAUSE.pm privatelib/PrivatePAUSE.pm
COPY --chown=pause t t
COPY --chown=pause doc doc
COPY --chown=pause htdocs htdocs
COPY --chown=pause cron cron
COPY --chown=pause bin bin
COPY --chown=pause lib lib
COPY --chown=pause app_2017.psgi app_2017.psgi
COPY --chown=pause app_2026.psgi app_2026.psgi

CMD ["plackup","app_2026.psgi"]
117 changes: 117 additions & 0 deletions doc/local-dev-docker-compose.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@

# Local development using docker-compose

To make local development easier, we now provide a container based setup orchestrated using `docker compose`. This setup is for local development only, **do not** use it for a production or even staging environment!

## Prerequisites

You will need:

* docker with `docker compose`

## Overview

* `docker compose up`
* Go to `http://pause.localhost:8080`
* It might happen that your browser redirects to `https://pause.localhost:8080`, which won't work. If this happens, adjust the protocol in the browser address bar and reload.
* Login with userid `testuser`, password `test`
* Play around with it!
* Read mail sent by PAUSE at `http://localhost:8025`
* `docker compose down`

The setup will persist after `docker compose down`.

## Running

### Start

To start the whole stack, do

`docker compose up`

This should fetch or build the required containers, set up an empty database and start the web app (`pause`) and `paused`.

If you have changed the `Containerfile` or `cpanfile`, rebuild the image first:

`docker compose up --build`

To see less output, list the specific services you want to see, eg

`docker compose up pause paused`

### Access the container(s)

* If the container is already running (started via `up`):
* `docker compose exec {{container-name}} {{comand}}`
* eg `docker compose exec pause bash`
* If it is not running:
* `docker compose run --rm -ti {{container-name}} {{command}}`
* `docker compose run --rm -ti paused cat /etc/passwd`

To inspect files inside the container, access the container and look around there.

To copy files from the container to the host (eg for more detailed analysis), copy it to `/pause-run/tmp`, which is mounted to `docker-compose/tmp/`:

```
~/perl/pause$ d-c exec pause bash
pause@bb2bd8edaad0:~$ echo "Hello" > /pause-run/tmp/foo
pause@bb2bd8edaad0:~$ exit
~/perl/pause$ ls docker-compose/tmp/
foo
```

### Stop

`docker compose down`

### Resetting

The current setup persists data between restarts. This applies to the DB and to files stored in `/data/pause` and `/pause-run`.

To reset those files (for a complete fresh start), do:

```
docker compose stop
docker compose down
docker volume rm pause_mysql_db # deletes the database
docker volume rm pause_pause_data # deletes /data
docker volume rm pause_pause_run # deletes /pause-run
```

The next `docker compose up` will set up a fresh database and empty directories.

## Services

### pause

The `pause` Plack app (currently `app_2017`) providing the web interface. Runs on port 5000 inside the container. But you should use the `nginx` proxy (see below).

### paused

The PAUSE daemon handling uploads. Logs to `/pause-run/log/paused.log`.

To tail the log from the host, do:

`docker compose exec paused tail -f /pause-run/log/paused.log`

### mysql

The mysql database server. It contains the PAUSE schema, 3 test users, but no further data. Data will persist between restart of the service.

To connect to the database from the host, do:

`docker compose exec mysql mysql -uroot -ptest pause`

To reset the DB, stop all services (`docker compose down`) and delete the volume:

`docker volume rm pause_mysql_db`

### nginx

A nginx frontend proxy. Currently only for serving static files, but could be used in the future to terminate some semi-fake SSL for testing.

### mail

An instance of [mailpit](https://mailpit.axllent.org/). This is a combined SMTP server (listening on port 1025 for incoming email) and webmail (on port 8025). `pause` can send email to `mailpit`, and you can read the mail on `http://localhost:8025`. No mail will actually leave your system!


67 changes: 67 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
services:
pause: &pause
build:
context: ./
dockerfile: Containerfile
ports:
- 5000:5000
volumes:
- ./docker-compose/PrivatePAUSE.pm:/home/pause/privatelib/PrivatePAUSE.pm
- ./docker-compose/tmp:/pause-run/tmp
- ./lib:/home/pause/lib
- ./bin:/home/pause/bin
- pause_run:/pause-run
- pause_data:/data
environment:
PAUSE_DEV_ROOT: /home/pause
PAUSE_DEV_EMAIL: pause@localhost.localdomain
PAUSE_DEV_DBUSER: pause
PAUSE_DEV_DBPASS: test
EMAIL_SENDER_TRANSPORT: SMTP
EMAIL_SENDER_TRANSPORT_host: mail
EMAIL_SENDER_TRANSPORT_port: 1025
depends_on:
- mysql
- mail
command: plackup -p 5000 -R /home/pause/lib/pause_2026 app_2026.psgi
paused:
<<: *pause
ports: []
command: bin/paused --pidfile /pause-run/pid/paused.pid
mysql:
image: mysql:5.7
container_name: mysql
volumes:
- ./doc/mod.schema.txt:/docker-entrypoint-initdb.d/01_mod.schema.sql
- ./doc/authen_pause.schema.txt:/docker-entrypoint-initdb.d/02_authen_pause.schema.sql
- ./docker-compose/mysql/03_fixtures.sql:/docker-entrypoint-initdb.d/03_fixtures.sql
- mysql_db:/var/lib/mysql
environment:
MYSQL_ROOT_PASSWORD: test
MYSQL_USER: pause
MYSQL_PASSWORD: test
MYSQL_DATABASE: pause
expose:
- 3306
mail:
image: axllent/mailpit
ports:
- 1025:1025
- 8025:8025
environment:
MP_MAX_MESSAGES: 100
MP_SMTP_AUTH_ACCEPT_ANY: 1
MP_SMTP_AUTH_ALLOW_INSECURE: 1
nginx:
image: nginx:latest
ports:
- 8080:8080
depends_on:
- pause
volumes:
- ./htdocs:/var/www/html/
- ./docker-compose/nginx/default.conf:/etc/nginx/conf.d/default.conf
volumes:
mysql_db:
pause_run:
pause_data:
52 changes: 52 additions & 0 deletions docker-compose/PrivatePAUSE.pm
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package PrivatePAUSE;
use File::Spec::Functions qw(catdir catfile);
use Email::Sender::Simple;

my $Root = $ENV{PAUSE_DEV_ROOT} // '/home/pause';
my $Email = $ENV{PAUSE_DEV_EMAIL} // 'pause@localhost.localdomain';

print STDERR "ENV: $_: $ENV{$_}\n" for sort keys %ENV;

print STDERR "Root: $Root\n";
print STDERR "Email: $Email\n";

$PAUSE::Config->{AUTHEN_DATA_SOURCE_NAME} = 'dbi:mysql:pause;host=mysql';
$PAUSE::Config->{AUTHEN_DATA_SOURCE_USER} = 'pause';
$PAUSE::Config->{AUTHEN_DATA_SOURCE_PW} = 'test';

$PAUSE::Config->{MOD_DATA_SOURCE_NAME} = 'dbi:mysql:pause;host=mysql';
$PAUSE::Config->{MOD_DATA_SOURCE_USER} = 'pause';
$PAUSE::Config->{MOD_DATA_SOURCE_PW} = 'test';

$PAUSE::Config->{DOCUMENT_ROOT} = catdir($Root, 'htdocs');
$PAUSE::Config->{ADMIN} = $Email;
$PAUSE::Config->{ADMINS} = [$Email];
$PAUSE::Config->{CPAN_TESTERS} = $Email;
$PAUSE::Config->{TO_CPAN_TESTERS} = $Email;
$PAUSE::Config->{REPLY_TO_CPAN_TESTERS} = $Email;
$PAUSE::Config->{GONERS_NOTIFY} = $Email;
$PAUSE::Config->{P5P} = $Email;
$PAUSE::Config->{ML_CHOWN_USER} = 'nobody';
$PAUSE::Config->{ML_CHOWN_GROUP} = 'nogroup';
$PAUSE::Config->{ML_MIN_INDEX_LINES} = 0;
$PAUSE::Config->{ML_MIN_FILES} = 0;
$PAUSE::Config->{RUNDATA} = '/pause-run/rundata';
$PAUSE::Config->{UPLOAD} = $Email;
$PAUSE::Config->{HAVE_PERLBAL} = 0;
$PAUSE::Config->{SLEEP} = 1;
$PAUSE::Config->{PAUSE_LOG} = '/pause-run/log/paused.log';
$PAUSE::Config->{PAUSE_LOG_DIR} = '/pause-run/log/';
$PAUSE::Config->{INCOMING} = 'file://data/pause/incoming/';
$PAUSE::Config->{RECAPTCHA_ENABLED} = 1 unless $ENV{TEST_HARNESS};
$PAUSE::Config->{CHECKSUMS_SIGNING_ARGS} = '--homedir /root/.gnupg --clearsign --default-key';
$PAUSE::Config->{CHECKSUMS_SIGNING_KEY} = 'A34B1DABBB49489C';
$PAUSE::Config->{BATCH_SIG_HOME} = '/root/.gnupg';

$PAUSE::Config->{TESTHOST_SCHEMA} = 'http';
$PAUSE::Config->{CRONPATH} = '/home/pause/cron';

$PAUSE::Config->{SKIP_GIT} = 1;
$PAUSE::Config->{CHECKSUMS_SIGNING_PROGRAM} = 'false';

1;

6 changes: 6 additions & 0 deletions docker-compose/mysql/03_fixtures.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
INSERT INTO `grouptable` VALUES ('TESTADMIN','admin');

INSERT INTO `users` VALUES ('TESTADMIN','unused','1970-01-01 00:00:00','testadmin@localhost','secr','','TESTADMIN Name',NULL,'',NULL,NULL,''),('TESTCNSRD','unused','1970-01-01 00:00:00','CENSORED','secr','','TESTCNSRD Name',NULL,'',NULL,NULL,''),('TESTUSER','unused','1970-01-01 00:00:00','testuser@localhost','secr','','TESTUSER Name',NULL,'',NULL,NULL,'');

INSERT INTO `usertable` VALUES ('TESTADMIN','$2a$12$CoQEZPZVEzqlkQWPzzQTses.eK86BVM07tjtWCywrPGnbLsc/0eTC','testadmin@localhost',0,NULL,NULL,NULL),('TESTCNSRD','$2a$12$zV/qZSD4Oa6uB4onl0b/6uA0yrcELZWebBCZOeX0T9rlmD97qXWj6','testcnsrd@localhost',0,NULL,NULL,NULL),('TESTUSER','$2a$12$Xq5nX/5AI4y/lbPC/wHbIeTpGXY76u8F8go90i03umhwRpG0bjtG2','testuser@localhost',0,NULL,NULL,NULL);

46 changes: 46 additions & 0 deletions docker-compose/nginx/default.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
upstream psgi {
server pause:5000;
}

server {
listen 8080;
listen [::]:8080;
server_name pause.localhost;

root /var/www/html;

location ~ /pause/.*\.(js|css|jpg|gif|png) {
expires 7d;
break;
}

location /incoming/ {
root /home/ftp;
autoindex on;
autoindex_exact_size off;
autoindex_localtime on;
}

location /pub/ {
root /home/ftp;
autoindex on;
autoindex_exact_size off;
autoindex_localtime on;
}

location / {
proxy_pass http://psgi;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Port $server_port;
proxy_set_header X-Forwarded-Proto $scheme;

proxy_pass_request_headers on;
proxy_no_cache $cookie_nocache $arg_nocache$arg_comment;
proxy_no_cache $http_pragma $http_authorization;
proxy_cache_bypass $cookie_nocache $arg_nocache $arg_comment;
proxy_cache_bypass $http_pragma $http_authorization;
proxy_pass_header Authorization;
}
}
21 changes: 21 additions & 0 deletions docker-compose/setup.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#!/bin/bash
set -e

mkdir -p \
/pause-run/tmp \
/pause-run/pid \
/pause-run/log \
/pause-run/rundata/session

mkdir -p \
/data/pause/ftp \
/data/pause/tmp \
/data/pause/incoming \
/data/pause/pub/PAUSE/PAUSE-git \
/data/pause/pub/PAUSE/PAUSE-data \
/data/pause/pub/PAUSE/modules \
/data/pause/pub/PAUSE/authors/id

chown -R pause: /pause-run
chown -R pause: /data

1 change: 1 addition & 0 deletions docker-compose/tmp/readme
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
placeholder so we can track this file in git
Loading