[Almost free] How to get a domain and SSL certificate for 0 yen using Freenom and Let's Encrypt, put docker in AWS EC2, start an nginx container, and launch an HTTPS WEB service that connects with the domain

Background

When you want to try a technology used for business or a new technology, set up a web server on AWS, prepare an API or test page, connect with http from a local Chrome or Android terminal, and do a lot of things. .. If you want to check the communication of RestAPI, that's fine, but if you want to use it for WebRTC or WebSocket verification, there was a problem that you could not check the operation because an error would occur unless the site was SSL-enabled. After investigating whether it would be possible to set up a web server that is cheap and not an oleore certificate somehow, it turned out that if you use Freenom and Let's Encrypt, you can set up an https server with your own domain almost for free.

There are fragments of how to get a domain with Freenom, how to get an SSL certificate with Let's Encrypt, and how to set them on AWS, but I didn't have a complete article, so I'll leave it here as a memorandum. Keep it.

things to do

  1. [Free] Get a free domain with Freenom
  2. [Conditional free] Create an AWS EC2 instance and install docker
  3. [Conditional Free] Issue a static IP address on AWS Elastic IP and associate it with an EC2 instance
  4. [Almost free] Set DNS on AWS Route53 so that you can connect to an EC2 instance with a domain name
  5. [Free] Launch an nginx container on an EC2 instance with docker
  6. [Free] Get a free SSL certificate with Let's Encrypt and connect with https

Free terms and almost free details

--AWS EC2 instances use free tier --You can use Amazon Machine Image (AMI), which is described as a free usage frame, for 750 hours a month for free. This time it will be free by using it --Keep EC2 instances assigned with Elastic IP running --If the IP address issued by Elastic IP is not associated with the EC2 instance, you will be charged. I haven't checked how much it will be charged, but it seems to be small. The reason for this mechanism is to prevent unnecessary IP addresses from being secured. --AWS Route 53 charges $ 0.5 a month --The following is an excerpt from the official (as of November 2020). Well, this is about half a canned coffee, which is good. image.png

1. [Free] Get a free domain with Freenom

I will do it immediately. The domain is obtained using a service called Freenom. Freenom is an overseas service that allows you to acquire a domain for free. You can get the domain name such as XXXX.tk, XXXX.ml, XXXX.ga for free. https://www.freenom.com/ja/index.html

Make sure your domain is available and check out

You can get the domain you like, so enter the domain you want to get. Check if it is available, and if it is available, the screen below will be displayed. Click "Get it now!" And then "Checkout".

image.png


image.png

Select the usage period

It seems that you can use it for free for up to 12 months, so let's use it to the maximum. Select "12 Months @ FREE" in Period and press "Continue".

image.png

User registration or login

** Make sure the amount is $ 0.00USD (free) **. If there is no problem, log in for purchase. In my case, I have already registered, so I usually log in with Google. If you have not registered for the first time, you may have to register in various ways. image.png

Agree to the terms and purchase

Again, ** confirm that the amount is $ 0.00USD (free) **, check the terms and conditions, and press "Complete Order".

image.png


image.png


image.png

This completes the acquisition of the domain.

2. [Conditional free] Create an AWS EC2 instance and install docker

You can use another article I wrote as it is, so please refer to here ↓.

How to install docker and docker-compose on AWS EC2 instance and launch a simple web service

3. Issue a static IP address on AWS Elastic IP and associate it with your EC2 instance

Get a static IP address (fixed IP address) and assign that IP address to the EC2 instance launched above. By doing this, the IP address will not change even if you restart EC2.

Get a static IP address

First, operate the screen to get a static IP address. Press "Elastic IP" and image.png Click "Assign Elastic IP Address" on the next screen. image.png Click "Assign" on the next screen. image.png I got a static IP address. image.png

Associate a static IP address with your EC2 instance

Select the assigned IP address and press "Associate Elastic IP Address" in "Action". image.png For the instance, enter the EC2 instance ID you created earlier. After entering, click "Associate". image.png

The association between the EC2 instance and the static IP address is complete. image.png

4. [Almost free] Set DNS on AWS Route53 so that you can connect to an EC2 instance with a domain name.

Set the DNS so that you can connect with the domain name. The procedure is to create a host zone → register A record → set Nameserver with Freenom.

Creating a host zone

Go to the Route53 screen and image.png Click "Host Zone". image.png Click "Create Host Zone". image.png Enter the domain obtained by Freenom and click "Create Host Zone". image.png The host zone has been created. image.png

Creating an A record

Click "Create Record". image.png Confirm that Simple Routing is selected by default and click "Next". image.png Click "Define a simple record". image.png After selecting "IP address according to record type or another value" in the value / traffic routing destination, enter the static IP address obtained earlier and press "Define simple record". image.png Click Create Record. image.png The record creation is complete. image.png

Nameserver settings

Now set the Nameserver in Freenom.

Press "My Domains" and then "Manage Domain" on the next screen.

image.png


image.png Click "Name servers" in "Management Tools". image.png Select "Use custom nameservers (enter below)" and copy the value of the NS record for the Route53 host zone in the Nameserver field. After entering, press "Change Name servers". image.png

After a few minutes at this point, DNS will penetrate and the site will be displayed with "http: // domain name". image.png

5. [Free] Launch an nginx container on an EC2 instance with docker

6. [Free] Get a free SSL certificate with Let's Encrypt and connect with https

5 and 6 are done at once. I think there are various ways to do it, but I will try using docker with the following configuration.

--reverse-Open the ploxy container to the Internet and accept https communication. --Reverse-Transfer communication from ploxy container to web container, web container accepts http communication from reverse-ploxy.

Untitled Diagram.png

Stop all dockers

To prevent malfunction, it is a good idea to stop all docker containers once and delete all docker objects before starting work.

docker stop $(docker ps -q)
docker system prune -a

Create and launch a web container

Create a web directory under the home directory and create the necessary configuration files.

cd
mkdir web

The structure under the directory and the contents of the files are as follows.

Directory structure


web
  - html
      - index.html #Write it as hoge
  - docker-compose.yml

docker-compose.yml


version: '3'

services:
  web:
    image: nginx:latest
    container_name: web
    volumes:
      - ./html:/usr/share/nginx/html

After creating it, start the docker container.

docker-compose up -d --build

Confirm that it has started.

docker-compose ps
Name              Command               State   Ports
------------------------------------------------------
web    /docker-entrypoint.sh ngin ...   Up      80/tcp

Creating and launching a reverse proxy container

Create a reverse-ploxy directory under your home directory and create the necessary configuration files.

cd
mkdir reverse-ploxy

As a result of struggling, the contents of the files and under the directory have been configured as follows.

Directory structure


reverse-proxy
  - reverse-proxy
    - default.conf
    - Dockerfile
    - entrypoint.sh
  - docker-compose.yml

default.conf


server{

    server_name y-do.tk;

    proxy_redirect off;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-Host $host;
    proxy_set_header X-Forwarded-Server $host;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

    location / {
      proxy_pass     http://web/;
    }

}

Dockerfile


FROM nginx

COPY default.conf /etc/nginx/conf.d/default.conf

RUN cp /usr/share/zoneinfo/Asia/Tokyo /etc/localtime

RUN apt-get update && apt-get install -y \
  wget cron && \
  apt-get clean && \
  rm -rf /var/lib/apt/lists/*

ADD https://raw.githubusercontent.com/vishnubob/wait-for-it/master/wait-for-it.sh /usr/local/bin/wait-for-it.sh
RUN chmod +x /usr/local/bin/wait-for-it.sh

ADD https://dl.eff.org/certbot-auto /usr/local/bin/certbot-auto
RUN chmod a+x /usr/local/bin/certbot-auto
RUN certbot-auto --os-packages-only -n

COPY ./entrypoint.sh /usr/local/bin/entrypoint.sh
RUN chmod +x /usr/local/bin/entrypoint.sh

ENTRYPOINT ["entrypoint.sh"]

entrypoint.sh


#!/bin/bash

# [email protected] is an email address
certbot-auto --nginx -d y-do.tk -m [email protected] --agree-tos -n
certbot-auto renew

# cron job settings
# Let's Encrypt automatic Renew
echo '0 8 * * * certbot-auto renew --post-hook "nginx -s reload"' >> /cron-tmpfile
crontab /cron-tmpfile
rm /cron-tmpfile

# cron start
/etc/init.d/cron start

/bin/bash

docker-compose.yml


version: '3'

services:
  reverse-proxy:
    build: ./reverse-proxy
    tty: true
    container_name: reverse-proxy
    logging:
      driver: "json-file"
      options:
        max-size: "10m"
        max-file: "3"
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - '/srv/letsencrypt:/etc/letsencrypt'
    command: ["wait-for-it.sh", "web:80"]
    networks:
      - default
      - web_default

networks:
  web_default:
    external: true

After creating it, start the docker container.

docker-compose up -d --build

Confirm that it has started.

docker-compose ps
    Name                   Command               State                    Ports
-------------------------------------------------------------------------------------------------
reverse-proxy   entrypoint.sh wait-for-it. ...   Up      0.0.0.0:443->443/tcp, 0.0.0.0:80->80/tcp

Update security groups on AWS to connect via https from the internet

Since it is played by FW, https communication cannot be accepted from the Internet yet. Modify the AWS security group inbound rules.

Add a rule and enter the type "HTTPS" and the source "0.0.0.0/0". After entering, click "Save Rule".

image.png

Operation check

At this point, you should finally be able to communicate via https. I will try to access it.

image.png


image.png

I was able to access it! !! !!

result

You can operate an SSL site with your own domain for 0.5 USD per month. However, the domain expires in 12 months and the SSL certificate expires in 3 months (I can't complain because it's free), so I'd like to introduce an automatic renewal mechanism in the future.

Recommended Posts

[Almost free] How to get a domain and SSL certificate for 0 yen using Freenom and Let's Encrypt, put docker in AWS EC2, start an nginx container, and launch an HTTPS WEB service that connects with the domain
Wait for PostgreSQL to start with Docker and then start the WEB service
Wait for the container service to start with docker healthcheck
[For beginners] Laravel Docker AWS (EC2) How to easily deploy a web application (PHP) from 0 (free) ①-Overview-
How to start a Docker container with a volume mounted in a batch file
Creating an SSL certificate using Let's Encrypt and setting up Nginx on Ubuntu 20
[Docker] How to update using a container on Heroku and how to deal with Migrate Error
[Docker] How to see the contents of Volumes. Start a container with root privileges.