start tensorflow docker container with jupyter and tensorboard together.

Well, today we’re gonna to have new journey on AWS.

I’d like to have some practices of tensorflow on AWS EC2, to make it simple, I decided to use the tensorflow docker image. (You can install tensorflow on EC2 directly, or just use the AWS deep learning AMI, or build the source code of tensorflow if you like)

This is quite simple actually, just pull the docker image and run it, more detail can be found in tensorflow installation page.

Run below command on EC2 instance:

docker run -d -p 8888:8888 gcr.io/tensorflow/tensorflow

then visit http://<EC2 IP>:8888, you can found jupyter is there waiting for you 🙂

NB: Like usually, please make sure you have port 8888 of EC2 instance is reachable from public internet. (add inbound rule of your EC2 security group).

When I played a little with tensorflow, I found that there is no tensorboard I can use, but if I hack into the running docker container, and start tensorboard from command line, it’s there !

So, tensorboard is already in the docker image, but not able to use outside. The point is, according to the design of docker, one container should only have one working process to run (we already have jupyter, so…), but we still can make it possible.

No more bothering, It’s also quite simple, just use ‘docker exec’ command to run tensorboard after jupyter is running.

Here is the scirpt

#!/bin/bash
docker run --name tensorflow \
 -d \
 -v /root/tensorflow/notebooks:/notebooks \
 -v /root/tensorflow/tflogs:/tflogs \
 -e "PASSWORD=tensorflow" \
 -p 8888:8888 \
 -p 6006:6006 \
 gcr.io/tensorflow/tensorflow \


sleep 3

docker exec tensorflow nohup tensorboard --logdir /tflogs &

That’s it ! Now you have your tensorboard at http://<EC2 IP>:6066 waiting for you.

NB: Like usually, please make sure you have port 6006 of EC2 instance is reachable from public internet. (add inbound rule of your EC2 security group).

Let’s have fun with tensorflow on EC2.

Error code=8096 reported when working with RTC Eclipse client

Today, I installed IBM rational software architect and RTC plugin for it.

But when I trying to load workspace from  Jazz source control via RTC client, I always got this error:

Java was started but returned exit code=8096

After some google, I found this solution from IBM official website.

Resolving the problem

To resolve the issue perform one of the following:

  • Comment out the -Xshareclasses:name=IBMSDP_%u value in the eclipe.ini file.
    This file will be found in the same directory as the eclipse.exe executable.

Set up nginx+multiple wordpress+RDS on EC2 with Docker

This is the version 2 of previous post “Set up nginx+wordpress+RDS on EC2 instance with Docker

In this journey, with some tricky, I make the ‘official’ wordpress docker images can support multiple website.
Important: This is definitely NOT the same as wordpress multisite (which is a build-in function of wordpress, but with terrible configuration work. )

My idea just as following:
1.  Nginx (1 instance), this is one docker container.
2. php-fpm (1 instance) + multiple wordpress (m independent instances) , this is another docker container.
3. Mysql (can be local mysql or docker container or AWS RDS or any connectable Mysql), I will chose ASW RDS (as it’s free 🙂

See below picture for a better view.

Ok, let’s start. I will only record the differences from the previous post “Set up nginx+wordpress+RDS on EC2 instance with Docker“, for more detail, just refer to that post.

1.  Prerequisites

  • You should have EC2 with public or elastic IP assigned, or make it accessible from public internet.
  • You should have your EC2 Security Group enabled 80 (http), 443(https) inbound connection.
  • You should have docker, docker-compose installed on EC2 instance.
  • You should have a connectable Mysql, for my case, I set up a RDS Mysql instance on AWS

2. Configure nginx.

Just like the previous post, you may need to use your own nginx.conf and server.conf files. I won’t paste the full configuration files here, will only list the key differences here.

A: nginx.conf, there is no difference of this file.

B: serverX.conf, the only difference is the php-fpm configuration.

server_name         serverX.com www.serverX.com;
listen              80;
root                /apps/websites/serverX/pages;

location ~ \.php$ {
    root /apps/websites/serverX/pages;
    fastcgi_pass wp:9000;
 
    # other configuration for php-fpm
}
  • NB1: Since will we support multiple servers (or domains/websites), you should have multiple configuration file for each server, like server1.conf, server2.conf, … serverN.conf
  • NB2: /apps/websites/serverX/pages will be the website root path used by wordpress container, Also this path (same path) is used by nginx container.
    So you must mount exactly the same path as /apps/websites/ for both wordpress and nginx containers. You will see the configuration later.
  • NB3: wp is the container name of wordpress (we will go for later)
  • NB4: make sure each serverX.conf has it’s owned servername and root, and all the server will listen on 80 port

C: nginx.yaml

version: '3'
services:
  nginx:
    image: nginx:latest
    volumes:
      #mount the nginx.conf and serverX.conf and the websites root
      - /apps/nginx/nginx.conf:/etc/nginx/nginx.conf:ro
      - /apps/nginx/conf:/etc/nginx/conf.d:ro
      - /apps/nginx/logs:/var/log/nginx:rw
      - /apps/websites:/apps/websites:ro
    restart: always
    ports:
      - "80:80"
      - "443:443"
    networks:
      - websites
networks:
  websites:
    external:
      name: websites

3. Configure wordpress

Since the official wordpress docker image only support one website, and with fixed default site root at /var/www/html/, so we have to do something to make it more flexible to support ONE php-fpm + Multiple WordPress

3.1 The AS-IS official wordpress docker image behavior

The default ‘entrypoint‘ of official wordpress docker image is: docker-entrypoint.sh, In container it’s under: /usr/local/bin/docker-entrypoint.sh. You can use ‘docker inspect <wordpress image>’ to check (just make sure you already pulled the image from docker hub).

The default docker-entrypoint.sh actually done 3 things:

  • A: Copy wordpress files to ‘/var/www/html’, and update the ‘wp-config.php’ file according to the ‘environment variables’ setting. (like DB_HOST, DB_NAME, DB_ROOT_PASSWORD etc)
  • B: Remove the ‘environment variables’ to make the container more security. Refer to the github doc as following:
    #now that we’re definitely done writing configuration, let’s clear out the relevant envrionment variables (so that stray “phpinfo()” calls don’t leak secrets from our code)
  • C: Start up php-fpm

3.2 Our requirements are:

  • Multiple wordpress installation,
  • single php-fpm running,
  • can be easily add new website (update wordpress) if necessary

3.3 Things to do to meet our requirements

  • build up our own ‘entrypoint’ script, to install multiple wordpress, and start single php-fpm (will not remove the ‘environment variables’ , to enable add new website), let’s call it ‘startup.sh‘Here is the startup.sh, it’s quite simple
    #!/bin/bash
    set -euo pipefail
    
    # install/update all the websites under $WEBSITES_ROOT
    installWebsites.sh
    
    # start up php-fpm
    exec php-fpm
  • build up 2 scripts, one will install multiple wordpress (used for all websites full installation or update), let’s call it ‘installWebsites.sh‘, and another will install single wordpress (used by single website install or update), let’s call it ‘installWebsite.sh‘, it will be invoked by ‘InstallWebsites.sh’ normally. Here is the installWebsites.sh

    #!/bin/bash
    set -euo pipefail
    
    # $WEBSITES_ROOT is the root path where all the websites exists in wordpress container
    # in my case, it's /apps/websites, it's an env variable can be set in docker-compose
    cd $WEBSITES_ROOT
    
    # Iterate all the folder (each folder means a separate website root path)
    for d in *
    do
     if [[ -d $d ]]; then
     cd ${d}/pages
     #WORDPRESS_TABLE_PREFIX=${d}_
     # In each folder install wordpress
     # the second argument '${d}_' is used as wordpress table_prefix.
     # normally the the folder name (${d}) is the server's domain name like (google, example, server1 etc)
     installWebsite.sh php-fpm ${d}_
     cd $WEBSITES_ROOT
     fi
    done

    And here is the key part of installWebsite.sh, actually it’s almost same as the default ‘entrypoint’ script docker-entrypoint.sh, copy it, and just comment out the unset ‘env variables’ and start php-fpm parts, and add a little tricky for the table_prefix of each website in wordpress DB.

    #comment out the unset environment variable part
    # now that we're definitely done writing configuration, let's clear out the relevant envrionment variables (so that stray "phpinfo()" calls don't leak secrets from our code)
    #for e in "${envs[@]}"; do
    # unset "$e"
    #done
    
    #comment out the 'starting php-fpm' part
    #exec "$@"
    
    #add table_prefix tricky after the default process
    # this is the original process, find it, and add the tricky part below.
    if [ "$WORDPRESS_TABLE_PREFIX" ]; then
     set_config '$table_prefix' "$WORDPRESS_TABLE_PREFIX"
    fi
    # this is the tricky part, '$2' is the second argument, passed by installWebsites.sh.
    if [ "$2" ]; then
     set_config '$table_prefix' "$2"
    fi
  • change the default  ‘entrypoint’ of wordpress container, this is can be done by docker-compose files (or you can use docker run if you like), and mount the scripts we have created to wordpress container.
    Here is the wordpress docker-compose file: servers.yaml
version: '3'

services:
  #the name will be used in nginx serverX.conf
  wp:
    image: wordpress:4.8.2-fpm
    volumes:
       #mount the scripts we build up, also the websites root
       - /apps/websites/startup.sh:/usr/local/bin/startup.sh
       - /apps/websites/installWebsites.sh:/usr/local/bin/installWebsites.sh
       - /apps/websites/installWebsite.sh:/usr/local/bin/installWebsite.sh
       - /apps/websites:/apps/websites
    restart: always
    environment:
       WORDPRESS_DB_HOST: aws-rds-mysql-url-with-port-3306
       WORDPRESS_DB_USER: wordpressuser
       WORDPRESS_DB_PASSWORD: wordpresspass
       #the multiple wordpress websites root, each website with it's own domain name as sub-folder in it.
       WEBSITES_ROOT: /apps/websites
    networks:
      - websites
    #override the default entrypoint of wordpress images
    entrypoint:
      - startup.sh
networks:
  websites:
    external:
      name: websites

4. Prepare websites information.

Let’s start from 2 websites.

Suppose we will setup 2 sites: server1.com and server2.com. Then we need to prepare:

Nginx conf files: server1.conf, server2.conf, refer to the Nginx configure step. Assume you already have the example.conf (the default one we created in previous post), then you can do it as following:

For server1.com

# copy the default one as template
cp example.conf server1.conf

# replace all the domain name from 'example' to 'server1'
sed -i 's/example.com/server1.com/g' server1.conf 
sed -i 's/example/server1/g' server1.conf 


# manually change the other key part mentioned above, e.g root, port, php-fpm config

For server2.com, it’s much easier

# copy the server1.conf as template
cp server1.conf server2.conf

# replace all the domain name from 'server1' to 'server2'
sed -i 's/server1.com/server2.com/g' server2.conf 
sed -i 's/server1/server2/g' server2.conf

Empty website folder for server1.com and sever2.com

mkdir -p /apps/websites/server1/pages
mkdir -p /apps/websites/server2/pages

Ok, now we almost have all set, just a few steps to prepare the nginx serverX.conf for each website, and  start the docker containers, then all will be set.

5. Startup wordpress. (php-fpm + multiple wordpress)

At the same path of servers.yaml (for me, it’s /apps/websites/servers.yaml), run:

docker-compose -f servers.yaml up -d

6. Startup nginx

At the same path of nginx.yaml (for me, it’s /apps/nginx/nginx.yaml), run:

docker-compose -f nginx.yaml up -d

7. Update your website domain DNS setting

Refer to previous post.

8. Add/remove a website.

Let’s say we want add a new website, server3.com. How could I do to achieve this ?

A: Prepare website info
Follow step 4  to make server4.conf (put it under nginx conf folder: /apps/nginx/conf)  and website folder /app/websites/server4/pages.
mkdir -p /app/websites/

B: Install new wordpress.
At the same path of servers.yaml (for me, it’s /apps/websites/servers.yaml), run:

docker-compose -f servers.yaml exec wp installWebsites.sh

C: Reload nginx configuration
At the same path of nginx.yaml (for me, it’s /apps/nginx/nginx.yaml), run:

docker-compose -f nginx.yaml exec nginx service nginx reload

Similar approach when you want to remove website, just remove the nginx serverX.conf, and corresponding website folder (rm -rf /apps/websites/serverX). then run the 2 docker-compose commands (same as add website).

That’s it, we all set.

Hope you can have a good journey with me on AWS.

 

Set up nginx+wordpress+RDS on EC2 instance with Docker

This is my second journey on AWS, at previous post, I practiced to setup LNMP on EC2 with RDS. This time I do it with Docker, which make the journey much easier.

Although EC2  is not the best choice for docker (ECS might be according to AWS) , but at least this is an optional.

Ok, let’s start.

1.  Install docker on EC2。

Quite simple if you have to version preference of docker.

sudo yum install docker

2. Download the related docker images.

You will need nginx, wordpress (fpm version), that’s all. (If you want to use mysql locally, you also need mysql docker image)

docker pull nginx #use the latest version is ok

docker pull wordpress:4.8.2-fpm #use the latest fpm version

docker pull mysql #if you want local mysql

3.  Install docker-compose

Docker-compose is optional, but I’d like to use it to run/maintain my container, you can just use ‘docker run’ to do the same work.

Follow the official  document to install docker-compose.

sudo curl -L https://github.com/docker/compose/releases/download/1.16.1/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose

sudo chmod +x /usr/local/bin/docker-compose

4. Configure nginx.

Just like the previous post, you may need to use your own nginx.conf and server.conf files. I won’t paste the full configuration files here (you can refer to the previous post,  I will only list the key differences here.

A: nginx.conf, there is no difference of this file.

B: server.conf, the only difference is the php-fpm configuration.

root /var/www/html;  #was /apps/websites/example/pages;
#NB:/var/www/html is the default root path used by wordpress container

fastcgi_pass example_wp:9000; #was unix:/var/run/php-fpm/php-fpm.sock
#NB:example_wp is the container name of wordpress (we will go for later)

5. Setup docker network

This step is crucial, we will create a local  bridge docker network (named “websites”) to connect all the containers (nginx + wordpress).

docker network create -d bridge websites

NB: you can create the network in docker-compose configuration file, but I don’t like that style, that makes the dependency between different containers.

6. Create AWS RDS for Mysql.

I just copy it from the previous post, maybe I should create a separated post for this part 🙂

NB: We will not install Mysql on EC2 instance, since it will consume lot of resource which the free tier EC2 instance may not able to afford. Fortunately, AWS is so generous, it provides a separate RDS instance which can be used for Mysql in our case.

This is quite simple too, just follow the document will do the job. Just record following information when you’re done:

Endpoint: The public url which you can access remotely.

DB instance name: like wordpress

DB master username (not root): like wordpress_user

DB master user password:

Another thing need your attention is:

Make sure the ‘Security Group’  you used with following inbound rule:

MYSQL/Aurora
TCP
3306
<the subnet where your want to access the DB>
or 0.0.0.0/0 for public access.

7. Startup wordpress.

Create a example.yaml docker-compose file like following:

version: '3'

services:
   example_wp:
     image: wordpress:4.8.2-fpm
     volumes:
       - /apps/websites/example/pages:/var/www/html
     restart: always
     environment:
       WORDPRESS_DB_HOST: aws-rds-mysql-url-with-port-3306
       WORDPRESS_DB_USER: wordpressuser
       WORDPRESS_DB_PASSWORD: wordpresspass
     networks:
      - websites

networks:
  websites:
    external:
      name: websites

Some remarks:
A:  The bind volume “/apps/websites/example/pages” is the place where you want to install the ‘wordpress’ (will done by the wordpress container), if you don’t want to modify the ‘wordpress’ installation/configuration, you do not need the ‘volume’ setting here.

B: The environment variables, just put your AWS RDS information which you created in step 6  here is ok.

C: The network, make sure you use the same network name which created in step 5.

Then you can startup the workpress container as following:

docker-compose -f example.yaml up -d

8. Startup nginx

Create nginx.yaml file like following:

version: '3'
services:
  nginx:
    image: nginx:latest
    volumes:
      - /apps/nginx/nginx.conf:/etc/nginx/nginx.conf:ro
      - /apps/nginx/conf:/etc/nginx/conf.d:ro
      - /apps/nginx/logs:/var/log/nginx:rw
      - /apps/websites:/apps/websites:ro
    restart: always
    ports:
      - "80:80"
      - "443:443"
    networks:
      - websites
networks:
  websites:
    external:
      name: websites

Also some remarks:
A: The bind volumes, export the nginx configuration files (nginx.conf + server.conf), just in case we can simple update them, export nginx log for easy problem analyzing, export the website root path, so we can make sure ‘nginx’ and ‘wordpress’ use the same website files.

Another thing need your attention is: only log file was bond as ‘rw’ (read-write) mode, other files are ‘ro’ (read-only) mode, that prevents the container change the file by accident (you will never know what have done in the container if you’re not the owner of it 🙂

B: The port, this is the ports nginx listening for http/https request, you have to make sure you setup corresponding ‘in bound’ rules(open 80/443 port http/https connection request for any IP [0.0.0.0/0]) in your EC2 Security Group. (something like below)

HTTP
TCP
80
0.0.0.0/0
HTTPS
TCP
443
0.0.0.0/0

C: The network, make sure you use the same network name which created in step 5.

Then you can startup the nginx container as following:

docker-compose -f nginx.yaml up -d

9. Finally and optionally, update your website domain DNS setting。

If you just want a test/develop environment, this step could be skip, update your domain DNS setting in you domain host (like godaddy), point your domain name to the public or Elastic IP of your EC2 instance.

I think that’s all. You should be able to visit your website via:

http://www.example.com (just in case you did the last step)

http://<public or elastic IP of EC2 instance>

Hope you can have a good journey with me on AWS.

Set up LNMP on AWS EC2 instance with RDS

Lately I’m playing with AWS free tier to start my way of AWS.

A good start for me is to set up LNMP (Linux, Nginx, Mysql, Php) on AWS EC2 instance.

Here are the steps:  (Below all actions are taken under the AWS free tier limitation)

1.  Create EC2 instances.

It’s quite easy, I won’t write down the steps here, just follow the AWS document is good enough.

I used t2.micro, Aamzon AMI x86_64 image, with 3 EBS attached, one for boot 8GB by default, another 2 disks, each 11GB (free tier can allocate up to 30GB GP2 EBS, so I used them up).

NB: To run EC2 instance as a simple website server, you need make sure following things:

A: put your EC2 in a public subnet

B: It should have a public/Elastic IP associated, 

C: make sure you enable 80 (and 443 if you're using SSL) port to accept inbound HTTP connection in 'Security Group'

 

2.  Get the EC2 instance ssh key and login to EC2 instance.

This is not difficult too, just download the <ssh-key>.pem file from AWS console, and follow the instruction of AWS document to login it.

3. Install nginx on EC2 instance.

sudo yum install nginx

4. Install php-fpm on EC2 instance.

sudo yum install php php-mysql php-fpm

5. Config nginx

You can use the default nginx.conf file (normally it’s at /etc/nginx/nginx.conf), or specify your typical configuration. Refer to nginx ‘configuration structure‘ details.

Here’re mine, nothing special, I like to configure each server (or domain) separately.

nginx.config

user  nginx;
worker_processes  1;

error_log  /var/log/nginx/error.log info;
pid        /var/run/nginx.pid;


events {
    worker_connections  1024;
}


http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    keepalive_timeout  65;

    #gzip  on;

    client_max_body_size    64m;
    include /etc/nginx/conf.d/*.conf;
}

One of the simple server.conf

server {
        server_name         example.com www.example.com;

        listen 80;
        listen 443 ssl;
        # force https-redirects
        if ($scheme = http) {
           return 301 https://$server_name$request_uri;
        }

        ssl_certificate /apps/websites/example/ca/bundle.crt;
        ssl_certificate_key /apps/websites/example/ca/key.key;
        ssl_session_timeout 5m;
        ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
        ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;
        ssl_prefer_server_ciphers on;

        root                /apps/websites/example/pages;
        index               index.php index.html index.htm;
        charset             UTF-8;

        access_log          /var/log/nginx/example_access.log;
        error_log           /var/log/nginx/example_error.log;

        error_page          404                     /404.html;
        error_page          500 502 503 504         /500.html;

        if ($http_host !~ '^www.example.com$') {
            rewrite ^/(.*)$                 https://www.example.com/$1 permanent;
        }

        location ~ .*\.(js|css|gif|jpg|jpeg|png|ico|eot|svg|ttf|woff|woff2)?$ {
            root        /apps/websites/example/pages;
            expires     30d;
        }

        location ~ .*\.(txt|xml)?$ {
            root        /apps/websites/example/pages;
            expires     30d;
        }

        location ~* /(404.html|500.html) {
            root   /apps/websites/example/pages;
        }


        location = /favicon.ico {
            log_not_found off;
            access_log off;
        }

        location = /robots.txt {
            allow all;
            log_not_found off;
            access_log off;
        }

        location / {
            # This is cool because no php is touched for static content.
            # include the "?$args" part so non-default permalinks doesn't break when using query string
            try_files $uri $uri/ /index.php?$args;
        }

        location ~ \.php$ {
            #NOTE: You should have "cgi.fix_pathinfo = 0;" in php.ini
            #include fastcgi.conf;
            root /apps/websites/example/pages;
            fastcgi_pass unix:/var/run/php-fpm/php-fpm.sock;

            include fastcgi_params;
            fastcgi_split_path_info ^(.+\.php)(/.+)$;
            fastcgi_index index.php;
            fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
            fastcgi_param PATH_INFO $fastcgi_path_info;

            fastcgi_intercept_errors on;
            fastcgi_buffers 16 16k;
            fastcgi_buffer_size 32k;
            fastcgi_param PHP_VALUE "upload_max_filesize=64M \n post_max_size=64M";
        }
}

Note 2 things:

A: The php-fpm server configuration

To forward your request to php-fpm

fastcgi_pass unix:/var/run/php-fpm/php-fpm.sock;

To set/override the parameter of php-fpm

fastcgi_param PHP_VALUE "upload_max_filesize=64M \n post_max_size=64M";

B: If you don’t have SSL CA certification, remove the ssl part.

6. start nginx and set it as service

service nginx start

chkconfig nginx on

7. Config php-fpm

A: Update /etc/php.ini (use your favorite editor, like vi or nano)

Uncomment the line and setting it to “0” like this:

cgi.fix_pathinfo=0

B: Update /etc/php-fpm.d/www.conf, make sure you  have following configuration updated.

# listen = 127.0.0.1:9000, this should be original value
listen = /var/run/php-fpm/php-fpm.sock

# could be www-data
listen.owner = <the user who will start php-fpm>
listen.group = <the group of user who will start php-fpm>

user = <the user who owned the website path> #was apache
group = <the group of user who owned the website path> #was apache

8. Start up php-fpm and set it as service

service php-fpm start

chkconfig php-fpm on

9. Upload/Install your php website.

I installed a wordpress for a test, just download wordpress.zip and unzip it to your website root path (should be configured in nginx server.conf), e.g

root /apps/websites/example/pages;

10. Create AWS RDS for Mysql.

NB: We will not install Mysql on EC2 instance, since it will consume lot of resource which the free tier EC2 instance may not able to afford. Fortunately, AWS is so generous, it provides a separate RDS instance which can be used for Mysql in our case.

This is quite simple too, just follow the document will do the job. Just record following information when you’re done:

Endpoint: The public url which you can access remotely.

DB instance name: like wordpress

DB master username (not root): like wordpress_user

DB master user password:

Another thing need your attention is:

Make sure the ‘Security Group’  you used with following inbound rule:

MYSQL/Aurora
TCP
3306
<the subnet where your want to access the DB>
or 0.0.0.0/0 for public access.

11.  Update website DB connection information.

For wordpress, you will have to update <website root>/wp-config.php

Update the DB related information like following.

define('DB_NAME', 'wordpress');

/** MySQL database username */
define('DB_USER', 'wordpressuser');

/** MySQL database password */
define('DB_PASSWORD', 'wordpresspass');

/** MySQL hostname */
define('DB_HOST', '<aws-rds-mysql-url-with-port-3306');

12. Finally and optionally, update your website domain DNS setting。

If you just want a test/develop environment, this step could be skip, update your domain DNS setting in you domain host (like godaddy), point your domain name to the public or Elastic IP of your EC2 instance.

I think that’s all. You should be able to visit your website via:

http://www.example.com (just in case you did the last step)

http://<public or elastic IP of EC2 instance>

Hope you can have a good journey with me on AWS.

The requested address is not valid in its context error

This is another one of trouble shoot record for ‘Set up ssserver (shadowsocks server) on Windows’ , put it there just for quick reference.

 

When start ssserver, got “The requested address is not valid in its context error”

 

The cause could be:

The server IP in your shadowsocks config.json is not correct or valid.

NB: This could be the case if you’re using AWS EC2 or other cloud virtual machine/container, and you set ServerIP = <Cloud> public or elastic IP, will cause this problem.

Solutions could be (any of below is ok):

1.  Set Server IP = “127.0.0.1”

2. Set Server IP = “private IP” of AWS EC2 or other cloud VM / Container.

3. Do not set Server IP

Here is an example of the Shadowsocks config.json

1
2
3
4
5
6
7
8
9
10
{
“server”:“127.0.0.1”, ##ServerIp
“server_port”:8000, ##Proxy Port
“password”:“iampassword”, ##password
“timeout”:300,
“method”:“aes-256-cfb”,
“dast_open”:false
}

Windows libcrypto(OpenSSL) not found

This is one of trouble shoot record for ‘Set up ssserver (shadowsocks server) on Windows’ , put it there just for quick reference.

When start ssserver, got “Windows libcrypto(OpenSSL) not found”.

 

The cause could be:

1.  You don’t install OpenSSL for windows.

Solution: Install it 🙂   OpenSSL for Windows

 

2. You don’t install the correct version of OpenSSL (use Light version may not work), and make sure of your OS Arch is X86 or X64.

Solution: Use Full version and correct OS Arch.

 

3. If you’re using the new version of OpenSSL (v 1.1.x), it may not work for some of old Shadowsocks version.

Solutions would be:

A: Use old OpenSSL (v 1.0.2), this worked for me.

B: Use Both OpenSSL (v 1.1.x & 1.0.2), this was recommended by the Win32 OpenSSL Installation Project 

C: Use latest Shadowsocks version (not tested, maybe not work 🙂

 

Set up ssserver (shadowsocks server) on Windows

Well, we help people, and we need help, that makes life better.

You know that, sometime we need a ladder to clime up the Great Wall  inside China, just to have a look what’s happening on the real world.

Thank God,  Shadowsocks is the helper, and if you have a server outside the Great Wall by accident :), that would be a great journey.

Let’s get rid of the further ado, start it right now.

Environment: A Windows server(Linux Server also will do) has real world wide internet connection.

Software list:

1.  Python 2.7 

2. OpenSSL for windows

OK, now we can go for Installation

1.  Install Python, just as normal software installation, only need to pay attention on:

A: Make sure you have downloaded the right version of Python according to you OS Arch (for me it’s  x86-64 MSI installer in 64bit Windows.)

B: please make sure you have ‘pip’ selected when you’re installing.

Python

2. Install Open SSL

Two things need to  pay attention

A: Download the ‘Full’ version (not light version) of OpenSSL with correct OS Arch (for me it’s: Win64 OpenSSL v1.0.2L)

B: As mentioned in the download page,  OpenSSL 1.1.0 is quite different from previous releases. Users should install BOTH the 1.0.2 series (LTS) and the 1.1.0 series for maximum application compatibility.

For me, I just install the old 1.0.2 version, that works fine.

3. Install Shadowsocks server

Use window CMD, run

pip install shadowsocks

That’s it ! You already done the installation !

Normally we should stop here like the ‘Shadowsocks official document’, but is this good enough ? Of course not ! most documentation just tell you how to install in one article, and you have to find out another article like ‘how to use it’ for hours ! That’s not quite convenient, actually it’s wasting time. (you know, time if life)

So, our journal will go on with : How to use Shadowsocks server on Windows

It’s not too difficult, isn’t it ? It’s very simple, only 2 steps will do.

1.  Set up config.json, copy below content, and save as config.json (you can put it anywhere, for me, it’s C:\apps\ss\config.json

1
2
3
4
5
6
7
8
9
10
{
“server”:“127.0.0.1”, ##ServerIp
“server_port”:8000, ##Proxy Port
“password”:“iampassword”, ##password
“timeout”:300,
“method”:“aes-256-cfb”,
“dast_open”:false
}

2. Start shadowsocks from Command line (CMD)

1
ssserver -c config.json

That’s all, we’re done! The ladder is ready, the world is open to you now 🙂

Trouble shooting (optional)

1.  When start ssserver,  got “Windows libcrypto(OpenSSL) not found”

Well, you may not install the OpenSSL for windows, or not installed correctly (refer to my attention above, use old 1.0.2 full version, and with correct OS Arch)

2.  When start ssserver, got “The requested address is not valid in its context error”

Well, this could caused by: the server IP is not correct, (E.g. If you’re using AWS EC2, and you set ServerIP = AWS public or elastic IP, will cause this problem). Actually you can just set ServerIp = 127.0.0.1, it will work.

3. Windows CMD Can’t find ssserver command ?

You need to add python execution path to your ‘PATH’ Environment Variables.

For me, like this: PATH=”C:\Python27\;C:\Python27\Scripts;……..”

Ok, Finally we’re done, enjoy your life now 🙂

Refer to Shadowsocks github wiki: https://github.com/shadowsocks/shadowsocks/wiki/Install-Shadowsocks-Server-on-Windows