Hi all!
Recently I had to setup a few small Docker containers for a couple of small websites.
As the sites were really small I didn’t want to run each one on a separate Droplet, so instead, I used Nginx with separate Nginx server blocks for each site and a reverse proxy for each Docker container.
Here’s how I set that up:
These answers are provided by our Community. If you find them useful, show some love by clicking the heart. If you run into issues leave a comment, or add your own answer to help others.
Before you start, make sure to have Docker and Nginx installed, here’s how to do that:
https://www.digitalocean.com/community/tutorials/how-to-install-nginx-on-ubuntu-18-04
Once you have both installed, you can continue with the steps:
For the same of simplicity, I will run a simple and I’ll run 2 small httpd
containers.
8080
on your host:docker run -dit --name container-1 -p 8080:80 httpd:2.4
Now if you visit http://your-dropets-ip:8080, you should be able to see a message saying It Works!
.
Just so that we could differentiate the two containers, let’s update the It works!
message with Container 1
for example:
docker ps
Then run the following sed
command to update the message:
docker exec CONTAINER_ID sed -i 's/It works!/Container 1/' /usr/local/apache2/htdocs/index.html
```
This would basically run a search and replace for the `It works!` string and update it with `Container 1` in the default `index.html` file in the container itself.
If you visit your Droplet's IP again in your browser the message should change from `It works!` to `Container 1`.
Let's do the same thing for container 2, but map it to port `8081` instead:
```
docker run -dit --name container-2 -p 8081:80 httpd:2.4
```
Then agian get your container ID
```
docker ps
```
Then run the `sed` command again to update the `It works!` message to `Container 2`:
docker exec CONTAINER_ID sed -i ‘s/It works!/Container 2/’ /usr/local/apache2/htdocs/index.html
Now if you visit http://your-dropets-ip:8081, you should be able to see a message saying `Container 2`.
## Step 2 - Configure Nginx
Now that we have our containers up and running we can go ahead and configure our Nginx server blocks, I will go ahead and use the following two subdomain names for this example:
* container1.bobbyiliev.com
* container2.bobbyiliev.com
To keep things as simple as possible, I will create 2 server blocks with the following content:
* Server block #1:
Create a new file called `container1.bobbyiliev.com.conf` in the `/etc/nginx/sites-available/` directory and add the following content:
server { listen 80; server_name container1.bobbyiliev.com;
location / { proxy_pass http://localhost:8080; } }
* Server block #2:
Create a new file called `container2.bobbyiliev.com.conf` in the `/etc/nginx/sites-available/` directory and add the following content:
server { listen 80; server_name container2.bobbyiliev.com;
location / { proxy_pass http://localhost:8081; } }
Then once you have the two config files ready `cd` to the `/etc/nginx/sites-enabled` directory, and run the following commands:
ln -s …/sites-available/container1.bobbyiliev.com.conf .
ln -s …/sites-available/container2.bobbyiliev.com.conf .
Run a config test to make sure that there are no errors:
nginx -t
And if you get `Syntax OK` message, restart Nginx:
systemctl restart nginx
Note, for more information about Nginx server blocks, I would recommend taking a look at this tutorial here:
https://www.digitalocean.com/community/tutorials/how-to-set-up-nginx-server-blocks-virtual-hosts-on-ubuntu-16-04
## Step 3 - Test the setup
That is pretty much it, now if I visit container1.bobbyiliev.com I should be able to see the `Container 1` message and the same for container2.bobbyiliev.com.
To test that I could run a simple `curl` request:
```command
curl container1.bobbyiliev.com
You should see the following output
<h1>Container 1</h1>
Then run the same request for container2.bobbyiliev.com:
- curl container2.bobbyiliev.com
And agian you should see the following output
<h1>Container 2</h1>
Here’s a quick video demo on how to do the above:
Now you have 2 different containers on the same Droplet being served from different domain names! Of course, this is just a very basic example, you could go a lot further by expanding your Nginx config a lot more, for example adding more headers to your Nginx proxy pass and even installing a Let’s Encrypt SSL.
Hope that this helps! Let me know if you have any questions! Regards, Bobby
Hi Bobby, Thank you very much for your tutorial,
What I want to achieve seems quite straightforward but I’ve been battling it for days now
I have a container for my frontend react app pulled in and running, same for my node-typescript app.
I mapped the frontend to port 3000 and the backend to 8000
I then set up Nginx to route the root requests to 3000 and then the request to the IP:8000 to /api
The frontend works fine but for some reason, I can’t seem to get the backend to work the way I want it.
When I visit the http://myIP:8000 it works from postman but when I use my https://server_address/api, the request comes back as bad gateway, tried a couple of solutions online but to no avail yet.
I will look forward to your response
Hi @bobbyiliev !
Thank you for your swift reply, this sorted things out. I created a ’ docker-compose.yml-file for all 3 containers, kept the nginx-proxy.conf :
And nginx-proxy.conf according to your instructions
Thanks for that clarification, it really helped!
Another way that works the same way ? Still, if I leave the out the nginx-proxy.conf-file then the following attributes ‘VIRTUAL_HOST’ and ‘ports’ in the docker-compose.yml-file will map the domain correctly. <p> What is the benefits of using an nginx-proxy.conf in that case ?
And this , follow-up question goes a bit beyond your post, that would be putting an Matomo-ID (wrapped in a javascript) in the nginx-configuration file instead of cluttering up my different services with the Matomo-ID
Best, Inkimar
matomo