Forkable website created with Docker, Flask, React (create-react-app), and Nginx.
In order to create a website from scratch you need to 1. aquire a host, 2. run a web application on that host, and 3. get a domain name that directs to your host. There are many different ways to stand up websites and most of them handle one or all of those three steps for you. Through the steps listed below I outline a way to do all those steps yourself as painlessly as possible. This way you will have almost total control over your website.
We'll use DigitalOcean for hosting, this project (docker-website-skeleton) as a basis for the web app, and namecheap for the domain name. Hosting and Domain names aren't free so have a credit card handy. However, this doesn't need to be expensive. Our shopping list will cost ~$10 all told.
These instructions are Windows-specific. If you're on Linux or Mac then you will do things slightly differently.
- Install git bash. Make sure you can open a git bash window.
- Try
cat ~/.ssh/id_rsa.pub
. If you get a result, move on to the next section. - If you did not get a result, run
ssh-keygen -t rsa -b 4096 -C "[email protected]"
and repeatedly press enter, accepting the defaults. Do not enter a password, just press enter. - Now try
cat ~/.ssh/id_rsa.pub
again. You should have a result.
You can host a website on any computer, but generally you don't want your website to go down every time you turn off your machine. It's going to be better to rent a host that never needs to go down (usually a virtual machine) from a hosting service. I like DigitalOcean for this, as you can buy a suitable host from them for $5 a month and they don't put any barriers between you and your host. Once you have it set up this little machine will be a great place to test any apps you create.
- Go to DigitalOcean's website and start creating your account.
- Once you get to the page where you provide your project details, be sure that you select "Docker" under the "tools and technologies that you plan to use on DigitalOcean." Other than that, everything is up to you.
- Soon you will find yourself on your project's DigitalOcean page. Under "Create a Droplet" click the Docker one. You have to hover over the Docker icon to see it.
- You're now creating your Droplet (aka "host" aka "node") that will host your website. DigitalOcean makes this
really easy. Under "Choose an image" make sure that Docker is selected.
- Scroll down to "Choose a plan". Wow, $40/month is expensive. Click the left arrow to find the $5/month option and select that instead!
- Scroll down to "Choose a datacenter region". Choose a datacenter in or nearby your country.
- Scroll down to "Authentication". Choose "SSH keys" and then click the "New SSH Key" button. Copy-paste the contents
of your
~/.ssh/id_rsa.pub
on your local machine, then click "Add SSH Key". Like this: - Scroll down to "Finalize and create". Change the hostname to something a little more human readable (I called mine
"tinydockernode01").
- Click "Create Droplet" at the bottom to finish. You should see a progress bar as your node spins up, then an IP address
when it is complete! Make a note of that IP address.
Congratulations, you are now the proud owner of a little linux node!
Now that you have a linux node, let's start doing things on it!
- Copy the IP address from your Droplet on DigitalOcean and ssh to it as root. My IP was 159.203.66.137 so I'll run
ssh [email protected]
. The first time you do this you'll need to type "yes" to say you trust your host.If all goes well your node should greet you like this:
- Let's go ahead and start docker swarm on our node.
Run
docker swarm init --advertise-addr XXX.XXX.XXX.XXX
whereXXX.XXX.XXX.XXX
is the IP address you used to connect to this node. - It'll also be nice to have a docker registry running on your swarm. You can do that by running
docker service create --name registry --publish published=5000,target=5000 registry:2
- Let's also set up authentication to github. Run
ssh-keygen -t rsa -b 4096 -C "[email protected]"
and repeatedly press enter. Thencat ~/.ssh/id_rsa.pub
and copy that result into a new ssh key on github. This way you can push and pull from github freely while on your droplet!
There quite a few other little quality-of-life things to do on your linux node, but above are the essentials. See this guide for instructions on how to set up your environment like I do mine.
- Create a fork of docker-website-skeleton (this repo) on github.
- On your fork, copy the ssh clone uri.
- Clone your fork onto your node using that uri:
cd
into your repo.docker-compose up --build
. This could take a while the first time, but on subsequent runs it should be decently fast.- Visit your website at
IP:3000
in your web browser. So for me I went to 159.203.66.137:3000. - Make any changes you wish to the frontend or API and see the changes reflected live. The only time you should need to rebuild is when you add new dependencies or change Docker or docker-compose configuration.
Your dev instance from the previous section is nice but to create an "official" instance of your project follow these steps. This instance will run in the background, will run on port 80, and will stay up indefinitely. These commands are based on https://docs.docker.com/engine/swarm/stack-deploy/
WEBSITE_VERSION=1.0.0 docker-compose -f docker-compose.prod.yml build
WEBSITE_VERSION=1.0.0 docker-compose -f docker-compose.prod.yml push
WEBSITE_VERSION=1.0.0 docker stack deploy -c docker-compose.prod.yml my-website
- Watch your website get replicated by typing
docker service ls
. - Visit your website by just typing your IP into your browser. Your browser connects to port 80 by default!
Whenever you want to update the "production" version of your website you can run the above commands again but with a new WEBSITE_VERSION.
When you fix a bug, increment the third number in the WEBSITE_VERSION (so 1.0.0 would become 1.0.1). When you add new features increment the second number and zero out the last number (so 1.0.1 would become 1.1.0). When you make a major overhaul increment the first number and zero out the other two (so 1.1.0 would become 2.0.0).
You don't want to have to reach your website at an IP all the time. Here's how you can get a domain name and attach it to your droplet.
- Visit namecheap.com
- Search for the domain name you want. You can't go wrong by claiming your name. I've already claimed lamsorsen.com, so in this example I'll claim lamsorsen.xyz. The suffix (.com, .net, .xyz, .pizza, etc) shouldn't matter for these purposes so choose something fun and cheap!
- Check out. You can keep any default config (whois guard, etc).
- Once you've paid, click the "Manage" button next to your domain on the "Thank you for your purchase" page.
- On the next page, click "Manage" again.
- On this page delete the redirect domain by clicking the trash can. Under "Nameservers" select "Custom DNS" and put
ns1.digitalocean.com
,ns2.digitalocean.com
, andns3.digitalocean.com
as the nameservers. Be sure to hit the little green checkmark when you're done. - Also, scroll down and under "Other Domain Settings" turn off the parking page.
- Alright, now go back to DigitalOcean. Click the three dots next to your droplet and click "Add a Domain".
- Add your www. your domain as a domain.
- Once that's successful, click the three dots next to your droplet and click "Add a Domain" again. This time, add
your domain without the www. prefix. Here's what your main DigitalOcean page should look like when you're done:
- Now all that's left to do is wait! It takes 30 minutes to a few hours for the changes on Namecheap's end to propagate.
When you come back later you should be able to visit your domain and see your website!