Sunday, September 22, 2019

Free Oracle Cloud: 7. Setup a web server on the Virtual Machine

This post is part of a series of blog posts on the Best and Cheapest Oracle APEX hosting: Free Oracle Cloud.

In this blog post we will configure a web server on our Compute VM Instance. This allows us to host some websites and have a custom URL for our Oracle APEX instance and applications.

Lets start with connecting to our VM:

From a Terminal connect to your Oracle Cloud VM:

ssh -i ssh_key opc@public_ip

The first thing we do, is change to the root user, as we want to install a web server it will be easier to do it with the root user. Alternatively in front of every command you can add sudo.

We logged in as the OPC user, to become the ROOT user we do:

sudo su

Although it doesn't really have anything to do with setting up a web server, I do want to share this... The first thing I always like to do on a machine, is get the system updated, so all latest software is being used. To do this, run following command:

yum update

It will take some time the first time, but after a couple of minutes you should see that all packages were updated:


So the purpose of this post was to install a web server so when we type in a certain domain, it will arrive at our machine. As web server, I typically chose between Apache and Nginx. Which one to choose is a hard one... if you search Google for "Apache vs Nginx" you can start reading ;) Since last year I started to use Nginx for all my new systems, before I always used Apache.

Following steps show how you install the Nginx web server and run it:

yum install nginx


Now we need to start the web server:

systemctl start nginx

To see if Nginx is successfully running, do:

systemctl status nginx

You should see something like:


The next thing we have to do is open the firewall on the Linux box, so incoming connections are allowed. The first line will open HTTP, the second HTTPS and then we reload the firewall:

firewall-cmd --permanent --zone=public --add-service=http
firewall-cmd --permanent --zone=public --add-service=https
firewall-cmd --reload

Opening the firewall on the Linux box is not enough. Oracle added some extra security layers around the VM (Compute Instance). We have to allow HTTP and HTTPS access to our machine in the Oracle Firewall too.

Click the Virtual Cloud Network link:


Click the Security Links:


And add two Ingress Rules, one for HTTP and one for HTTPS:


As Source add 0.0.0.0/0 so everything can connect to it and as destination port you specify the first time 80 (for HTTP) and the second time 443 (for HTTPS):


Once both Ingress Rules are added, your list looks like this:


Now you can navigate in a browser to your Public IP and you should see:


Now that we have a web server running and it's accessible through the IP address, we know things are working. Most of the time however you don't want to access your server through an IP address, rather you want people to use a domain name. To access my Free Oracle Cloud server for example I want to use the dgielis.com domain.

The first step to do, is in the domain provider you specify for the A record, the IP address of your Oracle Cloud VM (Compute) Instance.  I typically also setup some CNAME so any sub-domain will work too. For example I could point apex.dgielis.com to Oracle APEX Builder.


Now that the domain points to our VM, we have to make sure our web server listens to this domain and knows what to do. We will need to configure Nginx for this dgielis.com domain.

Here are the steps to do this (do this in your Terminal which is connected to your VM):

vi /etc/nginx/conf.d/dgielis.com.conf

# Add following to the file (change dgielis.com by your domain):
server {
    listen         80;
    listen         [::]:80;
    server_name    dgielis.com www.dgielis.com;
    root           /usr/share/nginx/html/dgielis.com;
    index          index.html;
    try_files $uri /index.html;
}

# Create a directory where your website resides:
mkdir /usr/share/nginx/html/dgielis.com

# Add an index.html file to the directory
# Quickest way is vi or cp an index.html in this folder
# Or develop your site locally first and when ready upload with scp
# scp -i .ssh/oraclecloud /Users/dgielis/site.zip opc@132.145.215.55:/tmp

# to test Nginx configuration
nginx -t 

# to restart Nginx
nginx -s reload

# note: in case nginx doesn't restart, kill the nginx process and try to restart again
ps -ef | grep nginx
kill ~pid~

When you go in your browser to your domain name, it should show your website!

This website runs over HTTP, but these days it's recommended to use HTTPS for your sites. Lets setup HTTPS for our website by using LetsEncrypt, a free service for SSL certificates.

First we have to install some supporting packages:

yum install certbot python2-certbot-nginx  # not necessary
yum install python27-python-pip
scl enable python27 bash
pip install certbot
pip install setuptools --upgrade
pip install certbot-nginx

Once the supporting packages are there, we can run certbot to setup the SSL certificates for our domain:

certbot --nginx

After completion of the wizard, you should see something like below:


During the Certbot wizard which configures LetsEncrypt, it asks if you want to redirect all HTTP access to HTTPS and I would answer Yes here.


Now, regardless if you use HTTP or HTTPS on dgielis.com, you will always end-up with HTTPS.
HTTPS is better for Google, better for security, so no reason not to do it :)



If we want to use our Nginx web server as reverse proxy for our APEX environment we can do that by adapting our /etc/nginx/conf.d/dgielis.com.conf file (see the location sections):

vi /etc/nginx/conf.d/dgielis.com.conf

Add following to the server:

  location /ords/ {
    proxy_pass your_apex_url/ords/;
    proxy_set_header Origin "" ;
    proxy_set_header X-Forwarded-Host $host:$server_port;
    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;
    proxy_connect_timeout       600;
    proxy_send_timeout          600;
    proxy_read_timeout          600;
    send_timeout                600;
  }

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

The final configuration file looks like this:


There's one other configuration change I would suggest you do straightaway; increase the size of the max_body_size in Nginx. Add following line to nginx.conf

vi /etc/nginx/nginx.conf


Test and reload the configuration of Nginx:

nginx -t
nginx -s reload

When going in a browser to https://dgielis.com/ords/ we arrive at Oracle APEX:


There's a lot of optimization we can do on the reverse proxy. To gain performance we can put the images folder of APEX on the Nginx server, as Nginx is super fast in transferring static files. We can add more redirects, for example, that apex.dgielis.com goes to the APEX builder and app.dgielis.com goes to one of our custom APEX apps. As this post is already long, I'm not including that in here.

Once Oracle provides vanity URLs, we don't need to do the above, and the URL will point directly to ATP.

Update 26-SEP-2019 (thanks Kris Rice): Note that setting the Origin would negate any CORS info that ORDS is enforcing. That could be a security issue for some people. Oracle is looking into the ability to have your ORDS running on your own Compute VM (the webserver we just setup), which would solve the issue. The vanity URLs would not have the CORS issue either.

In the next post, we will use this server to add an on-premises version of APEX Office Print (AOP), so we have everything we need to export data from the database in the format we want, for example in Excel and PDF.

Update 23-DEC-2019: If you are looking for other redirects see 17. Configure domain to redirect to APEX app

Update 31-AUG-2020: If you are interested in running ORDS on the same server, read Custom Domain Name (URL) with your own ORDS on the Webserver

63 comments:

Scott said...

Awesome article - found a small typo:

scl enable paython27 bash

Should be:

scl enable python27 bash

Dimitri Gielis said...

Thanks Scott, I corrected it also in the post.

Martin Børge Nielsen said...

Thanks Dimitri ! great post.
I tried to do the same with Apache but could not get the proxy setup working.
Works great with nginx.

Brgds
Martin

Sokos said...

Awesome post Dimitri,
Quick question, where does ORDS/Rest Services reside?
Usually we have to throw the ords.war in the Application server (e.g Tomcat webapps)

Dimitri Gielis said...

ORDS is running in front of ATP and managed by Oracle.
You can't change the configuration of ORDS - you get 20 simultaneous connections (which can serve 1000s of users depending your app).

Flieger said...

Great post, Dimitri. I typically opt for Apache. Any reasons why I should switch to Nginx?

Dimitri Gielis said...

Hi Flieger,

We've both Nginx and Apache in different projects... not really a preference.

I just like to try different things for myself and Nginx became more popular in the larger world, so used that. When you read about the architecture e.g. https://www.hostingadvice.com/how-to/nginx-vs-apache/, Nginx seems better for static sites and it's used a lot as reverse proxy. But in an Oracle APEX context I don't think it makes much of a difference especially not when you use the CDN for static files.

So if Apache works for you and you know that, stick with it :)

Hope that helps,
Dimitri

Flieger said...

Thanks, Dimitri. That helps.

Souleman DEMBELE said...

thanks you Dimitri, this article is useful and very clear. it will also be a good approach to configure a load balancer. may be another point in this article series.

Jeffrey Kemp said...

Brilliant stuff, followed your instructions to the letter and it worked well.

I had one hiccup, my domain was previously pointing to a server which was already serving https; Google Chrome consistently refused to send me to the http version of the new site. I had to test it in Firefox to verify that it was working. Once the letsencrypt cert was installed, it worked fine in Chrome again.

Chimpanzee said...

Thank you so much for this. Your guides are so easy to follow because you never really assume prior knowledge of anything - you just lay it out simply, step-by-step. Really great for someone like me who is comfortable in APEX and with designing databases, but knows next to nothing when it comes to server admin. Following your guides, I've managed to set up Oracle Cloud and APEX running on my own subdomain.

Is it possible to mask the URL even further? eg https://mydomain.com/f?p=4550:1 (without the /ords) or even attaching a specific APEX application to a subdomain so myapp1.domain.com goes to one app and myapp2.domain.com goes to another app (within the same workspace)?

Lucas Souza said...

Hi, thanks for this post, this help me so much to use ATP with APEX.
BUT, now I got other problem using a NGINX with ORACLE ATP and SOCIAL LOGIN (IDCS).
I created a new application on IDCS federation service pointing to my domain configured to NGINX, but when APEX redirect to IDCS authorize page, the APEX send a wrong "redirect_uri" parameter.

The "redirect_url" is the url of APEX ATP.

My doubt is how APEX gets the value to put on redirect_uri? is the HOST HTTP variable? or is a internal parameter? and can I change this value?

thanks

Anonymous said...

Hi,

Thank you so much for your precious series of posts. Even as a noob I managed to get this up and running.

Dimitri Gielis said...

Hi Chimpanzee,

You can give this a try: rewrite ^/$ /ords/f?p=101 permanent;

Hope that helps,
Dimitri

Anonymous said...

Great Post Thanks so much Dimitri.
Can you help how to setup 2 domains for apex apps?

Thanks/

Phanny said...

Great Post Thanks so much Dimitri.
Can you help how to setup 2 domains for apex apps?

Thanks/

Arturo said...
This comment has been removed by the author.
Arturo said...
This comment has been removed by the author.
Tia Barka said...

Thank you for this usefull post.
I Just added this to ninx domain config

location = / {
return 301 /ords/;
}

to redirect non /ords access.
Next step will be copy all /i resources to a local dir and avoid reverse proxy.

Jochen said...

Hi Dimitri
if i navigate to https://my-domain.com/ords/ i get an error message:

There is a problem with your environment because the Application Express files have not been loaded. Please verify that you have copied the images directory to your application server as instructed in the Installation Guide. In addition, please verify that your image prefix path is correct. Your current path is /i/19.1.0.00.15/

Should the images not already be in place by default?

thanks for help

Dimitri Gielis said...

Hi Jochen,

Yes, it should.
Did you configure NGinx to also forward /i/ ?

Dimitri

Jochen said...

Thanks for replying Dimitri.
Yes it actually did:

location /i/ {
proxy_pass https://kjflphbzcwyyi2q-dbjzzh.adb.eu-zurich-1.oraclecloudapps.com/ords/i/;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}

Dimitri Gielis said...

Hi Jochen,

When you go to the direct url of the Oracle Cloud, does it work for you then?
If not, best to contact Oracle.
If it does work, try to empty your cache of your browser for your domain and try again.

Hope that helps,
Dimitri

Yvo Breuer said...

Hi Dimitri,

I want ybis.nl to lead to an APEX application and apex.ybis.nl to lead to the APEX Builder. Like you already said, your post is quite long, which I understand. But could you please show me another blog post for example that provides some simple (like you did in your blog post) set-up to achieve what I want?

Kind regards, Yvo

Anonymous said...

This is truly a unique level of power and functionality for a free tier. Do you have any sense how long Oracle will offer it? Microsoft started a similar level of 'free' usage and then cut back significantly once there was traction.

Bertil Tandayamo said...

Dimitri thanks for your expertise. I'm newbie in apex. To avoid this vanity url from Oracle infrastructure, may I get an VM or a droplet in any cloud service and to install all my apex environment? Am I right?

Dimitri Gielis said...

Absolutely, you can go with a pre-configure VM/Droplet/AMI/... with all software pre-configured or you go with a blank Linux machine for example and install and Oracle DB, APEX and ORDS yourself - this works with any cloud provider.

firnnauriel said...

Can anyone point me to a an article on how to setup my own domain name on a free Compute instance? I'm not that good at these networking task but I was able to access my JET application so far using the public IP I saw in OCI. Another question is, will that public IP changes? If yes, how often?

x said...

why does everybody removes the origin header ? it renders CORS useless and unless your framework has csrf tokens, potentially makes your app vulnerable to CSRF attacks ... it's a rather dirty hack...
if you remove the origin header to your backend, you should at least handle cors in the reverse proxy or make sure csrf tokens are in place

Dimitri Gielis said...

Hi x,

The reason is that ORDS has build-in CORS checks, but as we reverse proxy the domains are different from what it expects.
Until we can run ORDS on the reverse proxy machine or ORDS gives us some more options, I didn't find a way to get it to work with ATP. But, you are absolutely right - it's a hack which has potential risks. This is why I update the post on 26-SEP-2019 (see section at bottom of blog post).

Feel free to share a better reverse proxy configuration that works and is more secure. I'm happy to update the blog post and give you credit for it.

Thanks,
Dimitri

x said...

I did not see the update - which is completely valid.
However, i have been testing cors with ORDS and it is not very well documented, hence you see the workaround of removing the origin header everywhere.
I tested cors yesterday in a test env with ords 18.3.0.r2701456 - I could use any random origin, I always received Access-Control-Allow-Origin allowing the origin, which is also not correct.
Then explicitely whitelisted the origin using ORDS.SET_MODULE_ORIGINS_ALLOWED - i could still send any origin and ords was fine with it - not blocking cross origin requests.
In ords 19.2 on the otherhand, I can't seem to get any request through - whitelisting with ORDS.SET_MODULE_ORIGINS_ALLOWED, tomcat cors filter etc.
The only option I currently have is using a reverse proxy which checks the origin header and sends the cors headers back and then remove the origin header to the backend (so cors is not triggered on ords)
for example - devs run their code on localhost and want to do cross origin requests to ords - the following apache httpd directives set a flag if origin is http(s)://localhost: - if the flag is set, added the cors response headers. Then we remove the origin header.
SetEnvIf Origin "http(s)?://(localhost)(.*)$" AccessControlAllowOrigin=$0
Header always set Access-Control-Allow-Origin %{AccessControlAllowOrigin}e env=AccessControlAllowOrigin
Header always set Access-Control-Allow-Credentials true env=AccessControlAllowOrigin
Header always set Access-Control-Allow-Methods "GET,POST,PUT,GET,DELETE" env=AccessControlAllowOrigin
Header always set Access-Control-Allow-Headers "x-software-key, authorization, content-type, cache-control, if-modified-since, pragma,Accept-Language"
RequestHeader unset origin

i'm trying to get to the bottom of this but it doesn't help that cors is not very well documented in ords and just about every piece of advice on the internet says 'just remove origin' which completely renders cors useless.

Florin Pop said...

Excelent post! Congrats!
I followed the steps and it works great, except one little issue I encounter when I try to integrate the Google Authentication. The redirect URL still contains the DB hostname in the redirect_uri: zfpygvlswt7pyh9-db201909202222.adb.eu-frankfurt-1.oraclecloudapps.com/ords/apex_authentication.callback . Is there a way to tell the APEX engine to use specific value for this? Anyone managed to workaround this?

Pawan Bahuguna said...

This is one of the best articles I found for Oracle cloud machines.

juanjf9 said...

Hi Dimitri thanks a lot for this post!, it worked great for me.

I have a question, can we use the same VM/Domain to point to different databases.

something like:
https://mydomain.com/dev/ords/
https://mydomain.com/qa/ords/
https://mydomain.com/prod/ords/

if so, how do you handle the /i/?

Nelson92 said...

Hi Dimitri, great post !!
Have question for this: "We can add more redirects, for example that apex.dgielis.com goes to the APEX builder and app.dgielis.com goes to one of our custom APEX apps. As this post is already long, I'm not including that in here."

Please make post for this, have question make subdomain for this or NGIX configuration.

Thanks !

Dimitri Gielis said...

see https://dgielis.blogspot.com/2019/12/free-oracle-cloud-17-configure-domain.html

Nelson92 said...

Thank you very much Dimitri! It works perfect !

Ask if you know anything about putting a video in the background on the home page, I have tried with # app_images # or # IMAGE_PREFIX #, but it does not understand the file path in static files, for example live video : https://makebackground.io/bk/under-cloud/orange-fly-under-clouds

Greetings from Costa Rica!

Randell said...

Thanks for sharing. It's helpful for many people. Judging from the comments, many people are very interested. Computers need good software, as well as good hardware and accessories, right?

Unknown said...

Hi Dimitri, great post !

I had to uncomment the root in the server section of the nginx.conf
Otherwise it wouldn't find www.mydomain\index.html

This section did not work :

yum install certbot python2-certbot-nginx # not necessary
yum install python27-python-pip
scl enable python27 bash
pip install certbot
pip install setuptools --upgrade
pip install certbot-nginx

To me it looks like the --upgrade upgraded to a wrong version.

On https://certbot.eff.org/lets-encrypt/pip-nginx I found :

wget https://dl.eff.org/certbot-auto
sudo mv certbot-auto /usr/local/bin/certbot-auto
sudo chown root /usr/local/bin/certbot-auto
sudo chmod 0755 /usr/local/bin/certbot-auto

sudo /usr/local/bin/certbot-auto --nginx

That worked flawless.

I made the certificate and the rewrites and voila there was my site :
www.codatax.com

Thanks !

Robert said...

Great stuff Dmitri.

In the same way as you have done for APEX, is it possible for SQLDeveloper Web?

I set up a /sql/ location, and specified the SQLDeveloper sign-in web address, but I cannot get it to work. I do get 2 boxes for username and password on top left hand side of screen, no labels or headings - the rest of screen blank.

If do I enter my admin/password details into the 2 boxes, my URL changes to have "success" at the end and the tab is renamed to Success.

Any clues appreciated.

Thanks,
Rob

Anonymous said...

Hi Dimitri,

Thanks for you post! This has really helped me run my app using nginx.

I have an issue and perhaps I may be missing something.

Everything works fine but I see one problem. When an app is published then the link also contains the ords e.g. domain.com/ords/f?p=1:1:0

If by mistake the end user simply romes the f?p .... part then it routs to the default Oracle APEX admin page.

How can we avoid it.

Thanks
Syed

Marcus B. said...

This is really helpful but I have run into an issue with certbot. The wizard will not run with an error,
raise ImportError("'pyOpenSSL' module missing required functionality. "
ImportError: 'pyOpenSSL' module missing required functionality. Try upgrading to v0.14 or newer.
I tried installing a newer version but v0.14 is the latest in yum repository. Here is the whole log.

[root@instance-20200612-0859 thebladencompany.com]# certbot --nginx
Traceback (most recent call last):
File "/bin/certbot", line 9, in
load_entry_point('certbot==1.3.0', 'console_scripts', 'certbot')()
File "/usr/lib/python2.7/site-packages/pkg_resources/__init__.py", line 558, in load_entry_point
return get_distribution(dist).load_entry_point(group, name)
File "/usr/lib/python2.7/site-packages/pkg_resources/__init__.py", line 2682, in load_entry_point
return ep.load()
File "/usr/lib/python2.7/site-packages/pkg_resources/__init__.py", line 2355, in load
return self.resolve()
File "/usr/lib/python2.7/site-packages/pkg_resources/__init__.py", line 2361, in resolve
module = __import__(self.module_name, fromlist=['__name__'], level=0)
File "/usr/lib/python2.7/site-packages/certbot/main.py", line 2, in
from certbot._internal import main as internal_main
File "/usr/lib/python2.7/site-packages/certbot/_internal/main.py", line 23, in
from certbot._internal import client
File "/usr/lib/python2.7/site-packages/certbot/_internal/client.py", line 13, in
from acme import client as acme_client
File "/usr/lib/python2.7/site-packages/acme/client.py", line 37, in
requests.packages.urllib3.contrib.pyopenssl.inject_into_urllib3() # type: ignore
File "/usr/lib/python2.7/site-packages/urllib3/contrib/pyopenssl.py", line 112, in inject_into_urllib3
_validate_dependencies_met()
File "/usr/lib/python2.7/site-packages/urllib3/contrib/pyopenssl.py", line 147, in _validate_dependencies_met
raise ImportError("'pyOpenSSL' module missing required functionality. "
ImportError: 'pyOpenSSL' module missing required functionality. Try upgrading to v0.14 or newer.

Abhishek said...

Need help is Google and Facebook Authentication.
I did all steps as above and my domain is pointing to an app id but now google authentication is not working. The authentication callback is of server name instead of domain name.
Please help.

You can check on www.acolytemeetings.com

The contents of conf file is

server {
server_name acolytemeetings.com www.acolytemeetings.com;

listen [::]:443 ssl ipv6only=on; # managed by Certbot
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/acolytemeetings.com/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/acolytemeetings.com/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot

location / {
rewrite ^/$ /acolyte/f?p=1000 permanent;
}

location /acolyte/ {
proxy_pass http://h2891394.stratoserver.net:8080/acolyte/;
proxy_set_header Origin "" ;
proxy_set_header X-Forwarded-Host $host:$server_port;
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;
# proxy_redirect http://h2891394.stratoserver.net:8080/acolyte/ $scheme://$host/acolyte/;
proxy_connect_timeout 600;
proxy_send_timeout 600;
proxy_read_timeout 600;
send_timeout 600;
}

location /i/ {
proxy_pass http://h2891394.stratoserver.net:8080/i/;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}


}
server {
if ($host = www.acolytemeetings.com) {
return 301 https://$host$request_uri;
} # managed by Certbot


if ($host = acolytemeetings.com) {
return 301 https://$host$request_uri;
} # managed by Certbot


listen 80;
listen [::]:80;
server_name acolytemeetings.com www.acolytemeetings.com;
return 404; # managed by Certbot

}

Mausam Gaurav said...

Hi Dimitri,

Have you managed to test this on Ubuntu servers. For some strange reason, the public IP address does not open in the browser in case of Ubuntu. I think there is some persistent firewall which doesn't allow it.
I have tried googling it but found no clues. You are probably my best bet now :)
Cheers

gazza said...

I followed the steps on the post very closely but had one issue with running certbot and setting up the https certificate and .conf file.
I was getting python errors running certbot (one of which is below). The wizard would not run.

I thought I would post how I got it working in case anyone else hits the same issue.

Error: AttributeError: 'module' object has no attribute 'Locale'

After a bit of searching I tried this:
pip install parsedatetime==2.5
then running certbot worked, the wizard ran, and the setup of the certificate worked.

Good or bad I am not sure, a bit of luck involved on my part to be honest, but its set up and works nicely.

thanks for the great post.

Garry Lawton said...

Hi Dimitri,
the section on certbot did not work but the code below did.
This is also in a previous comment.

wget https://dl.eff.org/certbot-auto
sudo mv certbot-auto /usr/local/bin/certbot-auto
sudo chown root /usr/local/bin/certbot-auto
sudo chmod 0755 /usr/local/bin/certbot-auto

sudo /usr/local/bin/certbot-auto --nginx

other than that - works great

Regards, Garry

Mirela said...

Hi Dimitri,
First of all, thank you. The information in these blogs is very useful, easy to follow.
I do have a working APEX environment. I managed to create a VM instance and maybe I could also install a web server.

What I want to achieve is to be able to put my own APEX static files onto the web server, but without changing the url, reverse proxy, certificates and all that. Maybe also creating a FTP/SFTP user to be able to access and modify this files.
Is it possible? And if so, could you point me in the right direction (like refering to steps already explained in you blogs or maybe other sites with good explanations)?

Regards, Mirela

Phil Winfield said...
This comment has been removed by the author.
Francois M said...

Dear Dimitri,
I did the config with Ngnix and it works fine, but my environment runs apache and i cannot have the same result of reverseproxy. When i set ProxyPreserveHost to Off, it works but not for a POST, when i set ProxyPreserveHost to On, ORDS of OCI returns 403 Forbidden and suggests to set ProxyPreserveHost.
I am stuck.
i have also set 'Header set Origin ""' with no better result
do you have a reverseproxy with Apache?
Finally great document and explanation

Antilus Alix Polidor said...

Hi, thank you for the post, help me a lot.
I did the config with nginx, except, for the certbot part but i get the following error "redirected too many times". can you help me, please.

Jimmy said...

Hi Dimitri, great post. However now seems that python 2.7 is no longer supported and this install script for certbot --nginx no longer works (I did upgrade python but that didn't seem to help).

certbot --nginx
/opt/rh/python27/root/usr/lib64/python2.7/site-packages/OpenSSL/crypto.py:12: CryptographyDeprecationWarning: Python 2 is no longer supported by the Python core team. Support for it is now deprecated in cryptography, and will be removed in a future release.
from cryptography import x509

Happy New Year!

burf said...

For anyone who is stuck with public IP being inaccessible, they would want to have a look at the IPTABLES rules (https://stackoverflow.com/a/54810101/9923626).

Hrishi said...

Hi Dimitri,

Excellent post!!!
My OCI is in mumbai region, and "yum install nginx" is giving error:
Loaded plugins: langpacks, ulninfo
No package nginx available.
Error: Nothing to do
vi /etc/yum/vars/ociregion shows -mumbai
echo $ociregion doesnt display anything.
I have done sudo su as well as updated all packages.

Please help.

Thanks,
Hrishi

edgiru said...

Install Ubuntu Nginx
https://medium.com/@saiful103a/create-free-ubuntu-vps-in-oraclecloud-with-nginx-always-free-f07d9d7fad40


sudo iptables -I INPUT -p tcp --dport 80 -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT
sudo iptables -I OUTPUT -p tcp --sport 80 -m conntrack --ctstate ESTABLISHED -j ACCEPT

Kees Vlek said...

Hi Dimitri,

Bedankt voor je uitgebreide uitleg. Het heeft mij erg geholpen om een en ander op te zetten.

Groet,
Kees Vlek

JellIT said...

Change python27 to python 3 for certbot. Should it be run as root?
https://certbot.eff.org/lets-encrypt/otherpip-nginx was helpful
Oracle linux 8 always free has nginx installed but gives a 502 gateway error. Run the fix from ords blog page:
https://dgielis.blogspot.com/2020/08/free-oracle-cloud-custom-domain-name.html
cat /var/log/audit/audit.log | grep nginx | grep denied | audit2allow -M mynginx
semodule -i mynginx.pp
Please feel free to correct but it is what got me going. Tq.

Yvo Breuer said...

In case "yum install nginx" gives you an error, you can resolve this via:
http://johanlouwers.blogspot.com/2016/01/install-nginx-on-oracle-linux.html
Works like a charm!

Yvo Breuer said...

In case you run into trouble when issuing "pip install certbot" have a look at https://certbot.eff.org/lets-encrypt/pip-nginx.html

Joe M said...

I couldn't get certbot added or python packages, good article here worked to first install Snapd on CentOS 8

https://computingforgeeks.com/install-snapd-snap-applications-centos/

Joe M said...

Follow up to last post:

Namely the steps I took to install certbot:

Install Snapd on CentOS 8

Add EPEL repository

sudo dnf -y install https://dl.fedoraproject.org/pub/epel/epel-release-latest-8.noarch.rpm
sudo dnf -y upgrade

Install Snap on CentOS 8

sudo dnf -y install snapd
sudo systemctl enable --now snapd.socket
sudo ln -s /var/lib/snapd/snap /snap


Then

[Certbot Instructions] https://certbot.eff.org/instructions?ws=nginx&os=centosrhel8

FMAN said...

Awesome tutorial, Dimitri, thanks a mil.
One note, I had an issue with the reverse proxy, got 502 bad gateway, the solution was to run this command:
setsebool -P httpd_can_network_connect 1

Satish said...

Thanks for sharing.

Need your support.

Our Current Apex environment in On Premise:
------------------------------------------

2 webservers - nginx
2 app servers - ORDS on tomcat
1 server - Oracle Database

Concurrent users count - 100
Database Size 150GB

We agree above is oversized configuration, but since we have plenty of resources available in our DC, they went with above configuration.


Now, we planned to move to OCI PASS and below is the quantity we got.
Oracle Base Database Service - Enterprise Edition OCPU --> 5 for prod and 2 for UAT
Virtual Machine(VM.Standard3.Flex) - Compute Standard-X9 OCPU--> 2 for PROD and 2 for UAT
We have got 2 load balancers - One for PROD and one for UAT


Unfortunately we cannot increase any of the above configuration.

As you have observed, we have got only 2 OCPU for each compute VM(2 for PROD and 2 for UAT). With this configuration, can you suggest some good setup from your expertise.

Not sure whether webservers are really required and we can we skip them.

Thanks,
SG

satish said...

Hi Dimitri,

We need your help.

With below configuration:

Oracle Base Database Service – Enterprise Edition OCPU

Virtual Machine(VM.Standard3.Flex) – Compute Standard-X9 OCPU


I think the compute has given by oracle to install ORDS. Please correct me if wrong

and Who is going to perform database activities? Is it customer or oracle.

Database Activities like Installing/Upgrading the Oracle Database


Thanks,
Satish