Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dockerize this project #53

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
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
61 changes: 61 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
FROM debian:jessie-slim

WORKDIR /root

RUN apt-get update
RUN apt-get -y install build-essential \
libanyevent-httpd-perl \
libdata-uuid-libuuid-perl \
libdatetime-perl \
libdbd-sqlite3-perl \
libdbi-perl \
libemail-address-perl \
libemail-mime-perl \
libhtml-parser-perl \
libhtml-strip-perl \
libhttp-date-perl \
libhttp-tiny-perl \
libimage-size-perl \
libio-socket-ssl-perl \
libencode-imaputf7-perl \
libjson-perl \
libjson-xs-perl \
liblocale-gettext-perl \
libswitch-perl \
libexpat1-dev \
libnet-libidn-perl \
curl \
git \
nginx

RUN cpan; true

RUN perl -MCPAN -e 'my $c = "CPAN::HandleConfig"; $c->load(doit => 1, autoconfig => 1); $c->edit(prerequisites_policy => "follow"); $c->edit(build_requires_install_policy => "yes"); $c->commit'

RUN curl -L -O http://www.cpan.org/authors/id/C/CI/CINDY/AnyEvent-HTTPD-SendMultiHeaderPatch-0.001003.tar.gz && \
tar xf AnyEvent-HTTPD-SendMultiHeaderPatch-0.001003.tar.gz && \
cd AnyEvent-HTTPD-SendMultiHeaderPatch-0.001003 && \
perl Makefile.PL && \
make install

ENV PERLPACKAGES "Test::Requires Mouse AnyEvent::HTTP AnyEvent::HTTPD::CookiePatch AnyEvent::IMAP Cookie::Baker Date::Parse Email::Sender::Simple Email::Sender::Transport::SMTPS HTML::GenerateUtil IO::LockedFile Mail::IMAPTalk Moose Net::CalDAVTalk Net::CardDAVTalk Net::DNS Net::Server::Fork Template"

RUN for PACKAGE in $PERLPACKAGES; do cpan $PACKAGE; done

RUN adduser --quiet --disabled-login --gecos "JMAP" jmap || true
RUN install -o jmap -g jmap -m 755 -d /home/jmap/data
RUN mkdir -p /home/jmap/data

COPY . /home/jmap/jmap-perl

WORKDIR /home/jmap/jmap-perl

RUN rm /etc/nginx/sites-enabled/default

COPY docker/nginx.conf /etc/nginx/sites-enabled/

COPY docker/entrypoint.sh /root/

EXPOSE 80

CMD ["sh", "/root/entrypoint.sh"]
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ PACKAGES= \
libjson-xs-perl \
liblocale-gettext-perl \
libswitch-perl \
libnet-libidn-perl \
nginx \

PERLPACKAGES= \
Expand Down
24 changes: 24 additions & 0 deletions README → README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,27 @@ support the CONDSTORE extension, (RFC4551/RFC7162).

A separate backend for Gmail is provided, because Gmail has native server-side
thread support, meaning that threading does not need to be calculated locally.


Installation
------------

See the [INSTALL](./INSTALL) instructions in this repository.


Run in Docker
-------------

Build a Docker image from this repository using the included [Dockerfile](./Dockerfile):

```
docker build -t local/jmap-perl .
```

Run the JMAP Proxy Docker container:

```
docker run -p 8088:80 --name=jmap-proxy -d local/jmap-perl
```

Now connect to the running proxy via http://localhost:8088
6 changes: 4 additions & 2 deletions bin/apiendpoint.pl
Original file line number Diff line number Diff line change
Expand Up @@ -422,8 +422,9 @@ sub handle_signup {
$force = 1;
}

else {
elsif (not $detail->{imapHost}) {
my $Resolver = Net::DNS::Resolver->new;
$Resolver->tcp_timeout(2);
my $domain = $detail->{username};
$domain =~ s/.*\@//;
my $reply;
Expand Down Expand Up @@ -526,7 +527,8 @@ sub handle_signup {
UseSSL => ($detail->{imapSSL} > 1),
UseBlocking => ($detail->{imapSSL} > 1),
);
die "UNABLE TO CONNECT for $detail->{username}\n" unless $imap;
die "UNABLE TO CONNECT for $detail->{username} @ $detail->{imapHost}\n" unless $imap;
# $imap->set_tracing(1);

my $ok = $imap->login($detail->{username}, $detail->{password});
die "LOGIN FAILED FOR $detail->{username}" unless $ok;
Expand Down
14 changes: 14 additions & 0 deletions docker/entrypoint.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#! /bin/sh

# Find the docker IP
IP=`ip addr | awk '/inet 172/ { print $2 }' | cut -d'/' -f1`
# Replace all occurrence of "proxy.jmap.io" by the docker IP
sed -i "s?https://proxy.jmap.io?http://$IP?g" ./bin/server.pl ./htdocs/landing.html ./JMAP/API.pm ./JMAP/DB.pm
# Or can be occurrence of previous docker IP
sed -i "s?http://172[^/]*?http://$IP?g" ./bin/server.pl ./htdocs/landing.html ./JMAP/API.pm ./JMAP/DB.pm

export jmaphost=$IP

service nginx start
perl ./bin/server.pl &
perl ./bin/apiendpoint.pl
131 changes: 131 additions & 0 deletions docker/nginx.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
server {
listen 80;

root /home/jmap/jmap-perl/htdocs/;
index index.html index.htm;
server_name proxy.jmap.io;

location / {
# First attempt to serve request as file, then
# as directory, then fall back to displaying a 404.
try_files $uri $uri/ /index.html;
}

location = / {
if ( $request_method = 'OPTIONS' ) {
add_header 'Access-Control-Allow-Origin' '*';

# -D GAPING_SECURITY_HOLE
add_header 'Access-Control-Allow-Headers' $http_access_control_request_headers;
add_header 'Access-Control-Allow-Methods' 'POST, GET, OPTIONS';
add_header 'Access-Control-Max-Age' 600;
add_header 'Content-Type' 'text/plain; charset=UTF-8';
add_header 'Content-Length' 0;

return 204;
}

# First attempt to serve request as file, then
# as directory, then fall back to displaying a 404.
proxy_pass http://127.0.0.1:9000/home;
}

location /events/ {
if ( $request_method = 'OPTIONS' ) {
add_header 'Access-Control-Allow-Origin' '*';

# -D GAPING_SECURITY_HOLE
add_header 'Access-Control-Allow-Headers' $http_access_control_request_headers;
add_header 'Access-Control-Allow-Methods' 'POST, GET, OPTIONS';
add_header 'Access-Control-Max-Age' 600;
add_header 'Content-Type' 'text/plain; charset=UTF-8';
add_header 'Content-Length' 0;

return 204;
}

# Immediately send backend responses back to client
proxy_buffering off;

# Disable keepalive to browser
keepalive_timeout 0;

# It's a long lived backend connection with potentially a long time between
# push events, make sure proxy doesn't timeout
proxy_read_timeout 7200;

proxy_pass http://127.0.0.1:9001/events/;
}

location /files/ {
proxy_pass http://127.0.0.1:9000/files/;
}

location /jmap/ {
if ( $request_method = 'OPTIONS' ) {
add_header 'Access-Control-Allow-Origin' '*';

# -D GAPING_SECURITY_HOLE
add_header 'Access-Control-Allow-Headers' $http_access_control_request_headers;
add_header 'Access-Control-Allow-Methods' 'POST, GET, OPTIONS';
add_header 'Access-Control-Max-Age' 600;
add_header 'Content-Type' 'text/plain; charset=UTF-8';
add_header 'Content-Length' 0;

return 204;
}

proxy_pass http://127.0.0.1:9000/jmap/;
}

location /upload/ {
if ( $request_method = 'OPTIONS' ) {
add_header 'Access-Control-Allow-Origin' '*';

# -D GAPING_SECURITY_HOLE
add_header 'Access-Control-Allow-Headers' $http_access_control_request_headers;
add_header 'Access-Control-Allow-Methods' 'POST, GET, OPTIONS';
add_header 'Access-Control-Max-Age' 600;
add_header 'Content-Length' 0;
add_header 'Content-Type' 'text/plain; charset=UTF-8';

return 204;
}

add_header 'Access-Control-Allow-Origin' '*';

proxy_pass http://127.0.0.1:9000/upload/;
}

location /raw/ {
proxy_pass http://127.0.0.1:9000/raw/;
}

location /A {
proxy_pass http://127.0.0.1:9000/A;
}

location /J {
proxy_pass http://127.0.0.1:9000/J;
}

location /U {
proxy_pass http://127.0.0.1:9000/U;
}

location /register {
proxy_pass http://127.0.0.1:9000/register;
}

location /signup {
proxy_pass http://127.0.0.1:9000/signup;
}

location /delete {
proxy_pass http://127.0.0.1:9000/delete;
}

location /cb {
proxy_pass http://127.0.0.1:9000/cb;
}
}