Skip to content

Instantly share code, notes, and snippets.

@jshimko
Last active February 25, 2022 10:11
Show Gist options
  • Save jshimko/745ca66748846551692e24c267a56060 to your computer and use it in GitHub Desktop.
Save jshimko/745ca66748846551692e24c267a56060 to your computer and use it in GitHub Desktop.
Deploy Reaction Commerce on Digital Ocean with Nginx and a Let's Encrypt SSL certificate
# start a server on Digital Ocean
# https://docs.docker.com/machine/drivers/digital-ocean/
docker-machine create \
--driver digitalocean \
--digitalocean-access-token <YOUR API KEY> \
--digitalocean-size 2gb \
reaction
# tell Docker to run commands on that server
eval "$(docker-machine env reaction)"
# Nginx
# https://github.com/jwilder/nginx-proxy
docker run -d -p 80:80 -p 443:443 \
--name nginx-proxy \
-v /opt/certs:/etc/nginx/certs:ro \
-v /etc/nginx/vhost.d \
-v /usr/share/nginx/html \
-v /var/run/docker.sock:/tmp/docker.sock:ro \
jwilder/nginx-proxy:latest
# Let's Encrypt
# https://github.com/JrCs/docker-letsencrypt-nginx-proxy-companion
docker run -d \
--name lets-encrypt \
--volumes-from nginx-proxy \
-v /opt/certs:/etc/nginx/certs:rw \
-v /var/run/docker.sock:/var/run/docker.sock:ro \
jrcs/letsencrypt-nginx-proxy-companion:latest
# Reaction
# https://github.com/reactioncommerce/reaction
docker run -d \
--name reaction \
--restart always \
-e MONGO_URL="mongodb://some-url" \
-e ROOT_URL="https://yoursite.com" \
-e VIRTUAL_HOST="yoursite.com" \
-e VIRTUAL_PORT=3000 \
-e LETSENCRYPT_EMAIL="[email protected]"
-e LETSENCRYPT_HOST="yoursite.com"
reactioncommerce/reaction:latest
@jshimko
Copy link
Author

jshimko commented Jun 13, 2016

Yep. You can also just build a custom nginx container with your own config. The Dockerfile might look something like...

FROM jwilder/nginx-proxy:latest

RUN sed -i 's/^http {/&\n    proxy_busy_buffers_size   256k;/g' /etc/nginx/nginx.conf && \
    sed -i 's/^http {/&\n    proxy_buffers   4 256k;/g' /etc/nginx/nginx.conf && \
    sed -i 's/^http {/&\n    proxy_buffer_size   128k;/g' /etc/nginx/nginx.conf

Then...

# build
docker build -t custom-nginx .

# run
docker run -d -p 80:80 -p 443:443 \
  --name nginx-proxy \
  -v /opt/certs:/etc/nginx/certs:ro \
  -v /etc/nginx/vhost.d \
  -v /usr/share/nginx/html \
  -v /var/run/docker.sock:/tmp/docker.sock:ro \
  custom-nginx

@owenhoskins
Copy link

Ah great, that saves manually editing the default.conf each docker run! More info on customizing nginx-proxy to be found here: Custom Nginx Configuration. Thanks!

@owenhoskins
Copy link

I've just followed this procedure with another digitalocean docker machine. This time around lets encrypt seems to be having trouble setting the certificate:

2016/06/22 04:51:32 Received event start for container 007e47a77fca
2016/06/22 04:51:47 Debounce minTimer fired
2016/06/22 04:51:47 Generated '/app/letsencrypt_service_data' from 2 containers
2016/06/22 04:51:47 Running '/app/update_certs'
Creating/renewal prize-editions.com certificates... (prize-editions.com)
2016-06-22 04:51:47,656:INFO:simp_le:1211: Generating new account key
2016-06-22 04:51:47,806:INFO:requests.packages.urllib3.connectionpool:756: Starting new HTTPS connection (1): acme-v01.api.letsencrypt.org
2016-06-22 04:51:48,041:INFO:requests.packages.urllib3.connectionpool:756: Starting new HTTPS connection (1): acme-v01.api.letsencrypt.org
2016-06-22 04:51:48,297:INFO:requests.packages.urllib3.connectionpool:756: Starting new HTTPS connection (1): acme-v01.api.letsencrypt.org
2016-06-22 04:51:48,557:INFO:requests.packages.urllib3.connectionpool:756: Starting new HTTPS connection (1): letsencrypt.org
2016-06-22 04:51:49,104:INFO:requests.packages.urllib3.connectionpool:756: Starting new HTTPS connection (1): acme-v01.api.letsencrypt.org
2016-06-22 04:51:49,368:INFO:requests.packages.urllib3.connectionpool:756: Starting new HTTPS connection (1): acme-v01.api.letsencrypt.org
2016-06-22 04:51:49,651:INFO:requests.packages.urllib3.connectionpool:207: Starting new HTTP connection (1): prize-editions.com
2016-06-22 04:51:49,731:WARNING:simp_le:1303: prize-editions.com was not successfully self-verified. CA is likely to fail as well!
2016-06-22 04:51:49,751:INFO:requests.packages.urllib3.connectionpool:756: Starting new HTTPS connection (1): acme-v01.api.letsencrypt.org
2016-06-22 04:51:49,995:INFO:simp_le:1313: Generating new certificate private key
2016-06-22 04:51:50,290:INFO:requests.packages.urllib3.connectionpool:756: Starting new HTTPS connection (1): acme-v01.api.letsencrypt.org
2016-06-22 04:51:50,516:ERROR:simp_le:1271: CA marked some of the authorizations as invalid, which likely means it could not access http://example.com/.well-known/acme-challenge/X. Did you set correct path in -d example.com:path or --default_root? Is there a warning log entry about unsuccessful self-verification? Are all your domains accessible from the internet? Failing authorizations: https://acme-v01.api.letsencrypt.org/acme/authz/lVZE4qLVAVHnZQnAHEBMJFr8zApX8yqV76DTP5BZ1Yo
Challenge validation has failed, see error log.

Debugging tips: -v improves output verbosity. Help is available under --help.
Sleep for 3600s

I recently pointed the DNS to the IP, I wonder if that could be the cause of this... any ideas? Much appreciated.

@jshimko
Copy link
Author

jshimko commented Jul 1, 2016

Your NGINX container needs to be reachable from the public internet on port 80 (which it likely isn't if you're on your laptop on a private network). The domain name you're requesting a certificate for needs to resolve to an IP that Let's Encrypt can reach. Their servers check that you own the domain name by making a request to that IP (which sends its a response via the linked NGINX container).

So in short, if you're running this on your laptop on your home network or don't have port 80 open, it isn't going to work because Let's Encrypt can't make the handshake it needs.

@lcampanis
Copy link

lcampanis commented Oct 30, 2016

Hi @jshimko,

Thanks for everything thus far. We are about to launch our first custom reaction container using the suggested gist.

Another setup could be to have your custom nginx config sitting outside the container, mapped to a folder on the host using:

# map a server config into nginx with custom options as suggested by @owenhoskins
docker run -d -p 80:80 -p 443:443 \
  --name nginx-proxy \
  -v /etc/nginx/nginx.conf:/etc/nginx/conf.d/my_proxy.conf:ro \
  -v /opt/certs:/etc/nginx/certs:ro \
  -v /etc/nginx/vhost.d \
  -v /usr/share/nginx/html \
  -v /var/run/docker.sock:/tmp/docker.sock:ro \
  jwilder/nginx-proxy

/etc/nginx/nginx.conf is the folder/custom-config.conf on your host, and /etc/nginx/conf.d/my_proxy.conf:ro is the config within the nginx container. Note nginx isn't setup on the host machine, this is only a file holding a config.

@hrath2015
Copy link

Need 1 help, @jshimko. How to run reaction on port other than 3000(say 4000) with nginx proxy.

@jshimko
Copy link
Author

jshimko commented Jan 17, 2017

@hrath2015 You need to use the VIRTUAL_PORT environment variable on your app container.

docker run -d \
  -e MONGO_URL="mongodb://some-url" \
  -e ROOT_URL="https://yoursite.com" \
  -e VIRTUAL_HOST="yoursite.com" \
  -e VIRTUAL_PORT=3000 \
  -e LETSENCRYPT_EMAIL="[email protected]"
  -e LETSENCRYPT_HOST="yoursite.com"
  reactioncommerce/reaction:latest

@jshimko
Copy link
Author

jshimko commented Jan 17, 2017

Keep in mind that you don't need to expose ports on your app container when you use nginx-proxy. They can talk internally via the Docker network interface. So I recommend just leaving the app at 3000 because it won't interfere with anything else on the host.

@shsunmoonlee
Copy link

shsunmoonlee commented Apr 17, 2017

The third docker command in the guide missed \ character at the end.
It should be

docker run -d \
  --name reaction \
  --restart always \
  -e MONGO_URL="mongodb://some-url" \
  -e ROOT_URL="https://yoursite.com" \
  -e VIRTUAL_HOST="yoursite.com" \
  -e VIRTUAL_PORT=3000 \
  -e LETSENCRYPT_EMAIL="[email protected]" \
  -e LETSENCRYPT_HOST="yoursite.com" \
  reactioncommerce/reaction:latest

@curranabell
Copy link

@jshimko

Hi I attempted to deploy reactioncommerce to digitalocean with a lets encrypt ssl by following this guide but I have several errors and problems. The first problem is that I have a "503 Service Temporarily Unavailable nginx/1.11.13" on the domain name I have attached my droplet too "naturalmedicinepharmacy.com".

After deploying the container I got the error

“docker: Error response from daemon: driver failed programming external connectivity on endpoint reaction (b708f485bce1d37366ea5787c6432e607bed6d5a8f30c0d5f413b06cede11a7e): Bind for 0.0.0.0:80 failed: port is already allocated.”

If you have any solutions that would be great. Thank You!

Here is what I deployed with docker:

docker-machine create
--driver digitalocean
--digitalocean-access-token
--digitalocean-size 512mb
--digitalocean-region sfo1
reaction

eval "$(docker-machine env reaction)"

docker run -d -p 80:80 -p 443:443
--name nginx-proxy
-v /opt/certs:/etc/nginx/certs:ro
-v /etc/nginx/vhost.d
-v /usr/share/nginx/html
-v /var/run/docker.sock:/tmp/docker.sock:ro
jwilder/nginx-proxy:latest

docker run -d
--name lets-encrypt
--volumes-from nginx-proxy
-v /opt/certs:/etc/nginx/certs:rw
-v /var/run/docker.sock:/var/run/docker.sock:ro
jrcs/letsencrypt-nginx-proxy-companion:latest

docker run -d
--name reaction
--restart always
-p 80:3000
-e MONGO_URL="mongodb://SERVER-IP-ADDRESS“
-e ROOT_URL="https://naturalmedicinepharmacy.com"
-e REACTION_EMAIL=“my-email”
-e REACTION_USER=“username”
-e REACTION_AUTH=“password”
-e VIRTUAL_HOST="naturalmedicinepharmacy.com"
-e VIRTUAL_PORT=3000
-e LETSENCRYPT_EMAIL=“my-email”
-e LETSENCRYPT_HOST=“naturalmedicinepharmacy.com”
reactioncommerce/reaction:latest

@shsunmoonlee
Copy link

For those who get

[error] 51#51: *5 upstream sent too big header while reading response header from upstream, 
client: 192.168.99.1, server: reaction.dev, request: "GET / HTTP/1.1", 
upstream: "http://172.17.0.5:80/", host: "reaction.dev"

solution is here below.
reactioncommerce/reaction#1075

@shsunmoonlee
Copy link

For those who have trouble getting latest docker image of reaction commerce,

#when there are outdated dockers , remove them
docker images -f dangling=true
docker rmi $(docker images -f dangling=true -q)

docker pull reaction:latest
docker run blablabla

hope it helps .
cheers

@rajeevjan1991
Copy link

rajeevjan1991 commented Jul 31, 2018

installing it on digital ocean .
getting error :
"docker run" requires at least 1 argument.
See 'docker run --help'.
Usage: docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
Run a command in a new container"

I have follow the step but getting error(PFA) while running below command.
docker run -d
--name eybii
--restart always
-e MONGO_URL="mongodb://mongodb1"
-e ROOT_URL="https://eybii.com"
-e VIRTUAL_HOST="eybii.com"
-e VIRTUAL_PORT=3000
-e LETSENCRYPT_EMAIL="[email protected]"
-e LETSENCRYPT_HOST="eybii.com"
reactioncommerce/reaction:latest
screenshot 396

@rajeevjan1991
Copy link

please let me know how to change buffer_size of nginx??
i did try the following but not success(after running reaction commerce website throw me same 502 error and code removed from default.conf)

vim /etc/nginx/conf.d/default.conf

proxy_buffer_size          128k;
proxy_buffers              4 256k;
proxy_busy_buffers_size    256k;

@nonfungibletunji
Copy link

nonfungibletunji commented Dec 31, 2018

I am getting a 503 bad gateway error, are these instructions still good, for version 1.7.1, that's been customized

@priyankaa02
Copy link

priyankaa02 commented May 28, 2019

Hi guys, I am getting 503 Service Temporarily Unavailable when running this script, can any one help me to know , what's wrong with this?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment