Code Monkey home page Code Monkey logo

https-portal's Introduction

HTTPS-PORTAL

HTTPS-PORTAL is a fully automated HTTPS server powered by Nginx, Let's Encrypt and Docker. By using it, you can run any existing web application over HTTPS, with only one extra line of configuration.

The SSL certificates are obtained, and renewed from Let's Encrypt automatically.

Docker Hub page: https://hub.docker.com/r/steveltn/https-portal/

Japanese README

Thanks to @yamada28go, there is a Japanese version of this README available. However, due to my inability to understand Japanese, I can't guarantee that the Japanese version is up-to-date.

Table of Contents

Prerequisite

HTTPS-PORTAL is shipped as a Docker image. To use it, you need a Linux machine (either local or remote host) which:

  • Has 80 and 443 port available and exposed.
  • Has Docker Engine installed. In addition, Docker Compose is highly recommended, for it makes your life easier. Examples in our documents are mainly in Docker Compose format.
  • Has all domains you're going to use in the following examples resolving to it.

Though it is good to have, knowledge about Docker is not required to use HTTPS-PORTAL.

See It Work

Create a docker-compose.yml file with the following content in any directory of your choice:

version: '3'

services:
  https-portal:
    image: steveltn/https-portal:1
    ports:
      - '80:80'
      - '443:443'
    environment:
      DOMAINS: 'example.com'
      # STAGE: 'production' # Don't use production until staging works
    volumes:
      - https-portal-data:/var/lib/https-portal

volumes:
    https-portal-data: # Recommended, to avoid re-signing when upgrading HTTPS-PORTAL

Run the docker-compose up command in the same directory. A moment later you'll have a welcome page running in https://example.com.

Quick Start

Here is a more real-world example: Create the file docker-compose.yml in another directory:

version: '3'

https-portal:
  image: steveltn/https-portal:1
  ports:
    - '80:80'
    - '443:443'
  restart: always
  environment:
    DOMAINS: 'wordpress.example.com -> http://wordpress:80'
    # STAGE: 'production' # Don't use production until staging works
    # FORCE_RENEW: 'true'
  volumes: 
    - https-portal-data:/var/lib/https-portal

wordpress:
  image: wordpress

db:
  image: mariadb
  environment:
    MYSQL_ROOT_PASSWORD: '<a secure password>'

volumes:
  https-portal-data:

Run the docker-compose up -d command. A moment later you'll get a WordPress running on https://wordpress.example.com.

In the example above, only the environment variables under the https-portal section are HTTPS-PORTAL specific configurations. This time we added an extra parameter -d, which will tell Docker Compose to run the apps defined in docker-compose.yml in the background.

Note:

  • STAGE is staging by default, which results in a test (untrusted) certificate from Let's Encrypt.
  • wordpress is the hostname of WordPress container within HTTPS-PORTAL container. Usually you can use the service name of your WordPress container.

Features

Test Locally

You can test HTTPS-PORTAL with your application stack locally.

https-portal:
  # ...
  environment:
    STAGE: local
    DOMAINS: 'example.com'

By doing this, HTTPS-PORTAL will create a self-signed certificate. This certificate is not likely to be trusted by your browser, but you can use it to test your docker-compose file. Make sure it works with your application stack.

Note that HTTPS-PORTAL only listens to example.com, as you specified in the compose file. In order to make HTTPS-PORTAL respond to your connection, you need to either:

  • modify your hosts file to have example.com resolving to your docker host to 127.0.0.1 (or any other IP address pointing to your Docker host),

or

  • set up DNSMasq on your computer/router. This method provides more flexibility.

or

  • configure DOMAINS: 'mysite.lvh.me in docker-compose.yml instead of example.com (lvh.me is a wildcard DNS entry that resolves any second level name to 127.0.0.1) so than you can access https://mysite.lvh.me.

Once you are done testing, you can deploy your application stack to the server.

Redirections

HTTPS-PORTAL support quick setup for redirections.

https-portal:
  # ...
  environment:
    DOMAINS: 'example.com => https://target.example.com' # Notice it's "=>" instead of the normal "->"

All paths will be redirected to the target. E.g. https://example.com/foo/bar will be 307 redirected to https://target.example.com/foo/bar.

If you want a permanent redirection, set the environment variable REDIRECT_CODE=301.

A common use case is to redirect www.example.com to example.com. Configure your DNS, make both www.example.com and example.com resolve to the HTTPS-PORTAL host, and use the following compose:

https-portal:
  # ...
  environment:
    DOMAINS: 'www.example.com => https://example.com' # Notice it's "=>" instead of the normal "->"

Automatic Container Discovery

WARNING: WE STRONGLY RECOMMEND AGAINST USING THIS FEATURE UNLESS ABSOLUTELY NECESSARY as exposing Docker socket to a container (even with :ro) essentially gives the container root access to your host OS. If you insist, verify the source code carefully. Read more

HTTPS-PORTAL is capable of discovering other Docker containers running on the same host, as long as the Docker API socket is accessible within the container.

In order to make it so, launch HTTPS-PORTAL using the following docker-compose.yml.

version: '2'

services:
  https-portal:
    # ...
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro # DANGEROUS, see the warning above

and launch one or more web applications with:

version: '2'

services:
  a-web-application:
    # ...
    environment:
      # tell HTTPS-PORTAL to set up "example.com"
      VIRTUAL_HOST: example.com

Caveat: Your web application must be created in the same network as HTTPS-PORTAL.

Note that here is no need to link your web service to HTTPS-PORTAL, and you shouldn't put example.com in environment variable DOMAINS of HTTPS-PORTAL.

This feature allows you to deploy multiple web applications on the same host without restarting HTTPS-PORTAL itself or interrupting any other application while adding/removing web applications.

If your web service has more than one port exposed (mind that ports can be exposed in your web service Dockerfile), use the environment variable VIRTUAL_PORT to specify which port accepts HTTP requests:

a-multi-port-web-application:
  # ...
  expose:
    - '80'
    - '8080'
  environment:
    VIRTUAL_HOST: example.com
    VIRTUAL_PORT: '8080'

Of course container discovery works in combination with ENV specified domains:

https-portal:
  # ...
  volumes:
    - /var/run/docker.sock:/var/run/docker.sock:ro # DANGEROUS, see the warning above
  environment:
    DOMAINS: 'example.com -> http://upstream'

Hybrid Setup with Non-Dockerized Apps

Web applications that run directly on the host machine instead of in Docker containers are available at host.docker.internal. It also works with Docker for Mac and Docker for Windows.

For instance, if an application accepts HTTP requests on port 8080 of the host machine, you can start HTTPS-PORTAL by:

https-portal:
  # ...
  environment:
    DOMAINS: 'example.com -> http://host.docker.internal:8080'

Firewall settings

If you use a firewall like ufw, you might need to allow communication from the container to your docker host machine. You can check if ufw is active by executing ufw status.

If the command returns active, add the ufw rule to allow communication on port 8080 from HTTPS-PORTAL's container IP to the docker host IP on the port where the web application is reachable:

DOCKER_HOST_IP=`docker network inspect code_default --format='{{ .IPAM.Config}}' |awk '{print $2}'` # Assumes that the network is named code_default
HTTPS_PORTAL_IP=`docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' code_https-portal_1` # Assumes that the container has the name code_https-portal_1
ufw allow from $HTTPS_PORTAL_IP to $DOCKER_HOST_IP port 8080

Multiple Domains

You can specify multiple domains by splitting them with commas:

https-portal:
  # ...
  environment:
    DOMAINS: 'wordpress.example.com -> http://wordpress:80, gitlab.example.com -> http://gitlab'

You can also specify the stage (local, staging, or production) for each individual site, note that stages of individual sites overrides the global stage:

DOMAINS: 'wordpress.example.com -> http://wordpress #local, gitlab.example.com #staging'

Multiple Upstreams

It's possible to define multiple upstreams for a domain for the purpose of load-balancing and/or HA. Just add additional upstreams separated by a pipe separator. Each upstream can have custom parameters.

https-portal:
  # ...
  environment:
    DOMAINS: 'wordpress.example.com -> http://wordpress1:80|wordpress2:80[weight=2 max_conns=100]

See Nginx Upstream-Module for possible parameters.

Serving Static Sites

Instead of forwarding requests to web applications, HTTPS-PORTAL can also serve (multiple) static sites directly:

https-portal:
  # ...
  environment:
    DOMAINS: 'hexo.example.com, octopress.example.com'
  volumes:
    - https-portal-data:/var/lib/https-portal
    - /data/https-portal/vhosts:/var/www/vhosts

After HTTPS-PORTAL is started, it will create corresponding sub-directories for each virtual host in the /data/https-portal/vhosts directory on the host machine:

/data/https-portal/vhosts
├── hexo.example.com
│  └── index.html
└── octopress.example.com
    └── index.html

You can place your own static files in this directory hierarchy, they will not be overwritten. You need an index.html to be served as the homepage.

Share Certificates with Other Apps

You can mount an arbitrary host directory to /var/lib/https-portal as a data volume.

For instance:

https-portal:
  # ...
  volumes:
    - /data/ssl_certs:/var/lib/https-portal

Now your certificates are available in /data/ssl_certs on your host.

HTTP Basic Auth

You can set up an HTTP Basic Auth easily. It is useful when you put the website online but don't want to open it to public until ready.

In your docker-compose file:

https-portal:
  # ...
  environment:
    DOMAINS: 'username:[email protected] -> <upstream>'

Access Restriction

Notice: Access Restriction might not work as intended with Docker for Mac and Docker for Windows. In those systems, Docker essentially runs in VMs, so the requesting IP would be the IP of the proxy service.

You can enable IP access restrictions to protect your website. Specify global restrictions with the environment variable ACCESS_RESTRICTION. In addition each website can have individual restrictions.

Example with global restriction:

https-portal:
  # ...
  environment:
    ACCESS_RESTRICTION: "1.2.3.4/24 4.3.2.1"

Example with individual restrictions:

https-portal:
  # ...
  environment:
    DOMAINS: "[1.2.3.4/24] a.example.com -> <upstream> , [1.2.3.4/24 4.3.2.1] b.example.com"

Example for auto discovery:

https-portal:
  # ...
my_app:
  image: ...
  environment:
    VIRTUAL_HOST: "[1.2.3.4] example.com"

For valid IP values see Nginx allow

Logging configuration

By default no Nginx access logs are written, and error logs are written to stdout, which will be captured by Docker. There are few options to configure them:

  • Redirect error/access logs to stdout/stderr:

    https-portal:
      # ...
      environment:
        ERROR_LOG: stdout
        ACCESS_LOG: stderr
  • Write logs to default locations:

    https-portal:
      # ...
      environment:
        ERROR_LOG: default
        ACCESS_LOG: default
      volumes:
        - https-portal-data:/var/lib/https-portal
        - /path/to/log/directory:/var/log/nginx/
        - /path/to/logrotate/state/directory:/var/lib/logrotate/

    Default log files pathes are /var/log/nginx/access.log and /var/log/nginx/error.log.

    Log files within default location /var/log/nginx/*.log are rotated on daily basis. HTTPS-PORTAL will keep up to 30 log files and will compress files older than 2 days (so current day log and previous day log are both available in plain text while all older ones are compresses).

    If you want to alter log rotation configuration, you can overwrite /etc/logrotate.d/nginx.

  • Write logs to custom locations:

    https-portal:
      # ...
      environment:
        ERROR_LOG: /var/log/custom-logs/error.log
        ACCESS_LOG: /var/log/custom-logs/access.log
      volumes:
        - https-portal-data:/var/lib/https-portal
        - /path/to/log/directory:/var/log/custom-logs/

    Note that no automatic log rotation will be performed in this case.

  • Other env variables:

    There are some other configurable environment variables regarding logging:

    • ACCESS_LOG_BUFFER - controls buffer size of access log. Example: 16k.
    • ERROR_LOG_LEVEL - controls error log level. Default value is error

Debugging

With the environment variable DEBUG=true you can see more info printed about domain parsing, such as:

DEBUG: name:'example.com' upstreams:'' redirect_target:''

Other Configurations

By default, HTTPS-PORTAL renews the certificate about 30 days before the expiry. You can customize it by:

RENEW_MARGIN_DAYS=30

Internationalized Domain Names (IDN)

If you have non-ASCII characters in your domain, convert it to an ASCII-Compatible Encoding (ACE) form before using HTTPS-PORTAL.

Advanced Usage

Configure Nginx through Environment Variables

In case you need to change Nginx's default parameters, there are several additional environment variables that you can use to config Nginx. They correspond to the configuration options that you would normally put in nginx.conf. The following are the available params with their default values:

INDEX_FILES=index.html                  # A space-separated list of index file names to look for
WORKER_PROCESSES=1
WORKER_CONNECTIONS=1024
KEEPALIVE_TIMEOUT=65
GZIP=on                                 # can be 'off' (you need quotes)
SERVER_TOKENS=off
SERVER_NAMES_HASH_MAX_SIZE=512
SERVER_NAMES_HASH_BUCKET_SIZE=32        # defaults to 32 or 64 based on your CPU
CLIENT_MAX_BODY_SIZE=1M                 # 0 disables checking request body size
PROXY_BUFFERS="8 4k"                    # Either 4k or 8k depending on the platform
PROXY_BUFFER_SIZE="4k"                  # Either 4k or 8k depending on the platform
RESOLVER="Your custom solver string"
PROXY_CONNECT_TIMEOUT=60;
PROXY_SEND_TIMEOUT=60;
PROXY_READ_TIMEOUT=60;
ACCESS_LOG=off;
ACCESS_LOG_INCLUDE_HOST=off;            # include vhost in access log (useful for goaccess => use log-format=VCOMBINED)
REDIRECT_CODE=307                       # Was 301 by default until 1.20.1

Websocket

You can add

WEBSOCKET=true

to make HTTPS-PORTAL proxy WEBSOCKET connections.

DNS caching

To avoid nginx DNS caching, activate dynamic upstream

RESOLVER="127.0.0.11 ipv6=off valid=30s"
DYNAMIC_UPSTREAM=true

HSTS Header

You can use the follow environment variable to set HSTS header.

WARNING: Please test with a low value before you set it to a desired high max_age value. Once you send the header out, all visited clients would refuse to downgrade to HTTP. It would then be impossible to fallback your website to HTTP.

HSTS_MAX_AGE=60  # in seconds

IPv6 connectivity

Notice: IPv6 is only supported on Linux hosts.

You can enable IPv6 connection using the following variable:

LISTEN_IPV6=true

Other server block level configurations

You can add additional server block level configurations to each domain:

  environment:
    ...
    CUSTOM_NGINX_SERVER_CONFIG_BLOCK: add_header Strict-Transport-Security "max-age=60" always;

You can also make it multi-line:

  environment:
    ...
    CUSTOM_NGINX_SERVER_CONFIG_BLOCK: |
    	add_header Strict-Transport-Security "max-age=60" always;
    	auth_basic "Password";	

When using variables, you need to escape them with $:

  environment:
    ...
    CUSTOM_NGINX_GLOBAL_HTTP_CONFIG_BLOCK: |
        limit_req_zone $$binary_remote_addr zone=one:10m rate=1000r/m;

The CUSTOM_NGINX_SERVER_CONFIG_BLOCK will be inserted after all other configuration blocks listed in section "Configure Nginx through Environment Variables", and it might conflict with other configurations.

In addition to the global CUSTOM_NGINX_SERVER_CONFIG_BLOCK, which applies to all configurations, there are CUSTOM_NGINX_<UPPERCASE_AND_UNDERSCORED_DOMAIN_NAME>_CONFIG_BLOCKs, which are inserted after the CUSTOM_NGINX_SERVER_CONFIG_BLOCK, but only into the configuration file for a specific site. For instance, To make specific changes to example.com only, create an environment variable CUSTOM_NGINX_EXAMPLE_COM_CONFIG_BLOCK.

# generated Nginx config:
server {
	listen 443 ssl http2;
	... # (other configurations)
	<%= CUSTOM_NGINX_SERVER_CONFIG_BLOCK %>
	<%= CUSTOM_NGINX_<DOMAIN_NAME>_CONFIG_BLOCK %>
	location / {
		...
	}
}

The variables CUSTOM_NGINX_GLOBAL_HTTP_CONFIG_BLOCK and CUSTOM_NGINX_SERVER_PLAIN_CONFIG_BLOCK can be used to add your own Nginx statements to the global http block or to the plaintext (non-SSL) server blocks.

In the rare case that you want to change the handling of /.well-known/acme-challenge/ requests, setting ACME_CHALLENGE_BLOCK will override the default configuration. Check out the Nginx config templates for more details.

Change Configuration Dynamically

Environment variables may be dynamically overridden by modifying files /var/lib/https-portal/dynamic-env. The file's name and contents will create an environment variable with that name and contents, respectively. About 1s after the last modification, the configuration will be updated to reflect the new configuration. This allows modifying the configuration without downtime.

Override Nginx Configuration Files

You can override default nginx settings by providing a config segment of nginx.conf containing a valid server block. The custom nginx configurations are ERB templates and will be rendered before usage.

You can either just override one single site's config or all sites' configs.

Override just one single site's config

In this case, you provide <your-domain>.conf.erb and <your-domain>.ssl.conf.erb. The former one takes care of the ownership verification from Let's Encrypt, and redirection to https URL. The latter one handles https connections.

For instance, to override both HTTPS and HTTP settings for my.example.com, you can launch HTTPS-PORTAL by:

https-portal:
  # ...
  volumes:
    - https-portal-data:/var/lib/https-portal
    - /path/to/http_config:/var/lib/nginx-conf/my.example.com.conf.erb:ro
    - /path/to/https_config:/var/lib/nginx-conf/my.example.com.ssl.conf.erb:ro

This file and this file are the default configuration files used by HTTPS-PORTAL. You can probably start by copying these files. You can either keep the variables or just hard-code the domain and upstream, etc.

Another example can be found here.

Override All sites' default config

If you want to make an Nginx configuration that will be used by all sites, you can overwrite /var/lib/nginx-conf/default.conf.erb or /var/lib/nginx-conf/default.ssl.conf.erb. These two files will be propagated to each site if the site-specific configuration files are not provided.

Since the config files will be used on all your sites, please keep using the variables already in the file and don't hard-code anything.

Manually Set Private Key Length/Type

By default, HTTPS-PORTAL generate 2048 bits long RSA private key.
However, you can manually set RSA private key length (numbits of openssl genrsa command) through NUMBITS environment variable.

https-portal:
  # ...
  environment:
    NUMBITS: '4096'

Alternatively, you can set the CERTIFICATE_ALGORITHM environment variable to prime256v1, as recommended by Mozilla. Note however, that this setting prevents some older clients/systems from connecting.

Both settings apply to newly generated keys only. If you would like to update existing keys, remove the existing keys stored under /var/lib/https-portal and restart https-portal.

How It Works

It:

  • obtains an SSL certificate for each of your subdomains from Let's Encrypt.
  • configures Nginx to use HTTPS (and force HTTPS by redirecting HTTP to HTTPS)
  • sets up a cron job that checks your certificates every week, and renew them. if they expire in 30 days.

About Rate Limits of Let's Encrypt

Let's Encrypt's service is rate limited to ensure fair usage. Please familiarize yourself with the various rate limits. This documentation page is the authoritative source for the current rate limit values.

For most people the most important rate limits are:

  • 5 failed validation attempts per hour
  • 50 certificates per registered domain per week
  • 5 duplicated certificate per week (for renewal)

If you want to use HTTPS for multiple sub-domains with a single certificate Let's Encrypt supports putting up to 100 domains in one certificate, however it can require careful planning and is hard to automate. So in HTTPS-PORTAL we only deal with single domain name certificates.

HTTPS-PORTAL stores your certificates in a data volume and will not re-sign certificates until 30 days before expiration if a valid certificate is found (you can force renew certificates by using FORCE_RENEW: 'true' environment variable). However if you play around with the image a lot, you can hit the limit. That's why STAGE is staging by default, and thus we use the Let's Encrypt staging server. When you have finished your experiments and feel everything is good, you can switch to production mode with STAGE: 'production'.

Troubleshooting

Force renew

If you find your certificates are not chained correctly, please run the container again with the follow setting once:

https-portal:
  # ...
  environment:
    # ...
    FORCE_RENEW: 'true' # <-- here

This is because with ACME v2 returns the full chain instead of a partial chain with ACME v1. If you have old certificates stored, HTTPS-PORTAL may not be able to handle the case correctly. If you run into this issue, just FORCE_RENEW to obtain a new set of certificates.

Reset the data volume

If you find HTTPS-PORTAL is not behaving as expected, try to reset the data volume:

docker-compose down -v
docker-compose up

Credits

https-portal's People

Contributors

bessonov avatar biow0lf avatar david-development avatar devidw avatar dmpanch avatar donskifarrell avatar geetotes avatar gilday avatar ifamirhasan avatar itsabdelrahman avatar j-o-lantern0422 avatar jacqt avatar jupegarnica avatar kapitanov avatar lrkwz avatar madsrc avatar marcelwaldvogel avatar nicklegr avatar omyno avatar prilka avatar rainux avatar s-nagaev avatar sarisia avatar stam avatar steveltn avatar vespakoen avatar vgeyer avatar weisisheng avatar yamada28go avatar ydkk avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

https-portal's Issues

https-portal and cloudflare?

If I add my website to Cloudflare and enable their certification, the website works fine but Let's Encrypts Cert is disabled and replaced with Cloudflares. As can be seen at the moment on my website: https://damir.tech

If I disabled this Certification in their control panel the website ceases to work and a redirect loop occurs, this didn't seem to be the issue with my previous Let's Encrypt setup.

Any clarification?

youngertv-tv-land-younger-sutton-foster-3o6ozpK4HCj42txQxG

Default redirections are made to http

Hello,

First of all, I'm a newbie, please be indulgent if my question is stupid ...

I run https-portal in front of a php-apache container. Everything works fine, except the default http redirections that are made to http instead of https. For instance, let say we have a directory named test in our website. Calling https://mysite.com/test returns a 301 code with redirection to http://mysite.com/test/.
This is not the same behaviour we obtain using a pure apache-php server with https enabled. In such a case, apache returns a 301 code with redirection to https://mysite.com/test/.
The problem is some http clients (ie java HttpURLConnection) follows redirection only if the scheme isn't changed, for security concerns.
Finally, my question: Is it possible to obtain the same behavior as pure apache-php server (redirection to https)?

Here is my docker-compose file:

version: '2'
services:
  https-portal:
    image: steveltn/https-portal
    ports:
      - 80:80
      - 443:443
    depends_on:
      - test
    restart: always
    environment:
      DOMAINS: 'test.fathzer.com -> http://test #production'
    volumes:
      - /root/ssl_certs:/var/lib/https-portal

  test:
    image:
      php:5-apache
    volumes:
      - /home/test/www:/var/www/html
    restart: always

I've made 2 web sites to make the demonstration:
One powered by https-portal: https://test.fathzer.com/test -> Redirects to http
One with plain old apache-php server: https://test2.fathzer.com/test -> Redirects to https

Best regards,
PS: Thanks for that great project :-)

Advised to mount certs folder?

Hey there!

I am super happy with this project, it makes SSL easy as it should be =)
However, I hit the rate limit, I have a CI/CD tool setup that will build docker containers and deploy them to production once a push happens on some branch, the way it works is it pulls my new images, stops / removes the running containers, then starts them again.

I guess in this process my certificates are lost, and they will get re-requested.
I now mount the certs folder to my host VM, hoping they will be "picked up" by https-portal on a new startup, avoiding the (rate limited) API calls to letsencrypt.
Do you know if this will work? (I cannot really test right now because of the rate limit).

If so, I'd be happy to update the readme on that.

host not found in upstream "etherpad" in /etc/nginx/conf.d/pads.domain.org.ssl.conf:18

Hi,

I'm trying to add multiple domains on https-portal but on some I'm getting:
'host not found in upstream'
I've mounted:
./config/docker/nginx/:/etc/nginx/conf.d/:rw
And checked the file pads.domain.org.ssl.conf I can see is exactly the same as other domains that are working. I added domains as explained here https://github.com/SteveLTN/https-portal and also specified VIRTUAL_HOST on the containers pointing to those domains on https-portal docker-compose.yml

I made that working with wordpress and ethercalc, containers failing are rocket chat and etherpad.

What should I do?

Uploading docker_compose.txt…

Any recommended way to add a auth_basic_user_file for a site ?

Hi,

First of all, thanks for this great project !
I'd like to add a login/password for a given upstream, is there a recommended way to do this (env var vs new config file) ?
In the last case, how should the default nginx config created by https-portal be updated ?

server {
    listen       80;
    server_name  domain.tld;
    location / {
       return    301 https://$server_name$request_uri;
    }
    location /.well-known/acme-challenge/ {
        alias /var/www/default/challenges/;
        try_files $uri =404;
    }
}

Open question re: default.ssl.conf.erb

Not terribly facile with nginx, google sitemaps search keeps complaining about a robots.txt file which I can not find after scouring the server. If I wanted to "allow all" would the following code snippet in the upstream section of default.ssl.conf.erb be enough? I don't want to add a custom file as I had issues with it in the past and everything is working perfectly the last few weeks ex the search engines complaining.

TIA for entertaining the question.

Designed to be included in any server {} block.

location = /favicon.ico {
log_not_found off;
access_log off;
}

location = /robots.txt {
allow all;
log_not_found off;
access_log off;
}

<% if domain.upstream %>
location / {
    proxy_pass <%= domain.upstream %>;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;

--> place snippet here

}
<% else %>
location / {
    root   <%= domain.www_root %>;
    index  index.html;

--> and here
}
<% end %>

*101 connect() failed (111: Connection refused) while connecting to upstream

I am using this kind of setup for my webapp - https://github.com/kampta/https-portal-example
It had been working fine for last one month or so but has starting throwing error 502 recently. Here is what I see in the log.

nginx_1       | 2016/08/04 14:29:15 [error] 159#159: *101 connect() failed (111: Connection refused) while connecting to upstream, client: xx.xx.xx.xx, server: example.com, request: "GET / HTTP/1.1", upstream: "http://xx.xx.xx.xx:8000/", host: "example.com"
nginx_1       | 2016/08/04 14:29:16 [error] 159#159: *101 connect() failed (111: Connection refused) while connecting to upstream, client: xx.xx.xx.xx, server: example.com, request: "GET /favicon.ico HTTP/1.1", upstream: "http://xx.xx.xx.xx:8000/favicon.ico", host: "example.com", referrer: "https://example.com/"

On googling, it seems to have something to do with ipv4/ipv6. Ideas? (Thanks a lot in advance)

Multiple domains for the same upstream container

Hi @SteveLTN – me again, exploring the edge-cases of HTTPS-PORTAL!

I've got a multilingual site where I run the Welsh and English versions on separate domains.

I've tried the following environment variable for HTTPS-PORTAL:

DOMAINS: 'mysite.wales -> http://mysite, mysite.cymru -> http://mysite'

If I do this, domain verification fails on mysite.cymru with the following in the logs:

Traceback (most recent call last):
  File "/bin/acme_tiny", line 198, in <module>
    main(sys.argv[1:])
  File "/bin/acme_tiny", line 194, in main
    signed_crt = get_crt(args.account_key, args.csr, args.acme_dir, log=LOGGER, CA=args.ca)
  File "/bin/acme_tiny", line 123, in get_crt
    wellknown_path, wellknown_url))
ValueError: Wrote file to /var/www/default/challenges/eA04PB7RP4KR9GqyVpE3pnM_k_cW7Zmjdqc_JXRcJu0, but couldn't download http://mysite.cymru/.well-known/acme-challenge/eA04PB7RP4KR9GqyVpE3pnM_k_cW7Zmjdqc_JXRcJu0
Failed to obtain certs for mysite.cymru

Any idea how to do multiple domains for the same container? Ideally, VIRTUAL_HOST would allow comma-separated domains so that it can be encapsulated in the web server rather than the RP, but I'll take anything that works!

Of course, it's also possible that I've just done something really stupid.

Request: WebSocket proxy configuration option

I'm running a weechat relay, and had a bit of head-scratching before I got it to work with https-portal. The reason being that nginx needs the following two config options to let WebSocket connections through.

        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "Upgrade";

If it's easy to add a configuration option for setting those per service, that would be nice.

Fails to come back up due to domain.rb error

Hi @SteveLTN

Me again!

I've had to bring HTTPS-PORTAL down on one of my servers. On that server, I've got the certificates mapped out to the host using - /data/ssl_certs:/var/lib/https-portal. When I've tried to docker-compose up -d again, it's not come back up and has the following errors in the logs:

[cont-init.d] executing container initialization scripts...
[cont-init.d] 00-setup: executing...
/opt/certs_manager/models/domain.rb:65:in `name': undefined method `strip' for nil:NilClass (NoMethodError)
    from /opt/certs_manager/lib/na_config.rb:3:in `uniq'
    from /opt/certs_manager/lib/na_config.rb:3:in `domains'
    from /opt/certs_manager/certs_manager.rb:11:in `setup'
    from /etc/cont-init.d/00-setup:4:in `<main>'
[cont-init.d] 00-setup: exited 1.
[cont-init.d] 10-set-docker-gen-status: executing...
[cont-init.d] 10-set-docker-gen-status: exited 0.
[cont-init.d] done.

If I remove the stored certs and bring it back up, it appears to work. I say "appears" because I've tried on a clone of my VPS and it fails because DNS doesn't resolve (rightly), but it seems to get further than with the stored certificates.

I can probably regenerate, but this server had 10-ish subdomains of my main domain, so I'm reluctant to try to regenerate in case I bump into the LE rate limit.

Any idea what might be going on?

Cheers

Fail at signing domain

I have a docker http working and I wanted to add a Let's Encrypt certificate for SSL.
While setting it up using docker-compose I run with this problem.

FYI: Port 80 is being used by this docker-compose. And DNS is setup correctly, if I use local environment (self signed certificate) domain works properly.

tcp6       0      0 :::80                   :::*                    LISTEN      11945/docker-proxy

docker-compose.yml

version: '2'
services:
  https-portal:
    image: steveltn/https-portal
    ports:
      - 80:80
      - 443:443
    restart: always
    environment:
      DOMAINS: 'git.mydomain.co -> http://dockerhost:10080'
      STAGE: 'production'
    volumes:
      - ./ssl_certs:/var/lib/https-portal

Any thoughts?

https-portal_1  | [fix-attrs.d] applying owners & permissions fixes...
https-portal_1  | [fix-attrs.d] 00-runscripts: applying...
https-portal_1  | [fix-attrs.d] 00-runscripts: exited 0.
https-portal_1  | [fix-attrs.d] done.
https-portal_1  | [cont-init.d] executing container initialization scripts...
https-portal_1  | [cont-init.d] 00-setup: executing...
https-portal_1  | 2016/11/02 12:14:43 [notice] 123#123: signal process started
https-portal_1  | Signing certificates from https://acme-v01.api.letsencrypt.org ...
https-portal_1  | Parsing account key...
https-portal_1  | Parsing CSR...
https-portal_1  | Registering account...
https-portal_1  | Already registered!
https-portal_1  | Verifying git.mydomain.co...
https-portal_1  | /opt/certs_manager/lib/acme.rb:28:in `system': execution expired (Timeout::Error)
https-portal_1  |   from /opt/certs_manager/lib/acme.rb:28:in `block in le_sign'
https-portal_1  |   from /usr/lib/ruby/2.1.0/timeout.rb:91:in `block in timeout'
https-portal_1  |   from /usr/lib/ruby/2.1.0/timeout.rb:35:in `block in catch'
https-portal_1  |   from /usr/lib/ruby/2.1.0/timeout.rb:35:in `catch'
https-portal_1  |   from /usr/lib/ruby/2.1.0/timeout.rb:35:in `catch'
https-portal_1  |   from /usr/lib/ruby/2.1.0/timeout.rb:106:in `timeout'
https-portal_1  |   from /opt/certs_manager/lib/acme.rb:16:in `le_sign'
https-portal_1  |   from /opt/certs_manager/lib/acme.rb:9:in `sign'
https-portal_1  |   from /opt/certs_manager/certs_manager.rb:60:in `block in ensure_signed'
https-portal_1  |   from /opt/certs_manager/certs_manager.rb:53:in `each'
https-portal_1  |   from /opt/certs_manager/certs_manager.rb:53:in `ensure_signed'
https-portal_1  |   from /opt/certs_manager/certs_manager.rb:19:in `setup'
https-portal_1  |   from /etc/cont-init.d/00-setup:4:in `<main>'
https-portal_1  | ================================================================================
https-portal_1  | Failed to sign git.mydomain.co, is DNS set up properly?
https-portal_1  | ================================================================================
https-portal_1  | [cont-init.d] 00-setup: exited 1.
https-portal_1  | [cont-init.d] 10-set-docker-gen-status: executing...
https-portal_1  | [cont-init.d] 10-set-docker-gen-status: exited 0.
https-portal_1  | [cont-init.d] done.
https-portal_1  | [services.d] starting services
https-portal_1  | [services.d] done.
https-portal_1  | Starting crond ...
https-portal_1  | 2016/11/02 12:15:13 [emerg] 164#164: bind() to 0.0.0.0:80 failed (98: Address already in use)
https-portal_1  | nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
https-portal_1  | 2016/11/02 12:15:13 [emerg] 164#164: bind() to 0.0.0.0:80 failed (98: Address already in use)
https-portal_1  | nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
https-portal_1  | 2016/11/02 12:15:13 [emerg] 164#164: bind() to 0.0.0.0:80 failed (98: Address already in use)
https-portal_1  | nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
https-portal_1  | 2016/11/02 12:15:13 [emerg] 164#164: bind() to 0.0.0.0:80 failed (98: Address already in use)
https-portal_1  | nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
https-portal_1  | 2016/11/02 12:15:13 [emerg] 164#164: bind() to 0.0.0.0:80 failed (98: Address already in use)
https-portal_1  | nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
https-portal_1  | 2016/11/02 12:15:13 [emerg] 164#164: still could not bind()
https-portal_1  | nginx: [emerg] still could not bind()
https-portal_1  | [cont-finish.d] executing container finish scripts...
https-portal_1  | [cont-finish.d] done.
https-portal_1  | [s6-finish] syncing disks.
https-portal_1  | [s6-finish] sending all processes the TERM signal.

Is it possibile to use this Docker image on a VPS?

I'm trying to make this Docker image on my VPS. I followed the prerequisites (I have Docker installed, the ports 80 and 443 are available and my domain name resolves to my machine (I could access it by http://claude.wtf).

I just copied the docker-copose.yml file:

https-portal:
image: steveltn/https-portal
ports:

  • '80:80'
  • '443:443'
    environment:
    DOMAINS: 'example.com'
    PRODUCTION: 'true'

And I changed the example.com by claude.wtf.
When I run the command docker-compose up -d, I don't have any errors, all seems to work well:

Name Command State Ports

root_https-portal_1 /init Up 0.0.0.0:443->443/tcp, 0.0.0.0:80->80/tcp

But if I try to access https://claude.wtf/ with curl I get this error: Failed to connect to claude.wtf port 443: Connection refused.

In order to avoid this error, I have done:

iptables -A INPUT -p tcp -m tcp --sport 443 -j ACCEPT
iptables -A OUTPUT -p tcp -m tcp --dport 443 -j ACCEPT

And I don't seem to have any firewall activated since sudo ufw status verbose gives Status: inactive.

What could I have forgotten, or what am I doing wrong?
Thanks for your responses ;)

Multiple domains with redirect

It would be nice to be able to easily do the following setup:

  • One certificate for multiple domains, e.g: example.com and www.example.com
  • If the user visits www.example.com he should be redirected to example.com

Maybe it is already possible but I couldn't figure out how?

docker registry behind https-portal

I am trying to setup a docker registry behind the https portal,
but i can not get it to work:

this was the output:

https-portal_1 | Starting docker-gen ...
https-portal_1 | Starting crond ...
https-portal_1 | 2016/01/28 20:25:23 Generated '/var/run/domains' from 6 containers
https-portal_1 | 2016/01/28 20:25:23 Running 'reconfig'
https-portal_1 | 12.12.12.122 - - [28/Jan/2016:20:25:25 +0000] "GET /.well-known/acme-challenge/0L8oxvvmfzfNB42zQmi2kgxgipY41Kmu99JgxJZFQ0M HTTP/1.1" 200 87 "-" "Python-urllib/2.7" "-"
https-portal_1 | 66.133.109.36 - - [28/Jan/2016:20:25:27 +0000] "GET /.well-known/acme-challenge/0L8oxvvmfzfNB42zQmi2kgxgipY41Kmu99JgxJZFQ0M HTTP/1.1" 200 87 "-" "Mozilla/5.0 (compatible; Let's Encrypt validation server; +https://www.letsencrypt.org)" "-"
https-portal_1 | 2016/01/28 20:25:33 [reconfig]: 2016/01/28 20:25:23 [notice] 166#166: signal process started
https-portal_1 | 2016/01/28 20:25:33 [reconfig]: Generating RSA private key, 2048 bit long modulus
https-portal_1 | 2016/01/28 20:25:33 [reconfig]: ......+++
https-portal_1 | 2016/01/28 20:25:33 [reconfig]: ..+++
https-portal_1 | 2016/01/28 20:25:33 [reconfig]: unable to write 'random state'
https-portal_1 | 2016/01/28 20:25:33 [reconfig]: e is 65537 (0x10001)
https-portal_1 | 2016/01/28 20:25:33 [reconfig]: Signing certificates from https://acme-staging.api.letsencrypt.org ...
https-portal_1 | 2016/01/28 20:25:33 [reconfig]: Parsing account key...
https-portal_1 | 2016/01/28 20:25:33 [reconfig]: Parsing CSR...
https-portal_1 | 2016/01/28 20:25:33 [reconfig]: Registering account...
https-portal_1 | 2016/01/28 20:25:33 [reconfig]: Registered!
https-portal_1 | 2016/01/28 20:25:33 [reconfig]: Verifying registry.testtest.nl...
https-portal_1 | 2016/01/28 20:25:33 [reconfig]: registry.testtest.nl verified!
https-portal_1 | 2016/01/28 20:25:33 [reconfig]: Signing certificate...
https-portal_1 | 2016/01/28 20:25:33 [reconfig]: Certificate signed!
https-portal_1 | 2016/01/28 20:25:33 [reconfig]: 2016/01/28 20:25:33 [notice] 185#185: signal process started
https-portal_1 | 2016/01/28 20:25:33 [reconfig]: Signed key for registry.testtest.nl
https-portal_1 | 2016/01/28 20:25:33 Watching docker events

from this docker-compose file:
https-portal:
restart: always
image: steveltn/https-portal
ports:
- '80:80'
- '443:443'
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- ./data/ssl_certs:/var/lib/https-portal
- ./data/http_config:/var/lib/nginx-conf:ro
- ./data/http_pass:/var/etc/passwords:ro
environment:
PRODUCTION: 'true'
container_name: https_portal

I tried Force renew

Set STAGE env on a application container (rather than HTTPS-PORTAL)

Hi @SteveLTN

I'm loving the project so much that I keep finding other little things that would make it even more amazing.

I was thinking that it would be good to be able to set the STAGE on a container independently of the STAGE on HTTPS-PORTAL. For instance, I have a staging server where I regularly bring up additional applications behind HTTPS-PORTAL. I'd like to be able be able to have HTTPS-PORTAL in STAGE: "production", while bringing an individual container up like:

wordpress: image: wordpress environment: STAGE: 'local' links: - db:mysqlz

By doing this, we could do two things:

  • Have an escape hatch for when you've done too many certificate requests on a domain, but you want to bring it up to have a play around with it, and, more importantly,
  • Work on a container in a pre-live environment before flipping the DNS. This is my big issues at the moment – I have a legacy Apache server with multiple virtualhosts that I want to migrate to my new server using HTTPS-PORTAL. But at the moment, I have to ensure that the DNS resolves to my new server before I can spin up the application. If I could spin this container up as local, I could use local host spoofing to get my application set up, before flipping the DNS at the last stage

I thought I had seen the ability to do this in the docs somewhere, but I can't find it again – and I can't seem to get it to work.

What do you think?

Cannot download acme-challenge

Hi,

I've setup https-portal in a service of my compose file but got the following error during startup.

2016/08/19 13:02:38 [notice] 135#135: signal process started
Generating RSA private key, 2048 bit long modulus
...............................+++
...........................................................................................+++
e is 65537 (0x10001)
Signing certificates from https://acme-v01.api.letsencrypt.org ...
Parsing account key...
Parsing CSR...
Registering account...
Registered!
Verifying www.mydomain.com...
Traceback (most recent call last):
  File "/bin/acme_tiny", line 198, in <module>
    main(sys.argv[1:])
  File "/bin/acme_tiny", line 194, in main
    signed_crt = get_crt(args.account_key, args.csr, args.acme_dir, log=LOGGER, CA=args.ca)
  File "/bin/acme_tiny", line 123, in get_crt
    wellknown_path, wellknown_url))
ValueError: Wrote file to /var/www/default/challenges/YCKUvZB8pEbmRGMNyQvUIDcFOifPoVecry7hN01FpfI, but couldn't download http://www.mydomain.com/.well-known/acme-challenge/YCKUvZB8pEbmRGMNyQvUIDcFOifPoVecry7hN01FpfI
2016/08/19 13:02:39 [emerg] 151#151: SSL_CTX_use_PrivateKey_file("/var/lib/https-portal/www.mydomain.com/production/domain.key") failed (SSL: error:0B080074:x509 certificate routines:X509_check_private_key:key values mismatch)
nginx: [emerg] SSL_CTX_use_PrivateKey_file("/var/lib/https-portal/www.mydomain.com/production/domain.key") failed (SSL: error:0B080074:x509 certificate routines:X509_check_private_key:key values mismatch)
Signed key for www.mydomain.com
2016/08/19 13:02:39 [emerg] 152#152: SSL_CTX_use_PrivateKey_file("/var/lib/https-portal/www.mydomain.com/production/domain.key") failed (SSL: error:0B080074:x509 certificate routines:X509_check_private_key:key values mismatch)
nginx: [emerg] SSL_CTX_use_PrivateKey_file("/var/lib/https-portal/www.mydomain.com/production/domain.key") failed (SSL: error:0B080074:x509 certificate routines:X509_check_private_key:key values mismatch)
Generating RSA private key, 2048 bit long modulus
......................................................................+++
...............................................................+++

In my compose file, I have

# TLS termination
  tls:
    image: steveltn/https-portal
    environment:
      - 'DOMAINS=www.mydomain.com -> http://proxy, admin.mydomain.com -> http://proxy:8000, api.mydomain.com -> http://proxy:8080'
      - 'FORCE_RENEW=true'
      - 'STAGE=production'
    links:
      - proxy
    ports:
      - '80:80'
      - '443:443'
    restart: always

The Docker host is behind a router configured to forward incoming traffic on port 80 and 443.
Any idea ?

dockerhost redirection not working on Mac

I'm trying to run the proxy locally and point it to an app running on my host machine (my Mac laptop running macOS Sierra.) Unfortunately I only get a "502 Bad Gateway" error.

Repro:

  1. Create this docker-compose.yml file:
version: '2'
services:
  proxy:
    image: steveltn/https-portal
    ports:
    - 80:80    # HTTP on 80
    - 3000:443 # HTTPS on 3000 to allow SAML to work
    environment:
      STAGE: local
      DOMAINS: 'local.cis-dev.brown.edu -> http://dockerhost:8080'
  1. Add local.cis-dev.brown.edu to your /etc/hosts like so:
127.0.0.1	local.cis-dev.brown.edu
  1. Run docker-compose up to run the proxy.
  2. Run python -m SimpleHTTPServer 8080 from a directory with a simple index.html.
  3. Navigate to https://local.cis-dev.brown.edu:3000. Expected to see the Python server, but actually receiving "502 Bad Gateway" error.

Any clue how to fix this?

Agreement URL problem during startup

Hi, I have a problem during startup of the container. It tells me that the agreement URL is invalid. Could you please help?

2016-08-19 18:28:45 stdout Failed to obtain certs for jiratest.obeznani.pl
2016-08-19 18:28:45 stdout }
2016-08-19 18:28:45 stdout "status": 400
2016-08-19 18:28:45 stdout "detail": "Provided agreement URL [https://letsencrypt.org/documents/LE-SA-v1.0.1-July-27-2015.pdf] does not match current agreement URL [https://letsencrypt.org/documents/LE-SA-v1.1.1-August-1-2016.pdf]",
2016-08-19 18:28:45 stdout "type": "urn:acme:error:malformed",
2016-08-19 18:28:45 stdout ValueError: Error registering: 400 {
2016-08-19 18:28:45 stdout raise ValueError("Error registering: {0} {1}".format(code, result))
2016-08-19 18:28:45 stdout File "/bin/acme_tiny", line 92, in get_crt
2016-08-19 18:28:45 stdout signed_crt = get_crt(args.account_key, args.csr, args.acme_dir, log=LOGGER, CA=args.ca)
2016-08-19 18:28:45 stdout File "/bin/acme_tiny", line 194, in main
2016-08-19 18:28:45 stdout main(sys.argv[1:])
2016-08-19 18:28:45 stdout File "/bin/acme_tiny", line 198, in
2016-08-19 18:28:45 stdout Traceback (most recent call last):
2016-08-19 18:28:44 stdout Registering account...
2016-08-19 18:28:44 stdout Parsing CSR...
2016-08-19 18:28:44 stdout Parsing account key...
2016-08-19 18:28:44 stdout Signing certificates from https://acme-v01.api.letsencrypt.org ...
2016-08-19 18:28:44 stdout e is 65537 (0x10001)
2016-08-19 18:28:44 stdout .........................+++
2016-08-19 18:28:44 stdout .+++
2016-08-19 18:28:44 stdout Generating RSA private key, 2048 bit long modulus
2016-08-19 18:28:44 stdout 2016/08/19 18:28:44 [notice] 129#129: signal process started
2016-08-19 18:28:43 stdout e is 65537 (0x10001)
2016-08-19 18:28:43 stdout ..................++
2016-08-19 18:28:43 stdout ..............................................................++
2016-08-19 18:28:41 stdout Generating RSA private key, 4096 bit long modulus
2016-08-19 18:28:41 stdout ...
2016-08-19 18:24:30 stdout This is going to take a long time
2016-08-19 18:24:30 stdout Generating DH parameters, 2048 bit long safe prime, generator 2
2016-08-19 18:24:29 stdout [cont-init.d] 00-setup: executing...
2016-08-19 18:24:29 stdout [cont-init.d] executing container initialization scripts...
2016-08-19 18:24:29 stdout [fix-attrs.d] done.
2016-08-19 18:24:29 stdout [fix-attrs.d] 00-runscripts: exited 0.
2016-08-19 18:24:29 stdout [fix-attrs.d] 00-runscripts: applying...
2016-08-19 18:24:29 stdout [fix-attrs.d] applying owners & permissions fixes...

Subdomains and no other place to put this comment

Between J. Wilder's and SteveLTN's phenomenal work, this devops noob is standing on the shoulders of giants! Just awesome.

Separately, be sure all subdomains are recognized by registrar before completing. I had one or two laggards whick borked the rest of the process.

Container auto discovery vhost not found

Hi! Thank you for amazing project.

I've encountered into some strange issue with autodiscovery:

https-portal_1  | 2016/11/06 18:37:17 
[error] 170#170: *2 "/var/www/vhosts/stilo.com.ua/index.html" is not found 
(2: No such file or directory), 
client: 77.213.32.33, server: stilo.com.ua, request: "GET / HTTP/1.1", 
host: "stilo.com.ua"

If I setup container with upstream - everything works perfectly. I thought that it is redmine issue, but I get the same error if I try to autodiscover container with basic webserver setup and different domain name.

Here is my docker-compose.yml:

  https-portal:
    image: steveltn/https-portal
    ports:
      - '80:80'
      - '443:443'
    links:
      - redmine
    restart: always
    environment:
      #DOMAINS: 'stilo.com.ua -> http://redmine'
      STAGE: 'production'
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro

  redmine:
    image: sameersbn/redmine
    container_name: redmine
    ports:
     - "8081:80"
    volumes:
     - /opt/redmine/data:/home/redmine/data
    environment:
     - DB_HOST=mydbip
     - DB_NAME=mysqluser
     - DB_USER=mybase
     - DB_PASS=mypass
     - DB_TYPE=mysql
     - SMTP_METHOD=async_smtp
     - [email protected]
     - SMTP_PASS=mypass
     - NGINX_MAX_UPLOAD_SIZE=200m
     - REDMINE_HTTPS=true
     - REDMINE_SECRET_TOKEN=mysecret
     - VIRTUAL_HOST=stilo.com.ua
     - VIRTUAL_PORT=8081

Error message when running "docker-compose up"

Hi, when I run "docker-compose up" using the example compose file:

https-portal:
  image: steveltn/https-portal
  ports:
    - '80:80'
    - '443:443'
  environment:
    DOMAINS: 'example.com'
    # PRODUCTION: 'true'

I've got the following error

luc ~/Desktop/https-test $ docker-compose up 
Creating httpstest_https-portal_1
Attaching to httpstest_https-portal_1
https-portal_1 | [fix-attrs.d] applying owners & permissions fixes...
https-portal_1 | [fix-attrs.d] 00-runscripts: applying...
https-portal_1 | [fix-attrs.d] 00-runscripts: exited 0.
https-portal_1 | [fix-attrs.d] done.
https-portal_1 | [cont-init.d] executing container initialization scripts...
https-portal_1 | [cont-init.d] 00-setup: executing...
https-portal_1 | Generating DH parameters, 2048 bit long safe prime, generator 2
https-portal_1 | This is going to take a long time
https-portal_1 | ................................................+....................................................................................
…….
+.....................................................++*++*
https-portal_1 | Generating RSA private key, 4096 bit long modulus
https-portal_1 | ................................................................++
https-portal_1 | ........................................................................................................++
https-portal_1 | e is 65537 (0x10001)
https-portal_1 | 2016/02/08 19:52:54 [notice] 125#125: signal process started
https-portal_1 | Generating RSA private key, 2048 bit long modulus
https-portal_1 | ..................................+++
https-portal_1 | ............................................................+++
https-portal_1 | e is 65537 (0x10001)
https-portal_1 | Signing certificates from https://acme-staging.api.letsencrypt.org ...
https-portal_1 | Parsing account key...
https-portal_1 | Parsing CSR...
https-portal_1 | Registering account...
https-portal_1 | Registered!
https-portal_1 | Verifying example.com...
https-portal_1 | Traceback (most recent call last):
https-portal_1 |   File "/bin/acme_tiny", line 198, in <module>
https-portal_1 |     main(sys.argv[1:])
https-portal_1 |   File "/bin/acme_tiny", line 194, in main
https-portal_1 |     signed_crt = get_crt(args.account_key, args.csr, args.acme_dir, log=LOGGER, CA=args.ca)
https-portal_1 |   File "/bin/acme_tiny", line 123, in get_crt
https-portal_1 |     wellknown_path, wellknown_url))
https-portal_1 | ValueError: Wrote file to /var/www/challenges/UUXuzci_dLfcKuBWsd2GviPaDFOAtJAJHry5WcVSqWs, but couldn't download     http://example.com/.well-known/acme-challenge/UUXuzci_dLfcKuBWsd2GviPaDFOAtJAJHry5WcVSqWs
https-portal_1 | Failed to obtain certs for example.com
https-portal_1 | 2016/02/08 19:52:56 [notice] 140#140: signal process started
https-portal_1 | [cont-init.d] 00-setup: exited 0.
https-portal_1 | [cont-init.d] 10-set-docker-gen-status: executing...
https-portal_1 | [cont-init.d] 10-set-docker-gen-status: exited 0.
https-portal_1 | [cont-init.d] done.
https-portal_1 | [services.d] starting services
https-portal_1 | [services.d] done.
https-portal_1 | Starting crond ...

I've created the docker host with Docker machine with IP 192.168.99.100 and setup my /etc/hosts so example.com is link to this IP.
I can telnet on 192.168.99.100 80 but not on port 443.
Any idea what I'm missing ?

Certificate chain incomplete / untrusted on iOS 9 Safari?

Hi,
I've setup a few sites through https-portal, one static and one using automatic container discovery. Both exhibit the same problems, both are untrusted by Safari in iOS 9 (desktop browsers are fine). When I run a test (https://www.ssllabs.com/ssltest/analyze.html) on the static site, I get the following warning:

This server's certificate chain is incomplete.

Here's my configuration:

https-portal:
  image: steveltn/https-portal
  ports:
    - '80:80'
    - '443:443'
  volumes:
    - /var/run/docker.sock:/var/run/docker.sock:ro
    - ./vhosts:/var/www/vhosts
  restart: always
  environment:
    PRODUCTION: 'true'
    FORCE_RENEW: 'true'
    CLIENT_MAX_BODY_SIZE: 600M
    GZIP: 'on'
    PROXY_READ_TIMEOUT: 900
    DOMAINS: '__domain_hidden__'

Full report attached.

SSL Server Test.pdf

Nginx SSL_CTX_use_PrivateKey_file key values mismatch failure

Hi,

I've been experiencing a certificate issue using this super simple docker-compose example:

# docker-compose.yml for my_wordpress site

https-portal:
  image: steveltn/https-portal
  ports:
    - '80:80'
    - '443:443'
  environment:
    - 'DOMAINS=taralocal.com'

I get the following errors running it:

Recreating sites_https-portal_1
Attaching to sites_https-portal_1
https-portal_1  | [fix-attrs.d] applying owners & permissions fixes...
https-portal_1  | [fix-attrs.d] 00-runscripts: applying...
https-portal_1  | [fix-attrs.d] 00-runscripts: exited 0.
https-portal_1  | [fix-attrs.d] done.
https-portal_1  | [cont-init.d] executing container initialization scripts...
https-portal_1  | [cont-init.d] 00-setup: executing...
https-portal_1  | 2016/08/01 19:00:08 [notice] 118#118: signal process started
https-portal_1  | 2016/08/01 19:00:08 [emerg] 122#122: SSL_CTX_use_PrivateKey_file("/var/lib/https-portal/taralocal.com/staging/domain.key") failed (SSL: error:0B080074:x509 certificate routines:X509_check_private_key:key values mismatch)
https-portal_1  | nginx: [emerg] SSL_CTX_use_PrivateKey_file("/var/lib/https-portal/taralocal.com/staging/domain.key") failed (SSL: error:0B080074:x509 certificate routines:X509_check_private_key:key values mismatch)
https-portal_1  | No need to re-sign certs for taralocal.com, it will not expire in 1689 days.
https-portal_1  | 2016/08/01 19:00:08 [emerg] 124#124: SSL_CTX_use_PrivateKey_file("/var/lib/https-portal/taralocal.com/staging/domain.key") failed (SSL: error:0B080074:x509 certificate routines:X509_check_private_key:key values mismatch)
https-portal_1  | nginx: [emerg] SSL_CTX_use_PrivateKey_file("/var/lib/https-portal/taralocal.com/staging/domain.key") failed (SSL: error:0B080074:x509 certificate routines:X509_check_private_key:key values mismatch)
https-portal_1  | [cont-init.d] 00-setup: exited 0.
https-portal_1  | [cont-init.d] 10-set-docker-gen-status: executing...
https-portal_1  | [cont-init.d] 10-set-docker-gen-status: exited 0.
https-portal_1  | [cont-init.d] done.
https-portal_1  | [services.d] starting services
https-portal_1  | [services.d] done.
https-portal_1  | Starting crond ...
https-portal_1  | 2016/08/01 19:00:09 [emerg] 152#152: SSL_CTX_use_PrivateKey_file("/var/lib/https-portal/taralocal.com/staging/domain.key") failed (SSL: error:0B080074:x509 certificate routines:X509_check_private_key:key values mismatch)
https-portal_1  | nginx: [emerg] SSL_CTX_use_PrivateKey_file("/var/lib/https-portal/taralocal.com/staging/domain.key") failed (SSL: error:0B080074:x509 certificate routines:X509_check_private_key:key values mismatch)
https-portal_1  | [cont-finish.d] executing container finish scripts...
https-portal_1  | [cont-finish.d] done.
https-portal_1  | [s6-finish] syncing disks.
https-portal_1  | [s6-finish] sending all processes the TERM signal.
https-portal_1  | 2016/08/01 19:00:09 [emerg] 117#117: SSL_CTX_use_PrivateKey_file("/var/lib/https-portal/taralocal.com/staging/domain.key") failed (SSL: error:0B080074:x509 certificate routines:X509_check_private_key:key values mismatch)
https-portal_1  | [s6-finish] sending all processes the KILL signal and exiting.
sites_https-portal_1 exited with code 0

This has been happening for the other examples as well, the same issue.
This is on a new Digital Ocean box running Ubuntu 16.04.1 x64, Docker version 1.12.0. I own the taralocal.com domain and it is pointing to the DigitalOcean name servers correctly.

What am I missing?

Revisting issue #32 w.r.t. nginx and robots.txt file

For some reason, I am unable to eliminate or edit my highly restrictive robots.txt file as found here.

go away

User-agent: *
Disallow: /

I have tried to delete the file completely, edit it directly, change ownership, etc. Nothing seems to work and yet I can't find any documentation on nginx automatically writing the file. I want to make the site searchable by all agents

I have attempted to slightly modify default.conf.erb and default.ssl.conf.erb to incorporate an inline statement as such " location /robots.txt {return 200 "User-agent: *\nDisallow:\n";} ". The server statement lives on through a docker commit and server restart and yet it isn't having an effect on the robots.txt file. Any help would be much appreciated.

Proxy for S3...

A noob at nginx usage and some of the code is still foreign. Is there any reason why I couldn't attempt to use https-portal to proxy pass S3 private files with the appropriate additions?

TIA.

Creating a new database (on same server) when adding another application

I'd just like to say amazing work on this project. This is absolutely incredible.

I'm having a little bit of trouble adding additional WordPress sites to my network. I'd like it to be a new wordpress container, but share the existing mariadb. I've been trying something like this:

docker run -d -P \ --link existingnetwork_db_1:mysql \ -e "VIRTUAL_HOST=site.example.com" \ --name="site" \ wordpress

This works well enough if I go into the existingnetwork_db_1 container and add a database and then go into the site container and change the wp-config.php to reflect the name of the new database, but that's not exactly a solution.

I think what I'm missing is that somehow when the db in docker-compose.yml spins up, it somehow (or something else) creates a database called wordpress and then seds wp-config.php or something to add the correct database name.

Any idea how I might do this when adding another application to use the same database server?

wordpress example - always failing on verification step

Hello!
I have a domain at Route53 and I'm trying to install an https proxy by your guide.
The only 2 strings I've changed - the domain name and mysql password.
Everything else - same as in your example.
I tried with digital ocean and EC2, different subdomains, but I always get same error:

ValueError: Wrote file to /var/www/default/challenges/g_1gc6VVSosIaplaaiPbp0I6RBSznMPsNpFKtbN8uNc, but couldn't download http://testme.afdevops.com/.well-known/acme-challenge/g_1gc6VVSosIaplaaiPbp0I6RBSznMPsNpFKtbN8uNc

I logged in a container - /var/www/default/challenges is empty.
If I create hello.html file there, I can reach it by URL http://testme.afdevops.com/.well-known/acme-challenge/hello.html
So I guess the problem is not in nginx.

# cat docker-compose.yml
https-portal:
  image: steveltn/https-portal
  ports:
    - '80:80'
    - '443:443'
  links:
    - wordpress
  restart: always
  environment:
    DOMAINS: 'testme.afdevops.com -> http://wordpress'
    # STAGE: 'production'
    # FORCE_RENEW: 'true'

wordpress:
  image: wordpress
  links:
    - db:mysql

db:
  image: mariadb
  environment:
    MYSQL_ROOT_PASSWORD: supersecretpassword 

Host not found in upstream after cert is obtained

Using latest image, trying to obtain valid certs for subdomains again after verifying against staging server. Missing something fundamental though. The docker-compose.yml has both my FQDN 'www.foo.cn' and a separate (sub)-domain 'clients.foo.cn' for https-portal env variables. So far I have been able to obtain certs for both as found in the linked folder on the host. And I verified that DNS is set up properly.

Simultaneously I launch a docker container with a virtual host of 'clients.foo.cn' with a simple flask app and the error below surfaces and https-portal dies. The flask container was working last week when I first obtained a cert for www.foo.cn. TIA for any assistance.

https-portal_1 | 2016/02/11 00:59:26 [emerg] 119#119: host not found in upstream "clients" in /etc/nginx/conf.d/clients.foo.cn.ssl.conf:18

here is the abbreviated docker-compose.yml

https-portal:
image: steveltn/https-portal:latest
ports:
- '80:80'
- '443:443'
environment:
DOMAINS: 'www.foo.cn, clients.foo.cn -> http://clients'
PRODUCTION: 'true'
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- /home/ubuntu/foo/foo:/var/lib/https-portal

...
clients:
image: danriti/docker-flask-nginx
environment:
# tell HTTPS-PORTAL to set up "example.com"
VIRTUAL_HOST: 'clients.foo.cn'
VIRTUAL_PROTO: https

connection is not secure/trusted in Firefox, Chrome, and Safari browsers

First of all, thanks for making this great docker image that uses lets encrypt for generating SSL certificates. I've tried this and my https seems to be working fine with this docker image. The following is my docker-compose, but all three browsers I tested still show unstructed/insecure connection. I am not sure if this is related to this https-portal or the certificates generated by letsencrypt is not trusted:

nginx_portal:
   image: steveltn/https-portal
   container_name: nginx_proxy_container
   ports:
    - "80:80"
    - "443:443"
   volumes:
    - ./ssl_letsen:/var/lib/https-portal
    - /var/run/docker.sock:/tmp/docker.sock:ro
   environment:
    DOMAINS: 'www.domain.com -> http://api:1337'

Visiting https://www.domain.com, I got warnings in my browsers. Any ideas what might be wrong? Thanks!

How can I test https-portal locally

Is it possible to run https-portal locally?
Whenever I try it, I get

Chrome: https://example.org    (/etc/hosts: 192.168.99.100  example.org)
This webpage is not available
ERR_CONNECTION_REFUSED

Entering docker-machine shows that port 443 and 80 are listening, but curl returns an SSL error:

docker@default:~$ curl https://127.0.0.1
curl: (35) Unknown SSL protocol error in connection to 127.0.0.1:443

My docker-compose.yml:

https-portal:
  image: steveltn/https-portal
  ports:
    - '80:80'
    - '443:443'
  environment:
    DOMAINS: 'example.org'

Nginx #403 error after static folder/file upload

Had a perfectly good working test blog (test.foo.cn) using the Lektor static site framework with their example. Developed another blog model, renders fine on localhost, upload to /vhosts file and getting a #403 error. The directory has permissions of 755 (sudo chmod 755 -R test*) and the files are all 644 (sudo chmod -R 644 *). I notice the vhost test.foo.cn has user 'ubuntu' and the www.foo.cn has 'root'. Any assistance would be appreciated.

drwxr-xr-x 9 ubuntu ubuntu 4096 Feb 24 01:54 test.foo.cn
drwxr-xr-x 2 root root 4096 Feb 24 01:40 www.foo.cn

nginx error message when using multiple domains

Hi, thank you very much for this great docker image!
I just tried to use it for one domain and it worked perfectly.
Afterwards I used the described way to include multiple domains, but nginx does not want to start anymore.

Error message:
2016/01/08 23:14:11 [emerg] 129#129: could not build server_names_hash, you should increase server_names_hash_bucket_size: 32
nginx: [emerg] could not build server_names_hash, you should increase server_names_hash_bucket_size: 32

Is there a way to specify something like this:

server_names_hash_bucket_size 64;

?

Thanks!

continues error while trying automatic discovery

Hi Steve,

this is awesome men, i can't wait to fully try this out.
I only get stuck with this bug all the time:

Attaching to nginx_acme_1
acme_1 | 2016/01/02 22:42:14 Generated '/var/run/domains' from 11 containers
acme_1 | 2016/01/02 22:42:14 Running 'reconfig'
acme_1 | 2016/01/02 22:42:15 Error running notify command: reconfig, exit status 1
acme_1 | 2016/01/02 22:42:15 2016/01/02 22:42:14 [notice] 27#27: signal process started
acme_1 | 2016/01/02 22:42:14 [emerg] 29#29: invalid number of arguments in "proxy_pass" directive in /etc/nginx/conf.d/asbitesttest.nl.ssl.conf:17
acme_1 | nginx: [emerg] invalid number of arguments in "proxy_pass" directive in /etc/nginx/conf.d/asbitesttest.nl.ssl.conf:17
acme_1 | /opt/certs_manager/lib/nginx.rb:3:in `initialize': No such file or directory @ rb_sysopen - /etc/nginx/conf.d/http://172.17.0.67:80 (Errno::ENOENT)
acme_1 | fotografieline.com.conf
acme_1 |    from /opt/certs_manager/lib/nginx.rb:3:in `open'
acme_1 |    from /opt/certs_manager/lib/nginx.rb:3:in `config_http'
acme_1 |    from /opt/certs_manager/certs_manager.rb:54:in `block in ensure_signed'
acme_1 |    from /opt/certs_manager/certs_manager.rb:53:in `each'
acme_1 |    from /opt/certs_manager/certs_manager.rb:53:in `ensure_signed'
acme_1 |    from /opt/certs_manager/certs_manager.rb:45:in `reconfig'
acme_1 |    from /bin/reconfig:4:in `<main>'
acme_1 | No need to re-sign certs for asbitesttest.nl, it will not expire in 90 days.
acme_1 | 2016/01/02 22:42:15 Watching docker events

could you please point me in the right direction?
my /etc/nginx/conf.d/asbitesttest.nl.ssl.conf:17 lines is like:

    location / {
        proxy_pass ;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }

many thanks already

Vhost not working after failed cert renew attempt

We have problem with non working virtual host entry after failed certificate renewal attempt. After failed renewal, vhost configuration was still set to acme challenge while certificate was still valid. We also had previous DNS problem, which probably triggered this behaviour. We changed certificate time to live threshold from 30 days to 10 days as quick workaround.

Log:

Signing certificates from https://acme-v01.api.letsencrypt.org ...
Parsing account key...
Parsing CSR...
Registering account...
Already registered!
Verifying domain1.com...
    raise ValueError("Error requesting challenges: {0} {1}".format(code, result))
  File "/bin/acme_tiny", line 104, in get_crt
    signed_crt = get_crt(args.account_key, args.csr, args.acme_dir, log=LOGGER, CA=args.ca)
  File "/bin/acme_tiny", line 194, in main
    main(sys.argv[1:])
  File "/bin/acme_tiny", line 198, in <module>
Traceback (most recent call last):
  "status": 429
  "detail": "Error creating new authz :: Too many currently pending authorizations.",
  "type": "urn:acme:error:rateLimited",
ValueError: Error requesting challenges: 429 {
}
Failed to obtain certs for domain1.com
Signing certificates from https://acme-v01.api.letsencrypt.org ...
Parsing account key...
Parsing CSR...
Registering account...
Already registered!
Verifying domain2.com...
  "status": 429
  "detail": "Error creating new authz :: Too many currently pending authorizations.",
  "type": "urn:acme:error:rateLimited",
ValueError: Error requesting challenges: 429 {
    raise ValueError("Error requesting challenges: {0} {1}".format(code, result))
  File "/bin/acme_tiny", line 104, in get_crt
    signed_crt = get_crt(args.account_key, args.csr, args.acme_dir, log=LOGGER, CA=args.ca)
  File "/bin/acme_tiny", line 194, in main
    main(sys.argv[1:])
  File "/bin/acme_tiny", line 198, in <module>
Traceback (most recent call last):
}
Failed to obtain certs for domain2.com
Signing certificates from https://acme-v01.api.letsencrypt.org ...
Parsing account key...
Parsing CSR...
Registering account...
Already registered!
Verifying domain3.com...
================================================================================
Failed to sign domain3.com, is DNS set up properly?
================================================================================
Failed to obtain certs for domain3.com
Signing certificates from https://acme-v01.api.letsencrypt.org ...
Parsing account key...
Parsing CSR...
Registering account...
Already registered!
Verifying domain4.com...
    raise ValueError("Error requesting challenges: {0} {1}".format(code, result))
  File "/bin/acme_tiny", line 104, in get_crt
    signed_crt = get_crt(args.account_key, args.csr, args.acme_dir, log=LOGGER, CA=args.ca)
  File "/bin/acme_tiny", line 194, in main
    main(sys.argv[1:])
  File "/bin/acme_tiny", line 198, in <module>
Traceback (most recent call last):
  "status": 429
  "detail": "Error creating new authz :: Too many currently pending authorizations.",
  "type": "urn:acme:error:rateLimited",
ValueError: Error requesting challenges: 429 {
}
Failed to obtain certs for domain4.com
Signing certificates from https://acme-v01.api.letsencrypt.org ...
Parsing account key...
Parsing CSR...
Registering account...
Already registered!
Verifying domain5.com...
    raise ValueError("Error requesting challenges: {0} {1}".format(code, result))
  File "/bin/acme_tiny", line 104, in get_crt
    signed_crt = get_crt(args.account_key, args.csr, args.acme_dir, log=LOGGER, CA=args.ca)
  File "/bin/acme_tiny", line 194, in main
    main(sys.argv[1:])
  File "/bin/acme_tiny", line 198, in <module>
Traceback (most recent call last):
  "status": 429
  "detail": "Error creating new authz :: Too many currently pending authorizations.",
  "type": "urn:acme:error:rateLimited",
ValueError: Error requesting challenges: 429 {
}
Failed to obtain certs for domain5.com
[cont-init.d] 00-setup: exited 0.
[cont-init.d] 10-set-docker-gen-status: executing...
[cont-init.d] done.
[cont-init.d] 10-set-docker-gen-status: exited 0.
[services.d] starting services
[services.d] done.
Starting crond ...
ValueError: Error requesting challenges: 503 <HTML><HEAD>
<TITLE>Service Unavailable</TITLE>
</HEAD><BODY>
    raise ValueError("Error requesting challenges: {0} {1}".format(code, result))
  File "/bin/acme_tiny", line 104, in get_crt
    signed_crt = get_crt(args.account_key, args.csr, args.acme_dir, log=LOGGER, CA=args.ca)
  File "/bin/acme_tiny", line 194, in main
    main(sys.argv[1:])
  File "/bin/acme_tiny", line 198, in <module>
Traceback (most recent call last):
Reference&#32;&#35;15&#46;57f01202&#46;1468846508&#46;b73b83e
The server is temporarily unable to service your request.  Please try again
<H1>Service Unavailable - Zero size object</H1>
later.<P>
</BODY></HTML>

ERR_TOO_MANY_REDIRECTS

screen shot 2016-04-20 at 20 46 52

I feel like I am making such a newbie mistake, but can't figure out why I am getting redirects, tried every possible variation of docker-compose.yml as well as read your "readme" dozens of times. I just can't seem to find the probably obvious mistake I am making so I am hoping I could get some assistance.

docker-compose.yml

https-portal:
  image: steveltn/https-portal
  ports:
    - '80:80'
    - '443:443'
  links:
    - web
  restart: always
  environment:
    DOMAINS: 'damir.tech -> http://damir.tech' #mistake is here probably 
    STAGE: 'production'
   # FORCE_RENEW: 'true'

web:
  image: wordpress
  links:
    - db:mysql
  volumes:
    - ~/wordpress/wp_html:/var/www/html
db:
  image: mariadb
  environment:
    MYSQL_ROOT_PASSWORD: 'nopetynopenope'

output after running docker-compose up

Attaching to wordpress_db_1, wordpress_web_1, wordpress_https-portal_1
db_1            | 2016-04-20 18:53:09 139960919779264 [Note] mysqld (mysqld 10.1.13-MariaDB-1~jessie) starting as process 1 ...
https-portal_1  | [fix-attrs.d] applying owners & permissions fixes...
https-portal_1  | [fix-attrs.d] 00-runscripts: applying...
db_1            | 2016-04-20 18:53:09 139960919779264 [Note] InnoDB: Using mutexes to ref count buffer pool pages
db_1            | 2016-04-20 18:53:09 139960919779264 [Note] InnoDB: The InnoDB memory heap is disabled
db_1            | 2016-04-20 18:53:09 139960919779264 [Note] InnoDB: Mutexes and rw_locks use GCC atomic builtins
db_1            | 2016-04-20 18:53:09 139960919779264 [Note] InnoDB: Memory barrier is not used
db_1            | 2016-04-20 18:53:09 139960919779264 [Note] InnoDB: Compressed tables use zlib 1.2.8
db_1            | 2016-04-20 18:53:09 139960919779264 [Note] InnoDB: Using Linux native AIO
db_1            | 2016-04-20 18:53:09 139960919779264 [Note] InnoDB: Using SSE crc32 instructions
db_1            | 2016-04-20 18:53:09 139960919779264 [Note] InnoDB: Initializing buffer pool, size = 256.0M
https-portal_1  | [fix-attrs.d] 00-runscripts: exited 0.
https-portal_1  | [fix-attrs.d] done.
https-portal_1  | [cont-init.d] executing container initialization scripts...
https-portal_1  | [cont-init.d] 00-setup: executing...
db_1            | 2016-04-20 18:53:09 139960919779264 [Note] InnoDB: Completed initialization of buffer pool
db_1            | 2016-04-20 18:53:09 139960919779264 [Note] InnoDB: Highest supported file format is Barracuda.
db_1            | 2016-04-20 18:53:09 139960919779264 [Note] InnoDB: 128 rollback segment(s) are active.
db_1            | 2016-04-20 18:53:09 139960919779264 [Note] InnoDB: Waiting for purge to start
web_1           |
web_1           | Warning: mysqli::mysqli(): (HY000/2002): Connection refused in - on line 10
web_1           |
web_1           | MySQL Connection Error: (2002) Connection refused
db_1            | 2016-04-20 18:53:09 139960919779264 [Note] InnoDB:  Percona XtraDB (http://www.percona.com) 5.6.28-76.1 started; log sequence number 1616849
db_1            | 2016-04-20 18:53:09 139960124409600 [Note] InnoDB: Dumping buffer pool(s) not yet started
db_1            | 2016-04-20 18:53:09 139960919779264 [Note] Plugin 'FEEDBACK' is disabled.
db_1            | 2016-04-20 18:53:09 139960919779264 [Note] Server socket created on IP: '::'.
db_1            | 2016-04-20 18:53:09 139960919779264 [Warning] 'proxies_priv' entry '@% root@bb18a24a41eb' ignored in --skip-name-resolve mode.
db_1            | 2016-04-20 18:53:09 139960919779264 [Note] mysqld: ready for connections.
db_1            | Version: '10.1.13-MariaDB-1~jessie'  socket: '/var/run/mysqld/mysqld.sock'  port: 3306  mariadb.org binary distribution
https-portal_1  | 2016/04/20 18:53:10 [notice] 121#121: signal process started
https-portal_1  | 2016/04/20 18:53:10 [notice] 125#125: signal process started
https-portal_1  | No need to re-sign certs for damir.tech, it will not expire in 90 days.
https-portal_1  | 2016/04/20 18:53:10 [notice] 128#128: signal process started
https-portal_1  | [cont-init.d] 00-setup: exited 0.
https-portal_1  | [cont-init.d] 10-set-docker-gen-status: executing...
https-portal_1  | [cont-init.d] 10-set-docker-gen-status: exited 0.
https-portal_1  | [cont-init.d] done.
https-portal_1  | [services.d] starting services
https-portal_1  | [services.d] done.
https-portal_1  | Starting crond ...
web_1           | AH00558: apache2: Could not reliably determine the server's fully qualified domain name, using 172.17.0.3. Set the 'ServerName' directive globally to suppress this message
web_1           | AH00558: apache2: Could not reliably determine the server's fully qualified domain name, using 172.17.0.3. Set the 'ServerName' directive globally to suppress this message
web_1           | [Wed Apr 20 18:53:12.979854 2016] [mpm_prefork:notice] [pid 1] AH00163: Apache/2.4.10 (Debian) PHP/5.6.20 configured -- resuming normal operations
web_1           | [Wed Apr 20 18:53:12.982923 2016] [core:notice] [pid 1] AH00094: Command line: 'apache2 -D FOREGROUND'
https-portal_1  | 172.17.0.1 - - [20/Apr/2016:18:53:22 +0000] "GET / HTTP/1.0" 301 178 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.112 Safari/537.36" "109.93.144.201"
https-portal_1  | 109.93.144.201 - - [20/Apr/2016:18:53:22 +0000] "GET / HTTP/2.0" 301 259 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.112 Safari/537.36" "-"
https-portal_1  | 109.93.144.201 - - [20/Apr/2016:18:53:22 +0000] "GET / HTTP/2.0" 301 259 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.112 Safari/537.36" "-"
https-portal_1  | 172.17.0.1 - - [20/Apr/2016:18:53:22 +0000] "GET / HTTP/1.0" 301 178 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.112 Safari/537.36" "109.93.144.201"
https-portal_1  | 109.93.144.201 - - [20/Apr/2016:18:53:22 +0000] "GET / HTTP/2.0" 301 259 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.112 Safari/537.36" "-"
https-portal_1  | 172.17.0.1 - - [20/Apr/2016:18:53:22 +0000] "GET / HTTP/1.0" 301 178 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.112 Safari/537.36" "109.93.144.201"
https-portal_1  | 109.93.144.201 - - [20/Apr/2016:18:53:22 +0000] "GET / HTTP/2.0" 301 259 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.112 Safari/537.36" "-"
https-portal_1  | 172.17.0.1 - - [20/Apr/2016:18:53:22 +0000] "GET / HTTP/1.0" 301 178 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.112 Safari/537.36" "109.93.144.201"
https-portal_1  | 109.93.144.201 - - [20/Apr/2016:18:53:22 +0000] "GET / HTTP/2.0" 301 259 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.112 Safari/537.36" "-"
https-portal_1  | 172.17.0.1 - - [20/Apr/2016:18:53:22 +0000] "GET / HTTP/1.0" 301 178 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.112 Safari/537.36" "109.93.144.201"
https-portal_1  | 109.93.144.201 - - [20/Apr/2016:18:53:23 +0000] "GET / HTTP/2.0" 301 259 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.112 Safari/537.36" "-"
https-portal_1  | 172.17.0.1 - - [20/Apr/2016:18:53:23 +0000] "GET / HTTP/1.0" 301 178 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.112 Safari/537.36" "109.93.144.201"
https-portal_1  | 109.93.144.201 - - [20/Apr/2016:18:53:23 +0000] "GET / HTTP/2.0" 301 259 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.112 Safari/537.36" "-"
https-portal_1  | 172.17.0.1 - - [20/Apr/2016:18:53:23 +0000] "GET / HTTP/1.0" 301 178 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.112 Safari/537.36" "109.93.144.201"
https-portal_1  | 109.93.144.201 - - [20/Apr/2016:18:53:23 +0000] "GET / HTTP/2.0" 301 259 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.112 Safari/537.36" "-"
https-portal_1  | 172.17.0.1 - - [20/Apr/2016:18:53:23 +0000] "GET / HTTP/1.0" 301 178 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.112 Safari/537.36" "109.93.144.201"
https-portal_1  | 109.93.144.201 - - [20/Apr/2016:18:53:23 +0000] "GET / HTTP/2.0" 301 259 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.112 Safari/537.36" "-"
https-portal_1  | 172.17.0.1 - - [20/Apr/2016:18:53:23 +0000] "GET / HTTP/1.0" 301 178 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.112 Safari/537.36" "109.93.144.201"
https-portal_1  | 109.93.144.201 - - [20/Apr/2016:18:53:23 +0000] "GET / HTTP/2.0" 301 259 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.112 Safari/537.36" "-"
https-portal_1  | 172.17.0.1 - - [20/Apr/2016:18:53:23 +0000] "GET / HTTP/1.0" 301 178 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.112 Safari/537.36" "109.93.144.201"
https-portal_1  | 109.93.144.201 - - [20/Apr/2016:18:53:23 +0000] "GET / HTTP/2.0" 301 259 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.112 Safari/537.36" "-"
https-portal_1  | 172.17.0.1 - - [20/Apr/2016:18:53:23 +0000] "GET / HTTP/1.0" 301 178 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.112 Safari/537.36" "109.93.144.201"
https-portal_1  | 109.93.144.201 - - [20/Apr/2016:18:53:23 +0000] "GET / HTTP/2.0" 301 259 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.112 Safari/537.36" "-"
https-portal_1  | 172.17.0.1 - - [20/Apr/2016:18:53:23 +0000] "GET / HTTP/1.0" 301 178 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.112 Safari/537.36" "109.93.144.201"
https-portal_1  | 109.93.144.201 - - [20/Apr/2016:18:53:23 +0000] "GET / HTTP/2.0" 301 259 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.112 Safari/537.36" "-"
https-portal_1  | 172.17.0.1 - - [20/Apr/2016:18:53:23 +0000] "GET / HTTP/1.0" 301 178 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.112 Safari/537.36" "109.93.144.201"
https-portal_1  | 109.93.144.201 - - [20/Apr/2016:18:53:23 +0000] "GET / HTTP/2.0" 301 259 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.112 Safari/537.36" "-"
https-portal_1  | 172.17.0.1 - - [20/Apr/2016:18:53:23 +0000] "GET / HTTP/1.0" 301 178 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.112 Safari/537.36" "109.93.144.201"
https-portal_1  | 109.93.144.201 - - [20/Apr/2016:18:53:23 +0000] "GET / HTTP/2.0" 301 259 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.112 Safari/537.36" "-"
https-portal_1  | 172.17.0.1 - - [20/Apr/2016:18:53:23 +0000] "GET / HTTP/1.0" 301 178 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.112 Safari/537.36" "109.93.144.201"
https-portal_1  | 109.93.144.201 - - [20/Apr/2016:18:53:23 +0000] "GET / HTTP/2.0" 301 259 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.112 Safari/537.36" "-"
https-portal_1  | 172.17.0.1 - - [20/Apr/2016:18:53:23 +0000] "GET / HTTP/1.0" 301 178 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.112 Safari/537.36" "109.93.144.201"
https-portal_1  | 109.93.144.201 - - [20/Apr/2016:18:53:23 +0000] "GET / HTTP/2.0" 301 259 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.112 Safari/537.36" "-"
https-portal_1  | 172.17.0.1 - - [20/Apr/2016:18:53:23 +0000] "GET / HTTP/1.0" 301 178 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.112 Safari/537.36" "109.93.144.201"
https-portal_1  | 109.93.144.201 - - [20/Apr/2016:18:53:23 +0000] "GET / HTTP/2.0" 301 259 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.112 Safari/537.36" "-"
https-portal_1  | 172.17.0.1 - - [20/Apr/2016:18:53:23 +0000] "GET / HTTP/1.0" 301 178 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.112 Safari/537.36" "109.93.144.201"
https-portal_1  | 109.93.144.201 - - [20/Apr/2016:18:53:23 +0000] "GET / HTTP/2.0" 301 259 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.112 Safari/537.36" "-"
https-portal_1  | 172.17.0.1 - - [20/Apr/2016:18:53:23 +0000] "GET / HTTP/1.0" 301 178 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.112 Safari/537.36" "109.93.144.201"
https-portal_1  | 109.93.144.201 - - [20/Apr/2016:18:53:23 +0000] "GET / HTTP/2.0" 301 259 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.112 Safari/537.36" "-"
https-portal_1  | 172.17.0.1 - - [20/Apr/2016:18:53:23 +0000] "GET / HTTP/1.0" 301 178 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.112 Safari/537.36" "109.93.144.201"
https-portal_1  | 109.93.144.201 - - [20/Apr/2016:18:53:23 +0000] "GET / HTTP/2.0" 301 259 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.112 Safari/537.36" "-"
https-portal_1  | 172.17.0.1 - - [20/Apr/2016:18:53:23 +0000] "GET / HTTP/1.0" 301 178 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.112 Safari/537.36" "109.93.144.201"
Gracefully stopping... (press Ctrl+C again to force)

Hopefully someone will come to my newbie aid ˚‧º·(˚ ˃̣̣̥᷄⌓˂̣̣̥᷅ )‧º·˚

is there anything I can do if I am getting 7 day throttled?

I can't pull a new cert and am afriad I am just pushing my throttle back another week?

https-portal_1  | Signing certificates from https://acme-v01.api.letsencrypt.org ...
https-portal_1  | Parsing account key...
https-portal_1  | Parsing CSR...
https-portal_1  | Registering account...
https-portal_1  | Registered!
https-portal_1  | Verifying malice.io...
https-portal_1  | malice.io verified!
https-portal_1  | Signing certificate...
https-portal_1  | Traceback (most recent call last):
https-portal_1  |   File "/bin/acme_tiny", line 198, in <module>
https-portal_1  |     main(sys.argv[1:])
https-portal_1  |   File "/bin/acme_tiny", line 194, in main
https-portal_1  |     signed_crt = get_crt(args.account_key, args.csr, args.acme_dir, log=LOGGER, CA=args.ca)
https-portal_1  |   File "/bin/acme_tiny", line 161, in get_crt
https-portal_1  |     raise ValueError("Error signing certificate: {0} {1}".format(code, result))
https-portal_1  | ValueError: Error signing certificate: 429 {
https-portal_1  |   "type": "urn:acme:error:rateLimited",
https-portal_1  |   "detail": "Error creating new cert :: Too many certificates already issued for exact set of domains: malice.io",
https-portal_1  |   "status": 429
https-portal_1  | }
https-portal_1  | 2016/10/09 18:49:24 [emerg] 143#143: SSL_CTX_use_PrivateKey_file("/var/lib/https-portal/malice.io/production/domain.key") failed (SSL: error:0B080074:x509 certificate routines:X509_check_private_key:key values mismatch)
https-portal_1  | nginx: [emerg] SSL_CTX_use_PrivateKey_file("/var/lib/https-portal/malice.io/production/domain.key") failed (SSL: error:0B080074:x509 certificate routines:X509_check_private_key:key values mismatch)
https-portal_1  | Signed key for malice.io
https-portal_1  | 2016/10/09 18:49:24 [emerg] 144#144: SSL_CTX_use_PrivateKey_file("/var/lib/https-portal/malice.io/production/domain.key") failed (SSL: error:0B080074:x509 certificate routines:X509_check_private_key:key values mismatch)
https-portal_1  | nginx: [emerg] SSL_CTX_use_PrivateKey_file("/var/lib/https-portal/malice.io/production/domain.key") failed (SSL: error:0B080074:x509 certificate routines:X509_check_private_key:key values mismatch)
https-portal_1  | [cont-init.d] 00-setup: exited 0.
https-portal_1  | [cont-init.d] 10-set-docker-gen-status: executing...
https-portal_1  | [cont-init.d] 10-set-docker-gen-status: exited 0.
https-portal_1  | [cont-init.d] done.
https-portal_1  | [services.d] starting services
https-portal_1  | [services.d] done.
https-portal_1  | Starting crond ...
https-portal_1  | 2016/10/09 18:49:25 [emerg] 173#173: SSL_CTX_use_PrivateKey_file("/var/lib/https-portal/malice.io/production/domain.key") failed (SSL: error:0B080074:x509 certificate routines:X509_check_private_key:key values mismatch)
https-portal_1  | nginx: [emerg] SSL_CTX_use_PrivateKey_file("/var/lib/https-portal/malice.io/production/domain.key") failed (SSL: error:0B080074:x509 certificate routines:X509_check_private_key:key values mismatch)
https-portal_1  | [cont-finish.d] executing container finish scripts...
https-portal_1  | [cont-finish.d] done.
https-portal_1  | [s6-finish] syncing disks.
https-portal_1  | [s6-finish] sending all processes the TERM signal.
https-portal_1  | 2016/10/09 18:49:25 [emerg] 122#122: SSL_CTX_use_PrivateKey_file("/var/lib/https-portal/malice.io/production/domain.key") failed (SSL: error:0B080074:x509 certificate routines:X509_check_private_key:key values mismatch)
https-portal_1  | [s6-finish] sending all processes the KILL signal and exiting.
maliceio_https-portal_1 exited with code 0

502 Bad Gateway error

I assume this is a temporary lets encrypt problem but wanted to make you aware anyway. I'm getting this for all my domains and as a result none of my servers are accessible. Is there any way to use previous certificates in case of failure like this so that servers can at least remain accessible?

2016/04/04 17:20:39 [notice] 122#122: signal process started
Signing certificates from https://acme-v01.api.letsencrypt.org ...
Parsing account key...
Parsing CSR...
Registering account...
Traceback (most recent call last):
  File "/bin/acme_tiny", line 198, in <module>
    main(sys.argv[1:])
  File "/bin/acme_tiny", line 194, in main
    signed_crt = get_crt(args.account_key, args.csr, args.acme_dir, log=LOGGER, CA=args.ca)
  File "/bin/acme_tiny", line 85, in get_crt
    "agreement": "https://letsencrypt.org/documents/LE-SA-v1.0.1-July-27-2015.pdf",
  File "/bin/acme_tiny", line 47, in _send_signed_request
    protected["nonce"] = urlopen(CA + "/directory").headers['Replay-Nonce']
  File "/usr/lib/python2.7/urllib2.py", line 154, in urlopen
    return opener.open(url, data, timeout)
  File "/usr/lib/python2.7/urllib2.py", line 437, in open
    response = meth(req, response)
  File "/usr/lib/python2.7/urllib2.py", line 550, in http_response
    'http', request, response, code, msg, hdrs)
  File "/usr/lib/python2.7/urllib2.py", line 475, in error
    return self._call_chain(*args)
  File "/usr/lib/python2.7/urllib2.py", line 409, in _call_chain
    result = func(*args)
  File "/usr/lib/python2.7/urllib2.py", line 558, in http_error_default
    raise HTTPError(req.get_full_url(), code, msg, hdrs, fp)
urllib2.HTTPError: HTTP Error 502: Bad Gateway
Failed to obtain certs for __my_domain__.com

Serving insecure content

Total noob question and nothing to do with an 'issue; with this code. Is there a way to isolate and serve non-secure content? I am trying to use a couple of Chinese services i.e. social media sharing button apps but they only serve their functionality/graphics using http://. TIA.

Serving static files with nginx, in a flask application

First of all, a big thanks for creating this. This will really save a lot of trouble for noob developers like me :).

I am creating a vanilla flask+gunicorn application, where static files are served by nginx. Here is a link to my current repo - https://github.com/kampta/https-portal-example

While nginx seems to be working alright, I keep getting this error

https-portal_1 | 2016/04/27 17:33:44 [error] 155#155: *2 connect() failed (111: Connection refused) while connecting to upstream, client: 122.166.166.183, server: staging.example.com, request: "GET / HTTP/2.0", upstream: "http://172.17.0.2:80/", host: "staging.example.com"
https-portal_1 | 122.166.166.183 - - [27/Apr/2016:17:33:44 +0000] "GET / HTTP/2.0" 502 626 "-" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.86 Safari/537.36" "-"
https-portal_1 | 2016/04/27 17:33:44 [error] 155#155: *2 connect() failed (111: Connection refused) while connecting to upstream, client: 122.166.166.183, server: staging.example.com, request: "GET /favicon.ico HTTP/2.0", upstream: "http://172.17.0.2:80/favicon.ico", host: "staging.example.com", referrer: "https://staging.example.com/"

Would you please be able to point me in the right direction?
Thanks again!

URGENT: Since I deployed my API in production

First of all, thanks a lot for the project. I have used this project and works very well. But for one project I need to use real IP of the request and can't seem to get it. I use nginx too for my app and tried to get several ways to get the requester IP and not able to.

Please help me.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.