I want to create a simple Progressive Web Application (PWA) user registration dialog, which runs on mobile devices, accepts user data and saves them to some backend.
I chose Ionic 2 (ignoring its capabilities to create native apps), because it’s based on Angular 2. It’s like sliced bread. And it uses TypeScript as its (preferred) language. If you’re new to Angular (as I am), head over to Code School’s Accellerating through Angular 2.
Before installing Ionic 2, you’ll need Node.js because it’s required by Ionic 2.
Refusing to infect my MacBook with all sorts of beginner’s (and beta) garbage, I chose to confine my developer environment within a Docker container, avoiding both homebrew and the irreversible native installer as well.
This will give you a virtual environment to take with you, hand over to colleagues, or even publish for anyone to start using within a couple of minutes.
This is not a tutorial. You’ll have to visit the links on your own in order to grasp, what and why you’re doing. I loosely followed Heitor’s recipe at Getting Started with Docker for the Node.js Developer, skipping Express in favor of Ionic 2 and ignoring any deprecated (e.g. Boot2Docker) stuff, instead immediately heading over to …
▶︎ Install Docker for Mac, outlined at Getting started: It’s just dragging the Docker app to your applications folder. Windows users should instead head over to Docker for Windows, Linux users to Install Docker Engine on Linux.
Then open Terminal and enter
docker run hello-world
in order to verify your installation and you’ve both, downloaded a public Docker image to your computer, instantiated a container and run a Hello World app.
Sit back for a moment and start figuring out: Docker is like introducing dependency injection into lightweight virtual machines, creating snapshots (i.e. containers) and exporting them as new VMs (i.e. Docker images). And it has an infrastructure to share complete solutions.
▶︎ Consider installing Kitematic, an optional GUI for managing your Docker containers. It’s neither required nor terribly useful, but handy for a Docker novice to visually explore what Docker is all about:
▶︎ Install Ubuntu and Node.js. There are a one-stop Debian based Docker images for Node.js, but I followed Heitor’s path, that more closely mimics a real Linux installation and manually installs any required stuff step-by-step.
I’ll later present an automated way to configure your environment. Skip to Introducing Dockerfiles and mounted volumes.
docker pull ubuntu docker run ubuntu /bin/echo 'Hello World' docker run -i -t ubuntu
You’ll now be sitting in front of an Ubuntu shell. Try
ls -la and install Node.js and npm:
ls -la apt-get update # As of 03-jul-16: Ionic is not yet ready for Node.js 6 # see https://github.com/driftyco/ionic-cli/issues/960 apt-get install curl curl -sL https://deb.nodesource.com/setup_5.x | bash - apt-get install nodejs node -v
npm install -g ionic@beta exit
Now save the container as a new image:
# Get your CONTAINER_ID docker ps -a # Save your container as a new image docker commit -a 'YOUR_NAME <YOUR@EMAIL>' -m 'ionic2 devjump' \ CONTAINER_ID my-ionic2:0.1 docker tag my-ionic2:0.1 my-ionic2:latest
And immediately shell a new container running your Ionic 2 installation:
docker run -i -t -p 8100:8100 -p 35729:35729 my-ionic2
Create and start your first Ionic 2 app:
ionic start cutePuppyPics sidemenu --v2 --ts ### --ts = TypeScript cd cutePuppyPics ionic serve --all ### without the --all Safari wouldn't connect to Ionic
Now head over to Safari or Chrome and open http://localhost:8100:
And on the iPad (serving as a personal LTE hotspot):
There’s some confusion about whether Docker for Mac is able to publish container ports to networks other than localhost. Using Docker for Mac 1.12.0-rc2-beta17 (build: 9779) and after having added a permissive rule to my Little Snitch in order to account for com.docker.slirp, everything appeared to be fine.
Introducing Dockerfiles and mounted volumes
Full stop! You might be tempted to start designing your app right now – but you shouldn’t! The source for your app is still within a Docker container. Once a container is gone, your sources will be gone as well.
If anything were missing or had to be changed within your Docker image, most probably you would have to start all over, tediously copy-pasting and running all statements again and and again.
We’ll use a Dockerfile to build a new Docker image:
▶︎ Create a new Dockerfile, i.e. from my Gisthub. NB: In favor of the automated build at Docker Hub, this example Dockerfile will not receive any further commits.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
|# No thrills Ionic 2 developer environment|
|# See https://blog.saddey.net/2016/07/03/jump-start-into-angular-2-and-ionic-2|
|MAINTAINER Reiner Saddey <email@example.com>|
|LABEL Description="Interactive Ionic 2 Framework example using volume /projects as the root for your app directories"|
|RUN apt-get update|
|RUN apt-get install -y -q \|
|# As of 03-jul-16: Ionic is not yet ready for Node.js 6, see https://github.com/driftyco/ionic-cli/issues/960|
|# RUN curl -sL https://deb.nodesource.com/setup_6.x | bash –|
|RUN curl -sL https://deb.nodesource.com/setup_5.x | bash –|
|# nodejs includes matching npm as well|
|RUN apt-get install -y -q \|
|&& apt-get -y autoclean \|
|&& rm -rf /var/lib/apt/lists/*|
|# As of 03-jul-16: You have been warned, DO NOT push this button: RUN npm update -g npm|
|# https://github.com/npm/npm/issues/9863 Reinstalling npm v3 fails on Docker|
|RUN npm install -g -y ionic@beta|
|RUN echo '1. Run ineractively and map the /projects volume to your host, e.g. docker run -it -v /Users/<host_path>:/projects <image>' > /readme.txt|
|RUN echo '2. ionic start myFirstIonic2App sidemenu –v2 –ts ### –ts selects TypeScript' >> /readme.txt|
|RUN echo '3. cd myFirstIonic2App' >> /readme.txt|
|RUN echo '4. ionic serve –all' >> /readme.txt|
|RUN echo 'cd /projects' > /start.sh|
|RUN echo 'cat /readme.txt' >> /start.sh|
|CMD bash -C '/start.sh';'bash'|
|EXPOSE 8100 35729|
|# 20-aug-16: Do NOT use VOLUME statement as it may result in numerous|
|# orphaned volumes when innocent users or apps just run|
|# docker run –rm … bash|
|# VOLUME /projects|
Next here is another shortcut: Instead of having to build the image yourself, skip to Let Docker Hub create your Docker image.
▶︎ Create a new Docker image
NB: We’ll pipe the bare Dockerfile into the build in order to prevent any context, i.e. stray files to be included as well.
docker build -t my-ionic2:0.2 -t my-ionic2:latest - > Dockerfile
If you’re too lazy to create the Dockerfile yourself, you can use mine (the one shown above) as-is instead:
docker build -t my-ionic2:0.2 \ -t my-ionic2:latest https://git.io/vKf3j
▶︎ Now run this image in new container, mounting /projects from your hosts file system and opening standard ports for Ionic development. NB: Always use absolute host paths as shown in this example. Otherwise Docker might misinterpret them as volume names. See Manage data in containers. With Docker for Mac, you may not be able to share arbitrary host paths: “You can share files in /Users, /Volumes, /private, and /tmp directly.”.
docker run --name my-ionic2 -it -p 8100:8100 -p 35729:35729 \ -v /Users/rsaddey/Documents/Dockers/projects/:/projects \ my-ionic2
In order to avoid containers piling up or having to remove them manually, you may pass
--rm to remove the container once its shell has exited. I prefer to re-use the same container instead, as long as it’s not kaputt:
▶︎ Re-use container, preserving ports, mounted /projects and your shell history
docker start -ai my-ionic2
Let Docker Hub create your Docker image
Once you’ve prepared a Dockerfile, you may chose to host it at Github (or Bitbucket) and have Docker Hub run the build, e.g. on every push. See Automated Builds on Docker Hub.
- Create a Github repo for the Dockerfile, e.g. https://github.com/rsaddey/jump-ionic2
- Create an automated build on Docker Hub, e.g. https://hub.docker.com/r/rsaddey/jump-ionic2/
Then use the image(s) to create your Docker containers:
docker run --name jump-ionic2 -it -p 8100:8100 -p 35729:35729 \ -v /Users/rsaddey/Documents/Dockers/projects/:/projects \ rsaddey/jump-ionic2
Again, once the container has stopped, you may continue where you left off:
docker start -ai jump-ionic2
and resume using it …
ionic start myFirstIonic2App sidemenu --v2 --ts cd myFirstIonic2App ionic serve --all
… by navigating to http://localhost:8100/ on your host:
Need a second shell to the same container?
docker exec -it jump-ionic2 bash
The VOLUME statement turned out to cause much more harm than good, as an innocent user might expect docker run –rm without explicitly mapping /projects to remove the volume after the container has been removed.
Docker however will NOT remove the volume, causing orphaned volumes to pile up, in turn causing disk space problems, especially for docker VMs with limited disk space, i.e. Windows and macOS using Virtualbox.
Orphaned volumes have to manually removed. See http://stackoverflow.com/questions/27812807/orphaned-docker-mounted-host-volumes
Hi,I have a question, If edit project files. How to let your project auto to rebuild? Thanks !
Is it possible to use this setup and run the container without -it? I have tried many different combos… I can only launch & run the ng2/ionic application with interactive shell running… I’d like to have it up and running and tucked away (-d) ….
LikeLiked by 1 person
I am facing the same issue. Does anybody have a solution to this?
Thanks for the information about dockerfiles,love seeing people encourage use of Docker for node apps.
I think you have forgotten to indicate in your Dockerfile to install cordova. When I execute ‘ionic start myFirstIonicApp sidemenu –v2 –ts’ it forces me to install cordova
Nice Article. In short description good explanation about the DevOps. Thanks For sharing the informative news.
Pingback: 使用Docker创建Ionic2 PWA开发环境 1 _ 脚本宝典